package com.ruoyi.tjfx.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.tjfx.common.PageResponse;
import com.ruoyi.tjfx.entity.*;
import com.ruoyi.tjfx.mapper.AnalysisDataMapper;
import com.ruoyi.tjfx.mapper.BaseDataMapper;
import com.ruoyi.tjfx.mapper.CategoryMapper;
import com.ruoyi.tjfx.mapper.ShopCustomerMapper;
import com.ruoyi.tjfx.service.AnalysisDataService;
import com.ruoyi.tjfx.util.ExcelUtil;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 分析数据Service实现类
 */
@Slf4j
@Service
public class AnalysisDataServiceImpl implements AnalysisDataService {

    @Autowired
    private AnalysisDataMapper analysisDataMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private BaseDataMapper baseDataMapper;

    @Autowired
    private ShopCustomerMapper shopCustomerMapper;

    @Autowired
    private ExcelUtil excelUtil;

    @Override
    public PageResponse<AnalysisData> getPage(Integer page, Integer pageSize, String productCode,
                                              String productName, String customerName, String shopName,
                                              Integer status, LocalDate startDate, LocalDate endDate) {

        Page<AnalysisData> pageParam = new Page<>(page, pageSize);
        IPage<AnalysisData> result = analysisDataMapper.selectPageWithConditions(pageParam,
                productCode, productName, customerName, shopName, status, startDate, endDate);

        PageResponse.Pagination pagination = new PageResponse.Pagination(
                result.getTotal(), page, pageSize);

        return new PageResponse<>(result.getRecords(), pagination);
    }

    @Override
    public AnalysisData getById(Long id) {
        return analysisDataMapper.selectById(id);
    }

    @Override
    @Transactional
    public void updateById(Long id, AnalysisData analysisData) {
        AnalysisData existing = analysisDataMapper.selectById(id);
        if (existing == null) {
            throw new RuntimeException("分析数据不存在");
        }

        analysisData.setId(id);
        analysisDataMapper.updateById(analysisData);
    }

    @Override
    @Transactional
    public void deleteById(Long id) {
        AnalysisData existing = analysisDataMapper.selectById(id);
        if (existing == null) {
            throw new RuntimeException("分析数据不存在");
        }

        analysisDataMapper.deleteById(id);
    }

    @Override
    @Transactional
    public void deleteBatchByIds(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            throw new RuntimeException("请选择要删除的数据");
        }

        analysisDataMapper.deleteBatchIds(ids);
    }

    @Override
    public void exportExcel(HttpServletResponse response, String productCode, String productName,
                           String customerName, String shopName, Integer status,
                           LocalDate startDate, LocalDate endDate, Integer page, Integer pageSize) {

        // 如果page和pageSize为null，则导出全部数据
        if (page == null || pageSize == null) {
            List<AnalysisData> dataList = analysisDataMapper.selectAllWithConditions(
                    productCode, productName, customerName, shopName, status, startDate, endDate);

            if (dataList.isEmpty()) {
                throw new RuntimeException("暂无数据可导出");
            }

            // 按分类分组
            Map<String, List<AnalysisData>> groupedData = dataList.stream()
                    .collect(Collectors.groupingBy(data ->
                            StringUtils.hasText(data.getCategory()) ? data.getCategory() : "未分类"));

            excelUtil.exportAnalysisData(response, groupedData);
        } else {
            // 分页导出
            Page<AnalysisData> pageParam = new Page<>(page, pageSize);

            // 构建查询条件
            QueryWrapper<AnalysisData> queryWrapper = new QueryWrapper<>();
            if (StringUtils.hasText(productCode)) {
                queryWrapper.like("product_code", productCode);
            }
            if (StringUtils.hasText(productName)) {
                queryWrapper.like("product_name", productName);
            }
            if (StringUtils.hasText(customerName)) {
                queryWrapper.like("customer_name", customerName);
            }
            if (StringUtils.hasText(shopName)) {
                queryWrapper.like("shop_name", shopName);
            }
            if (status != null) {
                queryWrapper.eq("status", status);
            }
            if (startDate != null) {
                queryWrapper.ge("date", startDate);
            }
            if (endDate != null) {
                queryWrapper.le("date", endDate);
            }
            queryWrapper.orderByDesc("id");

            // 执行分页查询
            IPage<AnalysisData> pageResult = analysisDataMapper.selectPage(pageParam, queryWrapper);

            if (pageResult.getRecords().isEmpty()) {
                throw new RuntimeException("暂无数据可导出");
            }

            // 按分类分组
            Map<String, List<AnalysisData>> groupedData = pageResult.getRecords().stream()
                    .collect(Collectors.groupingBy(data ->
                            StringUtils.hasText(data.getCategory()) ? data.getCategory() : "未分类"));

            excelUtil.exportAnalysisData(response, groupedData);
        }
    }

    @Override
    public Map<String, Object> importExcel(String filePath, Long categoryId) {
        // 验证分类是否存在
        Category category = categoryMapper.selectById(categoryId);
        if (category == null) {
            throw new RuntimeException("分类不存在");
        }

        // 读取Excel文件
        List<Map<String, Object>> excelData = excelUtil.readExcel(filePath);
        if (excelData.isEmpty()) {
            throw new RuntimeException("Excel文件为空或格式不正确");
        }

        return processExcelData(excelData, category, filePath);
    }

    @Override
    public Map<String, Object> importBatchExcel(List<String> filePaths, Long categoryId) {
        // 验证分类是否存在
        Category category = categoryMapper.selectById(categoryId);
        if (category == null) {
            throw new RuntimeException("分类不存在");
        }

        List<AnalysisData> allProcessedData = new ArrayList<>();
        List<String> allErrors = new ArrayList<>();
        int totalRows = 0;

        for (String filePath : filePaths) {
            // 1. 读取 Excel 数据（第一行为表头）
/*            List<ShopCustomerExcelDTO> excelDTOList  = EasyExcel.read(file.getInputStream())
                .head(ShopCustomerExcelDTO.class).headRowNumber(1).sheet().doReadSync();*/
            try {
                List<Map<String, Object>> excelData = excelUtil.readExcel(filePath);
                if (excelData.isEmpty()) {
                    allErrors.add("文件为空或格式不正确: " + filePath);
                    continue;
                }
                //删除里面都是null或者""的map
                excelData.removeIf(map ->
                    map.values().stream()
                        .allMatch(value -> value == null || "".equals(value))
                );

                totalRows += excelData.size();
                Map<String, Object> result = processExcelData(excelData, category, filePath);

                @SuppressWarnings("unchecked")
                List<AnalysisData> processedData = (List<AnalysisData>) result.get("data");
                @SuppressWarnings("unchecked")
                List<String> errors = (List<String>) result.get("errorDetails");

                allProcessedData.addAll(processedData);
                allErrors.addAll(errors);

            } catch (Exception e) {
                allErrors.add("处理文件失败: " + filePath + " - " + e.getMessage());
            }
        }

        Map<String, Object> result = new HashMap<>();
        result.put("total", totalRows);
        result.put("processed", allProcessedData.size());
        result.put("errors", allErrors.size());
        result.put("data", allProcessedData);
        result.put("errorDetails", allErrors.size() > 0 ? allErrors.subList(0, Math.min(20, allErrors.size())) : new ArrayList<>());
        result.put("filesProcessed", filePaths.size());

        return result;
    }

    @Override
    public Map<String, Object> importFbaExcel(String filePath, String shopName) {
        // 验证店铺是否存在
        ShopCustomer shopCustomer = shopCustomerMapper.selectByShopName(shopName);
        if (shopCustomer == null) {
            throw new RuntimeException("店铺不存在");
        }

        // 读取Excel文件
        List<Map<String, Object>> excelData = excelUtil.readFbaExcel(filePath);
        if (excelData.isEmpty()) {
            throw new RuntimeException("Excel文件为空或格式不正确");
        }

        return processFbaData(excelData, shopCustomer, filePath);
    }

    @Override
    public Map<String, Object> importBatchFbaExcel(List<String> filePaths, String shopName) {
        // 验证店铺是否存在
        ShopCustomer shopCustomer = shopCustomerMapper.selectByShopName(shopName);
        if (shopCustomer == null) {
            throw new RuntimeException("店铺不存在");
        }

        List<AnalysisData> allProcessedData = new ArrayList<>();
        List<String> allErrors = new ArrayList<>();
        int totalRows = 0;

        for (String filePath : filePaths) {
            try {
                List<Map<String, Object>> excelData = excelUtil.readFbaExcel(filePath);
                if (excelData.isEmpty()) {
                    allErrors.add("文件为空或格式不正确: " + filePath);
                    continue;
                }

                totalRows += excelData.size();
                Map<String, Object> result = processFbaData(excelData, shopCustomer, filePath);

                @SuppressWarnings("unchecked")
                List<AnalysisData> processedData = (List<AnalysisData>) result.get("data");
                @SuppressWarnings("unchecked")
                List<String> errors = (List<String>) result.get("errorDetails");

                allProcessedData.addAll(processedData);
                allErrors.addAll(errors);

            } catch (Exception e) {
                allErrors.add("处理文件失败: " + filePath + " - " + e.getMessage());
            }
        }

        Map<String, Object> result = new HashMap<>();
        result.put("total", totalRows);
        result.put("processed", allProcessedData.size());
        result.put("errors", allErrors.size());
        result.put("data", allProcessedData);
        result.put("errorDetails", allErrors.size() > 0 ? allErrors.subList(0, Math.min(20, allErrors.size())) : new ArrayList<>());
        result.put("filesProcessed", filePaths.size());

        return result;
    }

    @Override
    @Transactional
    public Map<String, Object> saveImportedData(List<AnalysisData> dataList) {
        if (dataList == null || dataList.isEmpty()) {
            throw new RuntimeException("没有可保存的数据");
        }

        int insertedCount = 0;
        int updatedCount = 0;
        List<String> errors = new ArrayList<>();

        for (AnalysisData data : dataList) {
            try {
                // 检查是否存在相同的记录
                AnalysisData existing = analysisDataMapper.selectByUniqueCondition(
                        data.getDate(), data.getShopName(), data.getProductCode(),
                        data.getDeliveryType(), data.getOrderNumber(), data.getRowNumber());

                if (existing != null) {
                    // 更新现有记录
                    data.setId(existing.getId());
                    analysisDataMapper.updateById(data);
                    updatedCount++;
                } else {
                    // 插入新记录
                    analysisDataMapper.insert(data);
                    insertedCount++;
                }
            } catch (Exception e) {
                errors.add("保存数据失败: " + e.getMessage());
            }
        }

        Map<String, Object> result = new HashMap<>();
        result.put("total", dataList.size());
        result.put("saved", insertedCount + updatedCount);
        result.put("inserted", insertedCount);
        result.put("updated", updatedCount);
        result.put("failed", errors.size());
        result.put("errors", errors.size() > 0 ? errors.subList(0, Math.min(10, errors.size())) : new ArrayList<>());

        return result;
    }

    /**
     * 处理Excel数据
     */
    private Map<String, Object> processExcelData(List<Map<String, Object>> excelData,
                                                Category category, String fileName) {
        List<AnalysisData> processedData = new ArrayList<>();
        List<String> errors = new ArrayList<>();
        int filteredCount = 0;

        for (int i = 0; i < excelData.size(); i++) {
            Map<String, Object> row = excelData.get(i);
            int rowIndex = i + 2; // Excel行号

            try {
                // 检查是否需要过滤
                if (shouldFilterData(row)) {
                    filteredCount++;
                    continue;
                }

                // 验证必填字段
                if (!validateRequiredFields(row, rowIndex, fileName, errors)) {
                    continue;
                }

                // 处理数据
                AnalysisData analysisData = processRowData(row, category, rowIndex, fileName);
                if (analysisData != null) {
                    processedData.add(analysisData);
                }

            } catch (Exception e) {
                errors.add(String.format("文件[%s]第(%d)行: 数据处理失败 - %s", fileName, rowIndex, e.getMessage()));
            }
        }

        Map<String, Object> result = new HashMap<>();
        result.put("total", excelData.size());
        result.put("processed", processedData.size());
        result.put("filtered", filteredCount);
        result.put("errors", errors.size());
        result.put("data", processedData);
        result.put("errorDetails", errors.size() > 0 ? errors.subList(0, Math.min(10, errors.size())) : new ArrayList<>());

        return result;
    }

    /**
     * 处理FBA数据
     */
    private Map<String, Object> processFbaData(List<Map<String, Object>> excelData,
                                              ShopCustomer shopCustomer, String fileName) {
        List<AnalysisData> processedData = new ArrayList<>();
        List<String> errors = new ArrayList<>();

        for (int i = 0; i < excelData.size(); i++) {
            Map<String, Object> row = excelData.get(i);
            int rowIndex = i + 2; // Excel行号

            try {
                // 验证必填字段
                if (!validateFbaRequiredFields(row, rowIndex, fileName, errors)) {
                    continue;
                }

                // 处理FBA数据
                AnalysisData analysisData = processFbaRowData(row, shopCustomer, rowIndex, fileName);
                if (analysisData != null) {
                    processedData.add(analysisData);
                }

            } catch (Exception e) {
                errors.add(String.format("文件[%s]第(%d)行: 数据处理失败 - %s", fileName, rowIndex, e.getMessage()));
            }
        }

        Map<String, Object> result = new HashMap<>();
        result.put("total", excelData.size());
        result.put("processed", processedData.size());
        result.put("filtered", 0); // FBA数据不需要过滤
        result.put("errors", errors.size());
        result.put("data", processedData);
        result.put("errorDetails", errors.size() > 0 ? errors.subList(0, Math.min(10, errors.size())) : new ArrayList<>());

        return result;
    }

    /**
     * 检查是否需要过滤数据
     */
    private boolean shouldFilterData(Map<String, Object> row) {
        String destination = String.valueOf(row.getOrDefault("目的地", ""));
        String deliveryType = String.valueOf(row.getOrDefault("出库类型", ""));
        String remarks = String.valueOf(row.getOrDefault("备注", ""));

        // 过滤条件
        return (destination.equals("SPD") && deliveryType.equals("批发出库") && remarks.trim().isEmpty()) ||
               deliveryType.equals("库内换码") ||
               deliveryType.equals("返品交互") ||
               destination.equals("Amazon") ||
               (destination.equals("開元") && deliveryType.equals("批发出库") && remarks.trim().isEmpty());
    }

    /**
     * 验证必填字段
     */
    private boolean validateRequiredFields(Map<String, Object> row, int rowIndex,
                                        String fileName, List<String> errors) {
        if (!row.containsKey("店铺名称") || StringUtils.isEmpty(row.get("店铺名称"))) {
            errors.add(String.format("文件[%s]第(%d)行: 店铺名称不能为空", fileName, rowIndex));
            return false;
        }
        if (!row.containsKey("商品编号") || StringUtils.isEmpty(row.get("商品编号"))) {
            errors.add(String.format("文件[%s]第(%d)行: 商品编号不能为空", fileName, rowIndex));
            return false;
        }
        if (!row.containsKey("商品名称") || StringUtils.isEmpty(row.get("商品名称"))) {
            errors.add(String.format("文件[%s]第(%d)行: 商品名称不能为空", fileName, rowIndex));
            return false;
        }
        if (!row.containsKey("数量") || StringUtils.isEmpty(row.get("数量"))) {
            errors.add(String.format("文件[%s]第(%d)行: 数量不能为空", fileName, rowIndex));
            return false;
        }
        if (!row.containsKey("单价") || StringUtils.isEmpty(row.get("单价"))) {
            errors.add(String.format("文件[%s]第(%d)行: 单价不能为空", fileName, rowIndex));
            return false;
        }
        return true;
    }

    /**
     * 验证FBA必填字段
     */
    private boolean validateFbaRequiredFields(Map<String, Object> row, int rowIndex,
                                            String fileName, List<String> errors) {
        if (!row.containsKey("出荷日") || StringUtils.isEmpty(row.get("出荷日"))) {
            errors.add(String.format("文件[%s]第(%d)行: 出荷日不能为空", fileName, rowIndex));
            return false;
        }
        if (!row.containsKey("出品者SKU") || StringUtils.isEmpty(row.get("出品者SKU"))) {
            errors.add(String.format("文件[%s]第(%d)行: 出品者SKU不能为空", fileName, rowIndex));
            return false;
        }
        if (!row.containsKey("数量") || StringUtils.isEmpty(row.get("数量"))) {
            errors.add(String.format("文件[%s]第(%d)行: 数量不能为空", fileName, rowIndex));
            return false;
        }
        return true;
    }

    /**
     * 处理行数据
     */
    private AnalysisData processRowData(Map<String, Object> row, Category category,
                                      int rowIndex, String fileName) {
        try {
            // 格式化日期
            LocalDate formattedDate = excelUtil.processExcelDate(row.get("出库日期"));
            if (formattedDate == null) {
                throw new RuntimeException("日期格式不正确");
            }

            String shopName = String.valueOf(row.get("店铺名称")).trim();
            String productCode = String.valueOf(row.get("商品编号")).trim();
            String productName = String.valueOf(row.get("商品名称")).trim();

            // 匹配店铺客户关系
            ShopCustomer shopCustomer = shopCustomerMapper.selectByShopName(shopName);
            String customerName = shopCustomer != null ? shopCustomer.getCustomerName() :
                                String.valueOf(row.getOrDefault("客户名称", ""));

            // 匹配基准数据分类规格
            BaseData baseData = baseDataMapper.selectByProductCodeAndCategoryId(productCode, category.getId());
            String categoryName = baseData != null ? category.getName() : category.getName();
            String categorySpecs = baseData != null ? baseData.getCategorySpecs() : "";

            // 计算合计金额
            BigDecimal quantity = new BigDecimal(String.valueOf(row.get("数量")));
            BigDecimal unitPrice = new BigDecimal(String.valueOf(row.get("单价")));
            BigDecimal shipping = new BigDecimal(String.valueOf(row.getOrDefault("送料", "0")));
            BigDecimal cod = new BigDecimal(String.valueOf(row.getOrDefault("代引", "0")));
            BigDecimal totalAmount = quantity.multiply(unitPrice).add(shipping).add(cod);

            // 确定状态
            int status = 1; // 默认正常
            if (StringUtils.isEmpty(customerName)) {
                status = 2; // 客户名称未匹配
            } else if (baseData == null) {
                status = 3; // 分类规格未匹配
            }

            AnalysisData analysisData = new AnalysisData();
            analysisData.setDate(formattedDate);
            analysisData.setShopName(shopName);
            analysisData.setProductCode(productCode);
            analysisData.setProductName(productName);
            analysisData.setCustomerName(customerName);
            analysisData.setCategory(categoryName);
            analysisData.setCategorySpecs(categorySpecs);
            analysisData.setQuantity(quantity.intValue());
            analysisData.setTotalAmount(totalAmount);
            analysisData.setSource("物流出库数据");
            analysisData.setStatus(status);
            analysisData.setDeliveryType(String.valueOf(row.getOrDefault("出库类型", "")));
            analysisData.setDestination(String.valueOf(row.getOrDefault("目的地", "")));
            analysisData.setRemarks(String.valueOf(row.getOrDefault("备注", "")));
            analysisData.setOrderNumber(String.valueOf(row.getOrDefault("注文番号", "")));
            analysisData.setRowNumber(rowIndex);
            analysisData.setBrand(baseData != null ? baseData.getBrand() : "");

            return analysisData;

        } catch (Exception e) {
            throw new RuntimeException("数据处理失败: " + e.getMessage());
        }
    }

    /**
     * 处理FBA行数据
     */
    private AnalysisData processFbaRowData(Map<String, Object> row, ShopCustomer shopCustomer,
                                         int rowIndex, String fileName) {
        try {
            // 处理日期
            LocalDate formattedDate = excelUtil.processFbaDate(row.get("出荷日"));
            if (formattedDate == null) {
                throw new RuntimeException("日期格式不正确");
            }

            // 处理SKU
            String rawSku = String.valueOf(row.get("出品者SKU")).trim();
            String processedSku = excelUtil.processFbaSku(rawSku);
            if (StringUtils.isEmpty(processedSku)) {
                throw new RuntimeException("SKU格式不正确");
            }

            // 匹配商品信息
            BaseDataVO baseData = baseDataMapper.selectByProductCode(processedSku);
            String productName = baseData != null ? baseData.getProductName() : "";
            String category = baseData != null ? baseData.getCategoryName() : "";//这里存名字
            String categorySpecs = baseData != null ? baseData.getCategorySpecs() : "";
            String brand = baseData != null ? baseData.getBrand() : "";

            // 获取客户名称
            String customerName = shopCustomer.getCustomerName();

            // 计算合计金额
            BigDecimal quantity = new BigDecimal(String.valueOf(row.get("数量")));
            BigDecimal unitPrice = new BigDecimal(String.valueOf(row.getOrDefault("商品金額（商品1点ごと）", "0")));
            BigDecimal shipping = new BigDecimal(String.valueOf(row.getOrDefault("配送料", "0")));
            BigDecimal giftWrap = new BigDecimal(String.valueOf(row.getOrDefault("ギフト包装手数料", "0")));
            BigDecimal totalAmount = quantity.multiply(unitPrice).add(shipping).add(giftWrap);

            // 确定状态
            int status = 1; // 默认正常
            if (StringUtils.isEmpty(customerName)) {
                status = 2; // 客户名称未匹配
            } else if (baseData == null) {
                status = 3; // 分类规格未匹配
            }

            // FBA 只保存正常的数据
            if (status != 1) {
                return null;
            }

            AnalysisData analysisData = new AnalysisData();
            analysisData.setDate(formattedDate);
            analysisData.setShopName(shopCustomer.getShopName());
            analysisData.setProductCode(processedSku);
            analysisData.setProductName(productName);
            analysisData.setCustomerName(customerName);
            analysisData.setCategory(category);
            analysisData.setCategorySpecs(categorySpecs);
            analysisData.setQuantity(quantity.intValue());
            analysisData.setTotalAmount(totalAmount);
            analysisData.setSource("FBA出库数据");
            analysisData.setStatus(status);
            analysisData.setDeliveryType("FBA");
            analysisData.setDestination("");
            analysisData.setRemarks("");
            analysisData.setOrderNumber(String.valueOf(row.getOrDefault("Amazon注文番号", "")));
            analysisData.setRowNumber(rowIndex);
            analysisData.setBrand(brand);

            return analysisData;

        } catch (Exception e) {
            throw new RuntimeException("数据处理失败: " + e.getMessage());
        }
    }
}
