package com.example.cattletends.service.impl;

import com.example.cattletends.dto.CattleDataDTO;
import com.example.cattletends.dto.ImportResult;
import com.example.cattletends.entity.CattleData;
import com.example.cattletends.repository.CattleDataRepository;
import com.example.cattletends.service.CattleDataService;
import com.example.cattletends.service.ProvinceDailyPriceService;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 牛只数据服务实现类
 */
@Service
public class CattleDataServiceImpl implements CattleDataService {

    private final CattleDataRepository cattleDataRepository;
    private final ProvinceDailyPriceService provinceDailyPriceService;
    private final com.example.cattletends.service.CattleProvinceService cattleProvinceService;
    private final com.example.cattletends.repository.CattleProvinceRepository cattleProvinceRepository;

    /**
     * 构造器注入
     */
    public CattleDataServiceImpl(CattleDataRepository cattleDataRepository,
                                 ProvinceDailyPriceService provinceDailyPriceService,
                                 com.example.cattletends.service.CattleProvinceService cattleProvinceService,
                                 com.example.cattletends.repository.CattleProvinceRepository cattleProvinceRepository) {
        this.cattleDataRepository = cattleDataRepository;
        this.provinceDailyPriceService = provinceDailyPriceService;
        this.cattleProvinceService = cattleProvinceService;
        this.cattleProvinceRepository = cattleProvinceRepository;
    }

    @Override
    @Transactional
    public List<CattleData> getAllCattleData(LocalDate date) {
        // 如果date为null，使用今天
        LocalDate queryDate = date != null ? date : LocalDate.now();
        Sort sort = Sort.by(Sort.Direction.ASC, "price");
        
        // 查询指定日期的数据
        List<CattleData> dataList = cattleDataRepository.findByCreateTimeDate(queryDate, sort);
        return dataList;
    }

    @Override
    @Transactional
    public List<CattleData> getCattleDataByProvince(String province, LocalDate date) {
        // 如果date为null，使用今天
        LocalDate queryDate = date != null ? date : LocalDate.now();
        Sort sort = Sort.by(Sort.Direction.ASC, "price");
        
        // 查询指定日期和省份的数据
        List<CattleData> dataList = cattleDataRepository.findByProvinceAndCreateTimeDate(province.trim(), queryDate, sort);
        return dataList;
    }

    @Override
    @Transactional
    public List<CattleData> getCattleDataByType(String type, LocalDate date) {
        // 如果date为null，使用今天
        LocalDate queryDate = date != null ? date : LocalDate.now();
        Sort sort = Sort.by(Sort.Direction.ASC, "price");
        
        // 查询指定日期和品种的数据
        List<CattleData> dataList = cattleDataRepository.findByTypeAndCreateTimeDate(type.trim(), queryDate, sort);
        return dataList;
    }
    
    /**
     * 按 location 字段去重处理
     * 如果同一个 location 有多条记录，保留最新的一条（up_time最大），更新其他记录
     * @param dataList 原始数据列表
     * @param province 省份筛选条件（可选，用于重新查询时保持筛选）
     * @param type 品种筛选条件（可选，用于重新查询时保持筛选）
     */
    private List<CattleData> deduplicateByLocation(List<CattleData> dataList, String province, String type) {
        if (dataList == null || dataList.isEmpty()) {
            return dataList;
        }
        
        System.out.println("[查询去重] 开始按 type + location 去重处理");
        System.out.println("[查询去重] 去重前记录数: " + dataList.size());
        
        // 按 type + location 分组，找出每个 type + location 组合的最新记录
        java.util.Map<String, CattleData> typeLocationMap = new java.util.HashMap<>();
        java.util.List<CattleData> duplicatesToUpdate = new java.util.ArrayList<>();
        
        for (CattleData item : dataList) {
            String itemType = item.getType();
            String location = item.getLocation();
            if ((itemType == null || itemType.trim().isEmpty()) || 
                (location == null || location.trim().isEmpty())) {
                continue;
            }
            
            String trimmedType = itemType.trim();
            String trimmedLocation = location.trim();
            String key = trimmedType + "|" + trimmedLocation; // 使用 | 作为分隔符
            
            if (!typeLocationMap.containsKey(key)) {
                // 第一次遇到该 type + location 组合，直接添加
                typeLocationMap.put(key, item);
            } else {
                // 已存在该 type + location 组合，比较更新时间，保留最新的
                CattleData existing = typeLocationMap.get(key);
                if (item.getUpTime() != null && existing.getUpTime() != null) {
                    if (item.getUpTime().isAfter(existing.getUpTime())) {
                        // 当前记录更新，标记旧记录需要更新
                        duplicatesToUpdate.add(existing);
                        typeLocationMap.put(key, item);
                    } else {
                        // 现有记录更新，标记当前记录需要更新
                        duplicatesToUpdate.add(item);
                    }
                } else if (item.getUpTime() != null) {
                    // 当前记录有更新时间，保留它
                    duplicatesToUpdate.add(existing);
                    typeLocationMap.put(key, item);
                } else if (existing.getUpTime() != null) {
                    // 现有记录有更新时间，保留现有记录
                    duplicatesToUpdate.add(item);
                } else {
                    // 都没有更新时间，保留ID较小的（通常是最早创建的）
                    if (item.getId() < existing.getId()) {
                        duplicatesToUpdate.add(existing);
                        typeLocationMap.put(key, item);
                    } else {
                        duplicatesToUpdate.add(item);
                    }
                }
            }
        }
        
        // 删除重复记录：只保留最新的记录，删除其他所有重复记录
        int deletedCount = 0;
        for (CattleData duplicate : duplicatesToUpdate) {
            String duplicateType = duplicate.getType() != null ? duplicate.getType().trim() : "";
            String duplicateLocation = duplicate.getLocation() != null ? duplicate.getLocation().trim() : "";
            String key = duplicateType + "|" + duplicateLocation;
            CattleData latest = typeLocationMap.get(key);
            if (latest != null && !latest.getId().equals(duplicate.getId())) {
                // 删除重复记录，只保留最新的
                System.out.println("[查询去重] 删除重复记录: ID=" + duplicate.getId() + ", type=[" + duplicateType + "], location=[" + duplicateLocation + "]");
                cattleDataRepository.delete(duplicate);
                deletedCount++;
            }
        }
        
        // 如果删除了重复记录，重新查询（保持原有的筛选条件）
        if (deletedCount > 0) {
            System.out.println("[查询去重] 删除了 " + deletedCount + " 条重复记录");
            // 重新查询数据（保持原有排序和筛选条件）
            Sort sort = Sort.by(Sort.Direction.ASC, "price");
            if (type != null && !type.trim().isEmpty()) {
                dataList = cattleDataRepository.findByType(type.trim(), sort);
            } else if (province != null && !province.trim().isEmpty()) {
                dataList = cattleDataRepository.findByProvince(province.trim(), sort);
            } else {
                dataList = cattleDataRepository.findAll(sort);
            }
        }
        
        // 最终去重：按 type + location 去重，每个 type + location 组合只保留一条（保留最新的）
        java.util.Map<String, CattleData> finalMap = new java.util.LinkedHashMap<>();
        for (CattleData item : dataList) {
            String itemType = item.getType();
            String location = item.getLocation();
            if ((itemType == null || itemType.trim().isEmpty()) || 
                (location == null || location.trim().isEmpty())) {
                continue;
            }
            
            String trimmedType = itemType.trim();
            String trimmedLocation = location.trim();
            String key = trimmedType + "|" + trimmedLocation;
            
            if (!finalMap.containsKey(key)) {
                finalMap.put(key, item);
            } else {
                CattleData existing = finalMap.get(key);
                if (item.getUpTime() != null && existing.getUpTime() != null) {
                    if (item.getUpTime().isAfter(existing.getUpTime())) {
                        finalMap.put(key, item);
                    }
                } else if (item.getUpTime() != null) {
                    finalMap.put(key, item);
                } else if (existing.getUpTime() != null) {
                    // 保持现有记录
                } else {
                    // 都没有更新时间，保留ID较小的
                    if (item.getId() < existing.getId()) {
                        finalMap.put(key, item);
                    }
                }
            }
        }
        
        dataList = new java.util.ArrayList<>(finalMap.values());
        System.out.println("[查询去重] 去重后记录数: " + dataList.size());
        System.out.println("[查询去重] 去重处理完成");
        
        return dataList;
    }

    @Override
    @Transactional(readOnly = true)
    public CattleData getCattleDataById(Integer id) {
        return cattleDataRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("牛只数据不存在，ID: " + id));
    }

    @Override
    @Transactional
    public CattleData createCattleData(CattleDataDTO dto) {
        CattleData cattleData = new CattleData();
        cattleData.setType(dto.getType());
        cattleData.setProvince(dto.getProvince());
        cattleData.setLocation(dto.getLocation());
        cattleData.setPrice(dto.getPrice());
        return cattleDataRepository.save(cattleData);
    }

    @Override
    @Transactional
    public CattleData updateCattleData(Integer id, CattleDataDTO dto) {
        CattleData cattleData = cattleDataRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("牛只数据不存在，ID: " + id));

        cattleData.setType(dto.getType());
        cattleData.setProvince(dto.getProvince());
        cattleData.setLocation(dto.getLocation());
        cattleData.setPrice(dto.getPrice());

        return cattleDataRepository.save(cattleData);
    }

    @Override
    @Transactional
    public void deleteCattleData(Integer id) {
        if (!cattleDataRepository.existsById(id)) {
            throw new RuntimeException("牛只数据不存在，ID: " + id);
        }
        cattleDataRepository.deleteById(id);
    }

    @Override
    @Transactional
    public ImportResult batchImportCattleData(List<CattleDataDTO> dataList) {
        List<CattleData> savedList = new ArrayList<>();
        int newCount = 0;
        int updateCount = 0; // 保留字段以兼容返回类型，但始终为0
        
        // 确定导入日期：统一使用导入时的当前日期
        LocalDate importDate = LocalDate.now();
        LocalDateTime startOfDay = importDate.atStartOfDay(); // 当天 00:00:00
        LocalDateTime endOfDay = importDate.atTime(23, 59, 59, 999999999); // 当天 23:59:59.999999999
        
        System.out.println("========== 开始导入数据，导入日期: " + importDate + " ==========");
        
        // 删除当天所有已存在的数据
        List<CattleData> todayData = cattleDataRepository.findByCreateTimeBetween(startOfDay, endOfDay);
        if (todayData != null && !todayData.isEmpty()) {
            System.out.println("========== 删除当天已存在的数据: " + todayData.size() + " 条 ==========");
            cattleDataRepository.deleteAll(todayData);
        }
        
        // 只新增，不做去重和更新
        LocalDateTime importDateTime = LocalDateTime.now(); // 统一使用导入时的当前时间
        
        for (CattleDataDTO dto : dataList) {
            // 验证必填字段
            String type = dto.getType() != null ? dto.getType().trim() : null;
            String location = dto.getLocation() != null ? dto.getLocation().trim() : null;
            
            if (type == null || type.isEmpty() || location == null || location.isEmpty()) {
                continue; // 跳过无效数据
            }
            
            // 创建新记录
            CattleData cattleData = new CattleData();
            cattleData.setType(type);
            cattleData.setProvince(dto.getProvince() != null ? dto.getProvince().trim() : null);
            cattleData.setLocation(location);
            cattleData.setPrice(dto.getPrice());
            
            // 统一设置create_time为导入时的当前时间
            cattleData.setCreateTime(importDateTime);
            
            CattleData saved = cattleDataRepository.save(cattleData);
            savedList.add(saved);
            newCount++;
            System.out.println("[新增] 创建新记录: ID=" + saved.getId() + ", type=[" + type + "], location=[" + location + "], price=" + dto.getPrice());
        }
        
        System.out.println("========== 导入完成: 新增 " + newCount + " 条数据 ==========");
        
        // 导入完成后，计算当天省份的平均价格并更新省份每日均价
        System.out.println("========== 开始计算当天省份平均价格并更新每日均价 ==========");
        calculateAndUpdateProvinceDailyPrices(importDate);
        System.out.println("========== 省份平均价格计算完成 ==========");
        
        return new ImportResult(savedList, newCount, updateCount);
    }
    
    /**
     * 计算当天省份的平均价格并更新省份每日均价
     * 只计算当天导入的数据
     *
     * @param importDate 导入日期
     */
    private void calculateAndUpdateProvinceDailyPrices(LocalDate importDate) {
        try {
            System.out.println("导入日期: " + importDate);
            
            // 获取所有15个省份（从 cattleprovince 表）
            List<com.example.cattletends.entity.CattleProvince> allProvinces = cattleProvinceService.getAllProvinceData(null);
            System.out.println("获取到 " + (allProvinces != null ? allProvinces.size() : 0) + " 个省份");
            
            if (allProvinces == null || allProvinces.isEmpty()) {
                System.out.println("没有找到省份数据，跳过省份平均价格计算");
                return;
            }
            
            // 只查询当天导入的数据
            Sort sort = Sort.by(Sort.Direction.ASC, "price");
            List<CattleData> todayDataList = cattleDataRepository.findByCreateTimeDate(importDate, sort);
            
            if (todayDataList == null || todayDataList.isEmpty()) {
                System.out.println("当天没有导入数据，跳过省份平均价格计算");
                return;
            }
            
            System.out.println("当天导入的数据条数: " + todayDataList.size());
            
            int updatedCount = 0;
            int createdCount = 0;
            
            // 按省份分组，计算每个省份的平均价格
            java.util.Map<String, java.util.Map<String, Object>> provinceStats = new java.util.HashMap<>();
            
            for (CattleData data : todayDataList) {
                if (data.getProvince() == null || data.getProvince().trim().isEmpty() || data.getPrice() == null) {
                    continue;
                }
                
                String originalProvince = data.getProvince().trim();
                String canonicalProvince = resolveProvinceNameForMatch(originalProvince);
                
                if (provinceStats.containsKey(canonicalProvince)) {
                    java.util.Map<String, Object> existing = provinceStats.get(canonicalProvince);
                    java.math.BigDecimal existingSum = (java.math.BigDecimal) existing.get("sum");
                    int existingCount = (Integer) existing.get("count");
                    existingSum = existingSum.add(data.getPrice());
                    existingCount++;
                    existing.put("sum", existingSum);
                    existing.put("count", existingCount);
                } else {
                    java.util.Map<String, Object> stats = new java.util.HashMap<>();
                    stats.put("sum", data.getPrice());
                    stats.put("count", 1);
                    provinceStats.put(canonicalProvince, stats);
                }
            }
            
            // 计算每个省份的平均价格并更新
            for (java.util.Map.Entry<String, java.util.Map<String, Object>> entry : provinceStats.entrySet()) {
                String province = entry.getKey();
                java.util.Map<String, Object> stats = entry.getValue();
                java.math.BigDecimal totalSum = (java.math.BigDecimal) stats.get("sum");
                int totalCount = (Integer) stats.get("count");
                
                // 计算平均值
                java.math.BigDecimal averagePrice = totalSum.divide(
                    java.math.BigDecimal.valueOf(totalCount), 
                    2, 
                    java.math.RoundingMode.HALF_UP
                );
                
                System.out.println("省份: " + province + ", 当天数据条数: " + totalCount + ", 平均价格: " + averagePrice);
                
                // 更新 cattleprovince 表的 province_price 字段
                java.util.Optional<com.example.cattletends.entity.CattleProvince> cattleProvinceOpt = 
                    cattleProvinceRepository.findFirstByProvince(province);
                if (cattleProvinceOpt.isPresent()) {
                    com.example.cattletends.entity.CattleProvince cattleProvince = cattleProvinceOpt.get();
                    cattleProvince.setProvincePrice(averagePrice);
                    cattleProvinceRepository.save(cattleProvince);
                    System.out.println("✓ 更新 cattleprovince 表的 province_price: " + province + ", 价格: " + averagePrice);
                }
                
                // 更新或创建省份每日均价记录
                provinceDailyPriceService.saveOrUpdate(province, averagePrice, importDate);
                updatedCount++;
                System.out.println("✓ 更新省份每日均价: " + province + ", 日期: " + importDate + ", 价格: " + averagePrice);
            }
            
            // 对于没有数据的省份，使用省份表中的省份均价（如果有）
            for (com.example.cattletends.entity.CattleProvince province : allProvinces) {
                String provinceName = province.getProvince();
                if (provinceName == null || provinceName.trim().isEmpty()) {
                    continue;
                }
                
                String trimmedProvince = provinceName.trim();
                if (!provinceStats.containsKey(trimmedProvince)) {
                    // 没有当天数据，使用省份表中的省份均价
                    if (province.getProvincePrice() != null) {
                        provinceDailyPriceService.saveOrUpdate(trimmedProvince, province.getProvincePrice(), importDate);
                        createdCount++;
                        System.out.println("✓ 创建省份每日均价（使用省份均价）: " + trimmedProvince + ", 日期: " + importDate + ", 价格: " + province.getProvincePrice());
                    }
                }
            }
            
            System.out.println("省份每日均价处理完成: 更新 " + updatedCount + " 条，创建 " + createdCount + " 条");
            
        } catch (Exception e) {
            System.err.println("计算省份平均价格失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    /**
     * 将牛只数据中的省份名称，转换为与 cattleprovince / province_daily_price 表中一致的标准省份名称
     * 例如：把“安徽省”“河北省”“新疆维吾尔自治区”等映射为“安徽”“河北”“新疆”等
     */
    private String resolveProvinceNameForMatch(String province) {
        if (province == null) {
            return null;
        }
        String trimmed = province.trim();
        
        // 1. 先按原样查找
        java.util.Optional<com.example.cattletends.entity.CattleProvince> exact = 
                cattleProvinceRepository.findFirstByProvince(trimmed);
        if (exact.isPresent()) {
            return exact.get().getProvince();
        }
        
        // 2. 尝试去掉常见后缀（省、市、自治区、回族、壮族、维吾尔）
        String shortName = trimmed
                .replace("维吾尔", "")
                .replace("回族", "")
                .replace("壮族", "")
                .replace("自治区", "")
                .replace("省", "")
                .replace("市", "")
                .trim();
        
        if (!shortName.equals(trimmed)) {
            java.util.Optional<com.example.cattletends.entity.CattleProvince> shortMatch =
                    cattleProvinceRepository.findFirstByProvince(shortName);
            if (shortMatch.isPresent()) {
                return shortMatch.get().getProvince();
            }
        }
        
        // 3. 找不到匹配时，退回原始名称（保证不会中断流程）
        return trimmed;
    }
}

