package com.lframework.xingyun.sc.impl.chart;


import cn.hutool.core.collection.CollectionUtil;
import com.lframework.xingyun.sc.dto.chart.OrderProportionDto;
import com.lframework.xingyun.sc.mappers.ProductStockMapper;
import com.lframework.xingyun.sc.mappers.PurchaseOrderMapper;
import com.lframework.xingyun.sc.mappers.SaleOrderMapper;
import com.lframework.xingyun.sc.service.chart.HomeChartService;
import com.lframework.xingyun.sc.util.ProportionUtils;
import com.lframework.xingyun.sc.vo.chart.*;
import com.lframework.xingyun.template.core.entity.SysUser;
import com.lframework.xingyun.template.inner.mappers.system.SysUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;


@Service
public class HomeChartServiceImpl implements HomeChartService {

  @Autowired
  private PurchaseOrderMapper purchaseOrderMapper;

  @Autowired
  private SaleOrderMapper saleOrderMapper;

  @Autowired
  private ProductStockMapper productStockMapper;

  @Autowired
  private SysUserMapper sysUserMapper;


  @Override
  public OrderTodaysDataVo statisticsTodaysOrderData() {

    OrderTodaysDataVo orderDataVo=new OrderTodaysDataVo();
    List<SaleOrderVo> saleOrderVoList= saleOrderMapper.CheckTodysSaleOrderLits();

    BigDecimal todayTotalSaleAmount = BigDecimal.ZERO;

    for (SaleOrderVo saleOrderVo : saleOrderVoList) {
      if (saleOrderVo.getTotalAmount() != null) {
        todayTotalSaleAmount = todayTotalSaleAmount.add(saleOrderVo.getTotalAmount());
      }
    }

    orderDataVo.setTodaySaleOrderAmount(todayTotalSaleAmount);
    orderDataVo.setTodaySaleQuantityCount(saleOrderVoList.size());


    BigDecimal todayTotalPurchaseAmount = BigDecimal.ZERO;
    List<PurchaseOrderVo> purchaseOrderVoList=purchaseOrderMapper.TodaysPurchaseOrder();
    for (PurchaseOrderVo purchaseOrderVo : purchaseOrderVoList) {
      if (purchaseOrderVo.getTotalAmount() != null) {
        todayTotalPurchaseAmount = todayTotalPurchaseAmount.add(purchaseOrderVo.getTotalAmount());
      }
    }
    orderDataVo.setTodayPurchaseOrderAmount(todayTotalPurchaseAmount);
    orderDataVo.setTodayPurchaseQuantityCount(purchaseOrderVoList.size());


    return orderDataVo;
  }

  @Override
  public OrderMonthDataVo statisticsMonthOrderData() {

    OrderMonthDataVo orderDataMonthVo=new OrderMonthDataVo();
    BigDecimal thisMonthTotalPurchaseAmount = BigDecimal.ZERO;
    List<PurchaseOrderVo> thisMonthPurchaseList=purchaseOrderMapper.thisMonthPurchaseOrder();

    for (PurchaseOrderVo purchaseOrderVo : thisMonthPurchaseList) {
      if (purchaseOrderVo.getTotalAmount() != null) {
        thisMonthTotalPurchaseAmount = thisMonthTotalPurchaseAmount.add(purchaseOrderVo.getTotalAmount());
      }
    }

    orderDataMonthVo.setThisMonthPurchaseOrderAmount(thisMonthTotalPurchaseAmount);
    orderDataMonthVo.setThisMonthPurchaseQuantityCount(thisMonthPurchaseList.size());


    BigDecimal thisMonthTotalSaleAmount = BigDecimal.ZERO;
    List<SaleOrderVo> thisMonthSaleList=saleOrderMapper.CheckThisMonthSaleOrderList();
    for (SaleOrderVo saleOrderVo : thisMonthSaleList) {
      if (saleOrderVo.getTotalAmount() != null) {
        thisMonthTotalSaleAmount = thisMonthTotalSaleAmount.add(saleOrderVo.getTotalAmount());
      }
    }

    orderDataMonthVo.setThisMonthSaleOrderAmount(thisMonthTotalSaleAmount);
    orderDataMonthVo.setThisMonthSaleQuantityCount(thisMonthSaleList.size());

    return orderDataMonthVo;

  }

  @Override
  public OrderMonthContrastVo orderMonthContrast() {

    OrderMonthContrastVo orderMonthContrastVo=new OrderMonthContrastVo();

    // 生成最近12个月的月份标签
    LocalDate now = LocalDate.now();
    List<String> months = new ArrayList<>();
    List<YearMonth> yearMonths = new ArrayList<>();

    // 倒序生成月份列表（从最早月份到当前月）
    for (int i = 11; i >= 0; i--) {
      YearMonth ym = YearMonth.from(now.minusMonths(i));
      yearMonths.add(ym);
      months.add(ym.getMonthValue() + "月");
    }

    // 初始化金额列表（12个0）
    List<BigDecimal> saleAmounts = ProportionUtils.initZeroList(12);
    List<BigDecimal> purchaseAmounts = ProportionUtils.initZeroList(12);

    // 创建月份索引映射表
    Map<YearMonth, Integer> indexMap = new HashMap<>();
    for (int i = 0; i < yearMonths.size(); i++) {
      indexMap.put(yearMonths.get(i), i);
    }

    // 处理销售数据
    List<Map<String, Object>> sales = saleOrderMapper.orderMonthContrastSaleOrder();
    ProportionUtils.fillAmounts(sales, saleAmounts, indexMap, "sale_amount");

    // 处理采购数据
    List<Map<String, Object>> purchases = purchaseOrderMapper.orderMonthContrastPurchaseOrder();
    ProportionUtils.fillAmounts(purchases, purchaseAmounts, indexMap, "purchase_amount");

    orderMonthContrastVo.setXAxisData(months);
    orderMonthContrastVo.setSaleAmounts(saleAmounts);
    orderMonthContrastVo.setPurchaseAmounts(purchaseAmounts);
    orderMonthContrastVo.setChartType("chart");  // 标识为按月统

    return orderMonthContrastVo;
  }

  @Override
  public OrderTodaysContrastVo orderTodaysContrast() {
    OrderTodaysContrastVo vo = new OrderTodaysContrastVo();

    // 生成最近30天的日期标签
    LocalDate now = LocalDate.now();
    List<String> xAxisData = new ArrayList<>();
    for (int i = 30; i > 0; i--) { // 生成从30天前到昨天的日期（共30天）
      LocalDate date = now.minusDays(i - 1); // i-1确保包含当天
      xAxisData.add(date.getMonthValue() + "/" + date.getDayOfMonth());
    }

    // 初始化金额列表
    List<BigDecimal> saleAmounts = new ArrayList<>(Collections.nCopies(30, BigDecimal.ZERO));
    List<BigDecimal> purchaseAmounts = new ArrayList<>(Collections.nCopies(30, BigDecimal.ZERO));

    // 获取销售数据
    List<Map<String, Object>> sales = saleOrderMapper.orderTodaysContrastSaleOrder();
    // 获取采购数据
    List<Map<String, Object>> purchases = purchaseOrderMapper.orderTodaysContrastPurchaseOrder();

    ProportionUtils.dayFillAmounts(purchases, purchaseAmounts, now, "purchase_amount"); // 采购用purchase_amount
    ProportionUtils.dayFillAmounts(sales, saleAmounts, now, "sale_amount"); // 销售用sale_amount

    vo.setXAxisData(xAxisData);
    vo.setSaleAmounts(saleAmounts);
    vo.setPurchaseAmounts(purchaseAmounts);
    vo.setChartType("chart");
    return vo;
  }

  @Override
  public OrderProportionVo orderProportion(OrderProportionDto orderProportionDto) {
    if (orderProportionDto.getMonth() == null || orderProportionDto.getMonth() < 1 || orderProportionDto.getMonth() > 12) {
      throw new IllegalArgumentException("Invalid month");
    }

    //默认年份为当前年
    Integer currentYear = LocalDate.now().getYear();

    //查询采购金额
    BigDecimal purchaseAmount = purchaseOrderMapper.getPurchaseAmountByMonth(currentYear, orderProportionDto.getMonth());

    //查询销售金额
    BigDecimal saleAmount = saleOrderMapper.getSaleAmountByMonth(currentYear, orderProportionDto.getMonth());

    //计算采销占比
    String proportion = ProportionUtils.calculateProportion(purchaseAmount, saleAmount);


    OrderProportionVo vo = new OrderProportionVo();
    vo.setPurchaseAmount(purchaseAmount);
    vo.setSaleAmount(saleAmount);
    vo.setProportion(proportion);
    return vo;
  }

  @Override
  public List<ProductStockProportionVo> productProductStockProportion() {

    //获取原始数据并计算总库存
    List<ProductStockDataVo> dataList = productStockMapper.getProductStockProportion();
    int totalStock = dataList.stream()
            .mapToInt(ProductStockDataVo::getStockNum)
            .sum();

    BigDecimal total = totalStock == 0 ? BigDecimal.ONE : new BigDecimal(totalStock);

    //按库存降序排序
    List<ProductStockDataVo> sortedList = dataList.stream()
            .sorted((d1, d2) -> Integer.compare(d2.getStockNum(), d1.getStockNum()))
            .collect(Collectors.toList());

    //分离前十和剩余商品
    List<ProductStockDataVo> top10 = sortedList.stream()
            .limit(10)
            .collect(Collectors.toList());

    List<ProductStockDataVo> others = sortedList.stream()
            .skip(10)
            .collect(Collectors.toList());

    List<ProductStockProportionVo> result = new ArrayList<>();

    //添加总库存条目
    ProductStockProportionVo totalVo = new ProductStockProportionVo();
    totalVo.setProductName("总库存");
    totalVo.setStock(String.valueOf(totalStock));
    totalVo.setProportion(""); // 总库存不显示百分比
    result.add(totalVo);

    //处理前十商品（计算百分比）
    top10.forEach(data -> {
      ProductStockProportionVo vo = new ProductStockProportionVo();
      vo.setProductName(data.getProductName());
      vo.setStock(String.valueOf(data.getStockNum()));

      // 计算百分比
      BigDecimal ratio = new BigDecimal(data.getStockNum())
              .divide(total, 4, RoundingMode.HALF_UP)
              .multiply(new BigDecimal(100));
      vo.setProportion(String.format("%.2f%%", ratio));

      result.add(vo);
    });

    //处理其他商品（合并并计算百分比）
    if (!others.isEmpty()) {
      int othersTotal = others.stream()
              .mapToInt(ProductStockDataVo::getStockNum)
              .sum();

      ProductStockProportionVo othersVo = new ProductStockProportionVo();
      othersVo.setProductName("其他商品");
      othersVo.setStock(String.valueOf(othersTotal));

      // 计算百分比
      BigDecimal othersRatio = new BigDecimal(othersTotal)
              .divide(total, 4, RoundingMode.HALF_UP)
              .multiply(new BigDecimal(100));
      othersVo.setProportion(String.format("%.2f%%", othersRatio));

      result.add(othersVo);
    }

    return result;

  }

  @Override
  public List<SaleSalerRankVo> saleSalerWeekRank() {
    // 计算本周一 00:00:00
    LocalDateTime now = LocalDateTime.now();
    LocalDateTime monday = now.with(DayOfWeek.MONDAY)
            .toLocalDate().atStartOfDay();
    LocalDateTime nextMonday = monday.plusDays(7);

// 格式化为数据库时间字符串
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    String startDate = monday.format(formatter);
    String endDate = nextMonday.format(formatter);
    List<SaleOrderVo> orders = saleOrderMapper.saleSalerWeekRank(startDate, endDate);

    if (CollectionUtil.isEmpty(orders)){
      return Collections.emptyList();
    }

    Set<String> salerIds = orders.stream()
            .filter(order -> order.getSalerId() != null)
            .map(SaleOrderVo::getSalerId)
            .collect(Collectors.toSet());

    Map<String, String> salerNameMap = sysUserMapper.selectUsersByIds(salerIds).stream()
            .collect(Collectors.toMap(SysUser::getId, SysUser::getName));

    Map<String, BigDecimal> salerAmountMap = new HashMap<>();
    for (SaleOrderVo order : orders) {
      if (order.getSalerId() == null || order.getTotalAmount() == null) continue;

      String salerName = salerNameMap.getOrDefault(order.getSalerId(), "未知销售员");

      // 获取订单金额（空值处理）
      BigDecimal amount = Optional.ofNullable(order.getTotalAmount()).orElse(BigDecimal.ZERO);

      salerAmountMap.merge(salerName, amount, BigDecimal::add);
    }

    return salerAmountMap.entrySet().stream()
            .map(entry -> new SaleSalerRankVo(
                    entry.getKey(),
                    Optional.ofNullable(entry.getValue()).orElse(BigDecimal.ZERO)
            ))
            .sorted((a, b) -> {
              BigDecimal aAmount = Optional.ofNullable(a.getSaleAmount()).orElse(BigDecimal.ZERO);
              BigDecimal bAmount = Optional.ofNullable(b.getSaleAmount()).orElse(BigDecimal.ZERO);
              return bAmount.compareTo(aAmount);
            })
            .collect(Collectors.toList());

  }

  @Override
  public List<SaleSalerRankVo> saleSalerMonthRank() {

    List<SaleOrderVo> orders = saleOrderMapper.saleSalerMonthRank();

    if (CollectionUtil.isEmpty(orders)) {
      return Collections.emptyList();
    }

    Set<String> salerIds = orders.stream()
            .filter(order -> order.getSalerId() != null)
            .map(SaleOrderVo::getSalerId)
            .collect(Collectors.toSet());

    Map<String, String> salerNameMap = sysUserMapper.selectUsersByIds(salerIds).stream()
            .collect(Collectors.toMap(SysUser::getId, SysUser::getName));

    Map<String, BigDecimal> salerAmountMap = new HashMap<>();
    for (SaleOrderVo order : orders) {
      if (order.getSalerId() == null || order.getTotalAmount() == null) continue;

      String salerName = salerNameMap.getOrDefault(order.getSalerId(), "未知销售员");

      // 获取订单金额（空值处理）
      BigDecimal amount = Optional.ofNullable(order.getTotalAmount()).orElse(BigDecimal.ZERO);

      salerAmountMap.merge(salerName, amount, BigDecimal::add);
    }

    return salerAmountMap.entrySet().stream()
            .map(entry -> new SaleSalerRankVo(
                    entry.getKey(),
                    Optional.ofNullable(entry.getValue()).orElse(BigDecimal.ZERO)
            ))
            .sorted((a, b) -> {
              BigDecimal aAmount = Optional.ofNullable(a.getSaleAmount()).orElse(BigDecimal.ZERO);
              BigDecimal bAmount = Optional.ofNullable(b.getSaleAmount()).orElse(BigDecimal.ZERO);
              return bAmount.compareTo(aAmount);
            })
            .collect(Collectors.toList());
  }

  @Override
  public SaleOrderGrossMarginVo saleOrderGrossMargin() {
    // 获取最近12个月的订单数据
    List<SaleOrderVo>  list=saleOrderMapper.latelyDecemberSaleOrderProfit();

    LocalDate currentDate = LocalDate.now();
    List<String> months = new ArrayList<>();
    List<YearMonth> yearMonths = new ArrayList<>();
    for (int i = 11; i >= 0; i--) {
      YearMonth yearMonth = YearMonth.from(currentDate.minusMonths(i));
      yearMonths.add(yearMonth);
      months.add(yearMonth.getMonthValue() + "月");
    }
    List<BigDecimal> profits = yearMonths.stream()
            .map(ym -> BigDecimal.ZERO)
            .collect(Collectors.toCollection(ArrayList::new));

    Map<YearMonth, Integer> monthIndexMap = new HashMap<>();
    for (int i = 0; i < yearMonths.size(); i++) {
      monthIndexMap.put(yearMonths.get(i), i);
    }

    // 计算每个月的毛利总和
    for (SaleOrderVo order : list) {
      // 转换时间到年月维度
      LocalDate orderDate = order.getCreateTime().toInstant()
              .atZone(ZoneId.systemDefault())
              .toLocalDate();
      YearMonth orderYearMonth = YearMonth.from(orderDate);

      // 找到对应的月份索引
      Integer index = monthIndexMap.get(orderYearMonth);
      if (index != null) {
        BigDecimal profit = order.getThisOrderProfit() != null ?
                order.getThisOrderProfit() : BigDecimal.ZERO;
        profits.set(index, profits.get(index).add(profit));
      }
    }

    for (SaleOrderVo saleOrderVo : list) {
      saleOrderVo.getThisOrderProfit();
    }

    SaleOrderGrossMarginVo result = new SaleOrderGrossMarginVo();
    result.setChartType("chart");
    result.setXAxisData(months);
    result.setSaleAmounts(profits);

    return result;
  }

  @Override
  public SaleOrderLastYearProfitVo saleOrderLastYearProfit() {

      //获取去年销售数据
      List<SaleOrderVo> orders = saleOrderMapper.lastYearSaleOrderProfit();

      LocalDate currentDate = LocalDate.now();
      Year lastYear = Year.from(currentDate.minusYears(1));
      List<String> months = new ArrayList<>();
      for (int month = 1; month <= 12; month++) {
        months.add(String.valueOf(month) + "月");
      }

      List<BigDecimal> profits = months.stream()
              .map(month -> BigDecimal.ZERO)
              .collect(Collectors.toCollection(ArrayList::new));

      Map<Integer, Integer> monthIndexMap = new HashMap<>();
      for (int i = 0; i < 12; i++) {
        monthIndexMap.put(i + 1, i);
      }

      for (SaleOrderVo order : orders) {
        // 转换时间到月份维度
        LocalDate orderDate = order.getCreateTime().toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDate();
        int orderMonth = orderDate.getMonthValue();

        // 找到对应的月份索引
        Integer index = monthIndexMap.get(orderMonth);
        if (index != null) {
          BigDecimal profit = order.getThisOrderProfit() != null ?
                  order.getThisOrderProfit() : BigDecimal.ZERO;
          profits.set(index, profits.get(index).add(profit));
        }
      }

      // 构建返回对象
      SaleOrderLastYearProfitVo result = new SaleOrderLastYearProfitVo();
      result.setChartType("chart");
      result.setXAxisData(months);
      result.setSaleAmounts(profits);

      return result;
  }

  @Override
  public SaleOrderCurrentYearAmountVo saleOrderCurrentYearAmount() {
    SaleOrderCurrentYearAmountVo vo = new SaleOrderCurrentYearAmountVo();

    // 获取数据：包含今年和去年（可能为0）
    List<Map<String, Object>> data = saleOrderMapper.getYearlyComparisonData();

    // 提取今年和去年的数据114.67.216.129
    BigDecimal currentYearAmount = BigDecimal.ZERO;
    BigDecimal currentYearCost = BigDecimal.ZERO;
    BigDecimal currentYearSales = BigDecimal.ZERO;
    BigDecimal lastYearAmount = BigDecimal.ZERO;
    BigDecimal lastYearCost = BigDecimal.ZERO;
    BigDecimal lastYearSales = BigDecimal.ZERO;

    for (Map<String, Object> item : data) {
      Long yearLong = (Long) item.get("year");
      if (yearLong != null) {
        Integer year = yearLong.intValue();
        // 使用 year
        BigDecimal amount = (BigDecimal) item.get("total_amount");
        BigDecimal sales = new BigDecimal(item.get("total_num").toString());
        BigDecimal cost = (BigDecimal) item.get("total_purchase_price");

        if (year == Year.now().getValue()) { // 今年
          currentYearAmount = amount != null ? amount : BigDecimal.ZERO;
          currentYearSales = sales;
          currentYearCost = cost != null ? cost : BigDecimal.ZERO;
        } else { // 去年
          lastYearAmount = amount != null ? amount : BigDecimal.ZERO;
          lastYearSales = sales;
          lastYearCost = cost != null ? cost : BigDecimal.ZERO;
        }
      }

    }

    // 填充基础数据
    vo.setCurrentYearAmount(currentYearAmount);
    vo.setSaleCount(currentYearSales.toPlainString());
    vo.setTotalPurchasePrice(currentYearCost);

    // 计算毛利率（百分比）
    if (currentYearAmount.compareTo(BigDecimal.ZERO) != 0) {
      BigDecimal grossMargin = currentYearAmount.subtract(currentYearCost)
              .divide(currentYearAmount, 4, RoundingMode.HALF_UP)
              .multiply(BigDecimal.valueOf(100));
      vo.setGrossMarginPercent(String.format("%.2f%%", grossMargin));
    } else {
      vo.setGrossMarginPercent("0.00%");
    }

    // 计算销售额同比增长率
    vo.setAmountGrowthPercent(ProportionUtils.calculateGrowth(currentYearAmount, lastYearAmount));

    // 计算销售数量同比增长率
    vo.setSaleCountGrowthPercent(ProportionUtils.calculateGrowth(currentYearSales, lastYearSales));

    // 计算成本同比增长率
    vo.setPurchasePriceGrowthPercent(ProportionUtils.calculateGrowth(currentYearCost, lastYearCost));

    // 计算毛利率同比增长率（需要计算去年毛利率）
    BigDecimal lastYearGrossMargin = BigDecimal.ZERO;
    if (lastYearAmount.compareTo(BigDecimal.ZERO) != 0) {
      lastYearGrossMargin = lastYearAmount.subtract(lastYearCost)
              .divide(lastYearAmount, 4, RoundingMode.HALF_UP)
              .multiply(BigDecimal.valueOf(100));
    }
    BigDecimal currentYearGrossMargin = new BigDecimal(vo.getGrossMarginPercent().replace("%", ""));
    vo.setGrossMarginGrowthPercent(ProportionUtils.calculateGrowth(currentYearGrossMargin, lastYearGrossMargin));

    return vo;
  }


}
