package com.ruoyi.tjfx.service.impl;

import com.alibaba.fastjson.JSON;
import com.ruoyi.tjfx.entity.*;
import com.ruoyi.tjfx.mapper.ReportMapper;
import com.ruoyi.tjfx.service.ReportService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ReportServiceImpl implements ReportService {

    @Autowired
    private ReportMapper reportMapper;

    /**
     * 整体销售分析
     * @param startDate
     * @param endDate
     * @param category
     * @param categorySpecs
     * @param customer
     * @param shop
     * @param brand
     * @param productCode
     * @return
     */
    @Override
    public OverallAnalysisVO overallAnalysis(String startDate, String endDate, String category, String categorySpecs, String customer, String shop, String brand, String productCode) {
        Map<String, Object> params = new HashMap<>();
        params.put("startDate", startDate);
        params.put("endDate", endDate);
        params.put("category", category);
        params.put("categorySpecs", categorySpecs);
        params.put("customer", customer);
        params.put("shop", shop);
        params.put("brand", brand);
        params.put("productCode", productCode);

        // 基础统计
        BasicStatsVO basicStats = reportMapper.selectBasicStats(params);

        // 去年同期
        String lastYearStart = LocalDate.parse(startDate).minusYears(1).toString();
        String lastYearEnd = LocalDate.parse(endDate).minusYears(1).toString();
        Map<String, Object> lastYearParams = new HashMap<>(params);
        lastYearParams.put("startDate", lastYearStart);
        lastYearParams.put("endDate", lastYearEnd);
        BasicStatsVO lastYearStats = reportMapper.selectLastYearStats(lastYearParams);

        // 上周期
        long days = LocalDate.parse(endDate).toEpochDay() - LocalDate.parse(startDate).toEpochDay();
        String prevStart = LocalDate.parse(startDate).minusDays(days + 1).toString();
        String prevEnd = LocalDate.parse(startDate).minusDays(1).toString();
        Map<String, Object> prevParams = new HashMap<>(params);
        prevParams.put("startDate", prevStart);
        prevParams.put("endDate", prevEnd);
        BasicStatsVO prevStats = reportMapper.selectPrevStats(prevParams);

        // 趋势
        List<TrendDataVO> trendData = reportMapper.selectTrendData(params);

        // TOP20
        List<TopProductVO> topProducts = reportMapper.selectTopProducts(params);

        // 品牌
        List<BrandDataVO> brandData = reportMapper.selectBrandData(params);

        // 计算同比、环比
        OverallAnalysisVO vo = new OverallAnalysisVO();
        vo.setBasicStats(basicStats);
        vo.setGrowthRates(
            new GrowthRatesVO((basicStats==null||lastYearStats==null)?"0":calcRate(basicStats.getTotalAmount(), lastYearStats.getTotalAmount()),
                (basicStats==null||lastYearStats==null)?"0":calcRate(basicStats.getTotalQuantity(), lastYearStats.getTotalQuantity()),
                (basicStats==null||prevStats==null)?"0":calcRate(basicStats.getTotalAmount(), prevStats.getTotalAmount()),
                (basicStats==null||prevStats==null)?"0":calcRate(basicStats.getTotalQuantity(), prevStats.getTotalQuantity()))
        );
        vo.setTrendData(trendData);
        vo.setTopProducts(topProducts);
        vo.setBrandData(brandData);
        return vo;
    }

    private String calcRate(BigDecimal now, BigDecimal prev) {
        if (now==null||now.compareTo(BigDecimal.ZERO) == 0||prev == null || prev.compareTo(BigDecimal.ZERO) == 0) return "0";
        return now.subtract(prev).divide(prev, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
    }

    @Override
    public ProductAnalysisVO productAnalysis(String startDate, String endDate, String productCode) {
        Map<String, Object> params = new HashMap<>();
        params.put("startDate", startDate);
        params.put("endDate", endDate);
        params.put("productCode", productCode);

        List<RankingDataVO> rankingData = reportMapper.selectProductRanking(params);
        List<TrendDataVO> trendData = reportMapper.selectProductTrend(params);

        ProductAnalysisVO vo = new ProductAnalysisVO();
        vo.setRankingData(rankingData);
        vo.setTrendData(trendData);
        return vo;
    }

    /**
     * 店铺销售分析
     * @param startDate
     * @param endDate
     * @param shop
     * @return
     */
    @Override
    public ShopAnalysisVO shopAnalysis(String startDate, String endDate, String shop) {
        Map<String, Object> params = new HashMap<>();
        params.put("startDate", startDate);
        params.put("endDate", endDate);
        params.put("shop", shop);

        BasicStatsVO basicStats = reportMapper.selectShopBasicStats(params);
        List<ShopAmountVO> shopAmountData = reportMapper.selectShopAmountData(params);
        List<ShopQuantityVO> shopQuantityData = reportMapper.selectShopQuantityData(params);
        List<CategoryTrendVO> categoryTrendData = reportMapper.selectCategoryTrendData(params);

        // 计算占比
        BigDecimal totalAmount = shopAmountData.stream()
            .map(vo -> BigDecimal.valueOf(vo.getAmount()))
            .reduce(BigDecimal.ZERO, BigDecimal::add);

        BigDecimal totalQuantity = shopQuantityData.stream()
            .map(vo -> BigDecimal.valueOf(vo.getQuantity()))
            .reduce(BigDecimal.ZERO, BigDecimal::add);
        shopAmountData.forEach(item -> {
            item.setPercentage(totalAmount.compareTo(BigDecimal.ZERO) == 0 ? "0" :
                new BigDecimal(item.getAmount()).divide(totalAmount, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).toString());
        });
        shopQuantityData.forEach(item -> {
            item.setPercentage(totalQuantity.compareTo(BigDecimal.ZERO) == 0 ? "0" :
                new BigDecimal(item.getQuantity()).divide(totalQuantity, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).toString());
        });

        ShopAnalysisVO vo = new ShopAnalysisVO();
        vo.setBasicStats(basicStats);
        vo.setShopAmountData(shopAmountData);
        vo.setShopQuantityData(shopQuantityData);
        vo.setCategoryTrendData(categoryTrendData);
        return vo;
    }

    /**
     * 品类销售分析
     * @param startDate
     * @param endDate
     * @param category
     * @return
     */
    @Override
    public CategoryAnalysisVO categoryAnalysis(String startDate, String endDate, String category) {
        Map<String, Object> params = new HashMap<>();
        params.put("startDate", startDate);
        params.put("endDate", endDate);
        params.put("category", category);

        List<Map<String, Object>> specsRawData = reportMapper.selectSpecsRawData(params);

        // 解析规格数据
        Map<String, Map<String, DimensionStatsVO>> dimensionStats = new HashMap<>();
        Set<String> availableDimensions = new HashSet<>();
        for (Map<String, Object> item : specsRawData) {
            String specsStr = (String) item.get("category_specs");
            BigDecimal quantity = (BigDecimal) item.get("quantity");
            BigDecimal amount = (BigDecimal) item.get("amount");
            try {
                Map<String, Object> specsObj = JSON.parseObject(specsStr, Map.class);
                for (Map.Entry<String, Object> entry : specsObj.entrySet()) {
                    String dim = entry.getKey();
                    String val = entry.getValue() == null ? "" : entry.getValue().toString();
                    if (!val.trim().isEmpty()) {
                        availableDimensions.add(dim);
                        dimensionStats.putIfAbsent(dim, new HashMap<>());
                        Map<String, DimensionStatsVO> dimMap = dimensionStats.get(dim);
                        dimMap.putIfAbsent(val, new DimensionStatsVO(val, 0d, 0d,  "0",0d));
                        DimensionStatsVO stats = dimMap.get(val);
                        stats.setQuantity(new BigDecimal(stats.getQuantity()).add(quantity == null ? BigDecimal.ZERO : quantity).doubleValue());
                        stats.setAmount(new BigDecimal(stats.getAmount()).add(amount == null ? BigDecimal.ZERO : amount).doubleValue());
                    }
                }
            } catch (Exception e) {
                // 非JSON格式跳过
            }
        }
        // 计算占比
        Map<String, DimensionChartVO> dimensionCharts = new HashMap<>();
        for (String dim : dimensionStats.keySet()) {
            Map<String, DimensionStatsVO> dimMap = dimensionStats.get(dim);
            //BigDecimal totalAmount = dimMap.values().stream().map(DimensionStatsVO::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            //BigDecimal totalQuantity = dimMap.values().stream().map(DimensionStatsVO::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal totalAmount = dimMap.values().stream()
                .map(vo -> BigDecimal.valueOf(vo.getAmount()))
                .reduce(BigDecimal.ZERO, BigDecimal::add);

            BigDecimal totalQuantity = dimMap.values().stream()
                .map(vo -> BigDecimal.valueOf(vo.getQuantity()))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
            List<DimensionStatsVO> amountData = new ArrayList<>();
            List<DimensionStatsVO> quantityData = new ArrayList<>();
            for (DimensionStatsVO stats : dimMap.values()) {
                //金额集合
                stats.setPercentage(totalAmount.compareTo(BigDecimal.ZERO) == 0 ? "0" :
                    new BigDecimal(stats.getAmount()).divide(totalAmount, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).toString());
                stats.setValue(stats.getAmount());
                amountData.add(stats);

                //销量集合
                DimensionStatsVO statsQuantity = new DimensionStatsVO(
                    stats.getName(),
                    stats.getQuantity(),
                    stats.getAmount(),
                    stats.getPercentage(),
                    stats.getValue());
                statsQuantity.setPercentage(totalQuantity.compareTo(BigDecimal.ZERO) == 0 ? "0" :
                    new BigDecimal(statsQuantity.getQuantity()).divide(totalQuantity, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).toString());
                statsQuantity.setValue(statsQuantity.getQuantity());
                quantityData.add(statsQuantity);
            }
            amountData.sort((a, b) -> b.getAmount().compareTo(a.getAmount()));
            quantityData.sort((a, b) -> b.getQuantity().compareTo(a.getQuantity()));
            dimensionCharts.put(dim, new DimensionChartVO(amountData, quantityData));
        }

        //添加品牌  因为没在分类规格里 所以只能额外添加了
// 添加品牌 因为没在分类规格里 所以只能额外添加了
        List<Map<String, Object>> brandRawData = reportMapper.selectBrandRawData(params);
        if (brandRawData != null && !brandRawData.isEmpty()) {
            List<DimensionStatsVO> amountData = new ArrayList<>();
            List<DimensionStatsVO> quantityData = new ArrayList<>();

            // 计算总金额和总数量
            double totalAmount = brandRawData.stream()
                .mapToDouble(vo -> Double.parseDouble(vo.get("amount").toString()))
                .sum();

            double totalQuantity = brandRawData.stream()
                .mapToDouble(vo -> Double.parseDouble(vo.get("quantity").toString()))
                .sum();

            for (Map<String, Object> map : brandRawData) {
                String brand = map.get("brand") != null ? map.get("brand").toString() : "未知品牌";
                double quantity = Double.parseDouble(map.get("quantity").toString());
                double amount = Double.parseDouble(map.get("amount").toString());

                // 金额占比（去掉%）
                String amountPercentage = totalAmount > 0
                    ? String.format("%.2f", amount * 100 / totalAmount)
                    : "0.00";

                DimensionStatsVO amountVO = new DimensionStatsVO(
                    brand,
                    quantity,
                    amount,
                    amountPercentage,
                    amount
                );
                amountData.add(amountVO);

                // 数量占比（去掉%）
                String quantityPercentage = totalQuantity > 0
                    ? String.format("%.2f", quantity * 100 / totalQuantity)
                    : "0.00";

                DimensionStatsVO quantityVO = new DimensionStatsVO(
                    brand,
                    quantity,
                    amount,
                    quantityPercentage,
                    quantity
                );
                quantityData.add(quantityVO);
            }

            DimensionChartVO dimensionChartVO = new DimensionChartVO(amountData, quantityData);
            dimensionCharts.put("品牌", dimensionChartVO);
            availableDimensions.add("品牌");
        }


        CategoryAnalysisVO vo = new CategoryAnalysisVO();
        vo.setDimensionCharts(dimensionCharts);
        vo.setAvailableDimensions(new ArrayList<>(availableDimensions));
        vo.setCurrentCategory(category == null ? "全部分类" : category);
        return vo;
    }

    @Override
    public FilterOptionsVO filterOptions() {
        FilterOptionsVO vo = new FilterOptionsVO();
        vo.setCategories(reportMapper.selectCategories());
        vo.setCategorySpecs(reportMapper.selectCategorySpecs());
        vo.setCustomers(reportMapper.selectCustomers());
        vo.setShops(reportMapper.selectShops());
        vo.setBrands(reportMapper.selectBrands());
        return vo;
    }

    @Override
    public List<ProductCodeSuggestionVO> productCodeSuggestions(String keyword) {
        List<Map<String, Object>> suggestions = reportMapper.selectProductCodeSuggestions("%" + keyword + "%");
        return suggestions.stream().map(item -> {
            String productName = (String) item.get("product_name");
            String categorySpecs = (String) item.get("category_specs");
            String categoryName = (String) item.get("category_name");
            String displayText = productName == null ? "" : productName;
            String specsText = "";
            if (categorySpecs != null) {
                try {
                    Map<String, Object> specs = JSON.parseObject(categorySpecs, Map.class);
                    specsText = specs.values().stream().filter(Objects::nonNull).map(Object::toString).collect(Collectors.joining("+"));
                } catch (Exception e) {
                    specsText = categorySpecs;
                }
            }
            if (!specsText.isEmpty()) displayText += "+" + specsText;
            if (categoryName != null && !categoryName.isEmpty()) displayText += "-" + categoryName;
            return new ProductCodeSuggestionVO((String) item.get("product_code"), displayText);
        }).collect(Collectors.toList());
    }
}
