package cn.van.business.util;

import cn.van.business.enums.ValidCodeConverter;
import cn.van.business.model.jd.OrderRow;
import cn.van.business.repository.OrderRowRepository;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static cn.van.business.util.WXUtil.*;


/**
 * @author Leo
 * @version 1.0
 * @create 2024/11/29 11:43
 * @description：
 */
@Service
public class OrderUtil {

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private OrderRowRepository orderRowRepository;
    @Autowired
    private WXUtil wxUtil;

    //标记唯一订单行：订单+sku维度的唯一标识
    private static final String ORDER_ROW_KEY = "jd:order:row:";

    /**
     * 手动调用 将订单发送到微信
     */
    @Async("threadPoolTaskExecutor")
    public void orderToWx(OrderRow orderRow, Boolean isAutoFlush) {
        // 获取订单当前状态
        Integer newValidCode = orderRow.getValidCode();
        String oldValidCode = redisTemplate.opsForValue().get(ORDER_ROW_KEY + orderRow.getId());

        // 检查Redis中是否有旧的状态码，没有的话赋予默认值
        Integer lastValidCode = oldValidCode != null ? Integer.parseInt(oldValidCode) : -100;

        // 这里使用了逻辑非(!)操作符来简化条件判断
        if (!isAutoFlush || !lastValidCode.equals(newValidCode)) {
            // 当 isAutoFlush 为 false 或状态确实有变化时，进行消息发送
            String content = getFormattedOrderInfo(orderRow, lastValidCode);
            String wxId = getWxidFromJdid(orderRow.getUnionId().toString());
            if (Util.isNotEmpty(wxId)) {
                wxUtil.sendTextMessage(wxId, content, 1, wxId, true);
                // 加一个简短的今日订单统计
                int[] param = {-1};
                List<WXUtil.SuperAdmin> superAdmins = getSuperAdmins(wxId);
                List<Long> unionIds = new ArrayList<>();
                for (WXUtil.SuperAdmin superAdmin : superAdmins) {
                    String unionId = superAdmin.getUnionId();
                    unionIds.add(Long.valueOf(unionId));
                }
                List<OrderRow> orderRows = orderRowRepository.findByValidCodeNotInAndUnionIdIn(param, unionIds);

                List<OrderRow> todayOrders = filterOrdersByDate(orderRows, 0);
                // 分割统计每个京粉今天下单多少个订单，避免一天一个京粉下单太多
                HashMap<String, List<OrderRow>> stringListHashMap = new HashMap<>();
                List<OrderRow> cachedOrders = new ArrayList<>();
                for (OrderRow todayOrder : todayOrders) {
                    String unionId = todayOrder.getUnionId().toString();
                    if (stringListHashMap.containsKey(unionId)) {
                        cachedOrders = stringListHashMap.get(unionId);
                    } else {
                        cachedOrders = new ArrayList<>();
                    }
                    cachedOrders.add(todayOrder);
                    stringListHashMap.put(unionId, cachedOrders);

                }
                // 只统计今天下单的京粉，因为有的京粉休息是不下单的
                StringBuilder resultContent = new StringBuilder();
                for (Map.Entry<String, List<OrderRow>> entry : stringListHashMap.entrySet()) {
                    String unionId = entry.getKey();
                    List<OrderRow> orderRows2 = entry.getValue();
                    OrderStats stats = calculateStats(orderRows2);
                    resultContent.append(buildStatsContent("京粉 : " + getRemarkFromJdid(unionId) , stats));
                }

                OrderStats orderStats = calculateStats(todayOrders);
                wxUtil.sendTextMessage(wxId, buildStatsContent("今日总统计 : ", orderStats) + " \n 详 : \n ━━━━━━━━━━━━\n" + resultContent, 1, wxId, true);

            }
        }

        // 更新 Redis 状态值
        redisTemplate.opsForValue().set(ORDER_ROW_KEY + orderRow.getId(), String.valueOf(orderRow.getValidCode()));
        //logger.info("订单状态：{}  订单号：{}  sku：{}", orderRow.getValidCode(), orderRow.getOrderId(), orderRow.getSkuName());

    }

    /**
     * 手动调用 将订单发送到微信 批量
     */
    @Async("threadPoolTaskExecutor")
    public void orderToWxBatch(List<OrderRow> orderRowList) {
        if (!orderRowList.isEmpty()) {
            int i = 1;
            String wxId = getWxidFromJdid(orderRowList.get(0).getUnionId().toString());
            StringBuilder content = new StringBuilder();
            content.append("批量订单：\n\r ").append(" 共 ").append(orderRowList.size()).append("单 \r");
            List<OrderRow> filterList = orderRowList.stream().filter(orderRow -> orderRow.getValidCode() != 2
                    && orderRow.getValidCode() != 3).toList();
            content.append("移除 拆单或者取消 的订单, 共 ").append(filterList.size()).append("单: \n\r");
            for (OrderRow orderRow : filterList) {
                content.append("\r\n");
                content.append(i++).append("、");
                content.append(getFormattedOrderInfoBatch(orderRow));

            }
            if (Util.isNotEmpty(wxId)) {
                wxUtil.sendTextMessage(wxId, content.toString(), 1, wxId, false);
            }

        }

    }


    /**
     * 将数据库订单转化成微信所需要文本
     */
    public String getFormattedOrderInfo(OrderRow orderRow, Integer oldValidCode) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        ValidCodeConverter converter = new ValidCodeConverter();
        Long unionId = orderRow.getUnionId();
        String remarkFromJdid = getRemarkFromJdid(String.valueOf(unionId));
        StringBuilder orderInfo = new StringBuilder()
                .append(" ").append(getEmjoy(orderRow.getValidCode())).append(" ")
                .append(converter.getCodeDescription(orderRow.getValidCode())).append("\r");

        //if (oldValidCode != -100 && !oldValidCode.equals(orderRow.getValidCode())) {
        //    orderInfo.insert(0, "从 ：" + getEmjoy(oldValidCode) + " "
        //        + converter.getCodeDescription(oldValidCode) + "\r变成  "
        //        + getEmjoy(orderRow.getValidCode()) + " "
        //        + converter.getCodeDescription(orderRow.getValidCode()) + "\r\n");
        //}

        orderInfo
                //+ "订单+sku：" + orderRow.getId() + "\r"
                .append("京粉：").append(remarkFromJdid).append("\r")
                .append("订单：").append(orderRow.getOrderId()).append("  (")
                .append(orderRow.getPlus() == 1 ? "plus" : "非plus").append(")\r")
                .append("名称：").append(orderRow.getSkuName()).append("\r").append("\r")
                //+ "商品单价：" + orderRow.getPrice() + "\r"
                //+ "商品数量：" + orderRow.getSkuNum() + "\r"
                //+ "商品总价：" + (orderRow.getPrice() * orderRow.getSkuNum()) + "\r"
                .append("计佣金额：").append(orderRow.getEstimateCosPrice()).append("\r")
                //+ "金额：" + orderRow.getActualCosPrice() + "\r"
                .append("比例：").append(orderRow.getCommissionRate()).append("\r")
                .append("[Packet] 佣金：").append(orderRow.getEstimateFee()).append("\r")
                .append("下单：").append(formatter.format(orderRow.getOrderTime())).append("\r")
                .append("完成：").append(orderRow.getFinishTime() != null
                        ? formatter.format(orderRow.getFinishTime())
                        : "未完成");

        return orderInfo.toString();
    }


    public String getEmjoy(Integer status) {
        return switch (status) {
            //[爱心]已付款
            case 16 -> "[爱心]";
            //[Wow] 待付款
            case 15 -> "[Wow]";
            //[心碎]已取消
            case 2, 3 -> "[心碎]";
            //[亲亲] 已完成
            case 17 -> "[亲亲]";
            //[Broken] 违规
            case 27, 28 -> "[Broken]";
            default -> "";
        };
    }


    /**
     * 将数据库订单转化成微信所需要文本 简洁版
     */
    public String getFormattedOrderInfoBatch(OrderRow orderRow) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        ValidCodeConverter converter = new ValidCodeConverter();
        Long unionId = orderRow.getUnionId();
        String remarkFromJdid = getRemarkFromJdid(String.valueOf(unionId));

        //+ "订单+sku：" + orderRow.getId() + "\r"
        //+ "商品单价：" + orderRow.getPrice() + "\r"
        //+ "商品数量：" + orderRow.getSkuNum() + "\r"
        //+ "商品总价：" + (orderRow.getPrice() * orderRow.getSkuNum()) + "\r"
        //+ "计佣金额：" + orderRow.getEstimateCosPrice() + "\r"
        //+ "金额：" + orderRow.getActualCosPrice() + "\r"
        //+ "比例：" + orderRow.getCommissionRate() + "\r"
        //if (oldValidCode != -100) {
        //    if (!oldValidCode.equals(orderRow.getValidCode()))
        //        orderInfo = "从 ：" + (converter.getCodeDescription(oldValidCode)) + "\r变成  " +
        //                (converter.getCodeDescription(orderRow.getValidCode())) + "\r\n" + orderInfo;
        //}


        return "订单：" + orderRow.getOrderId() + "  (" + (orderRow.getPlus() == 1 ? "plus" : "非plus") + ")\r"
               +"走的京粉："+ remarkFromJdid + "\r"

                +"状态：" + (converter.getCodeDescription(orderRow.getValidCode())) + "\r"

                + "标题：" + orderRow.getSkuName() + "\r\n"+ "\r\n"
                //+ "商品单价：" + orderRow.getPrice() + "\r"
                //+ "商品数量：" + orderRow.getSkuNum() + "\r"
                //+ "商品总价：" + (orderRow.getPrice() * orderRow.getSkuNum()) + "\r"
                //+ "计佣金额：" + orderRow.getEstimateCosPrice() + "\r"

                //+ "金额：" + orderRow.getActualCosPrice() + "\r"
                //+ "比例：" + orderRow.getCommissionRate() + "\r"
                + "佣金：" + orderRow.getEstimateFee() + "\r\n"

                + "下单：" + formatter.format(orderRow.getOrderTime()) + "\r"
                + "完成：" + (orderRow.getFinishTime() != null ? formatter.format(orderRow.getFinishTime()) : "未完成") + "\r";
    }

    /**
     * JDUtil拷贝的方法，避免循环注入
     * */

    private  List<OrderRow> filterOrdersByDate(List<OrderRow> orderRows, int daysBack) {
        LocalDate now = LocalDate.now();

        return orderRows.stream().filter(order -> {
            // 将 Date 转换为 LocalDate
            LocalDate orderDate = order.getOrderTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

            // 计算是否在给定的天数内
            return !orderDate.isBefore(now.minusDays(daysBack)) && !orderDate.isAfter(now);
        }).collect(Collectors.toList());
    }
    private  OrderStats calculateStats(List<OrderRow> orders) {
        long paid = orders.stream().filter(o -> o.getValidCode() == 16).count();
        long pending = orders.stream().filter(o -> o.getValidCode() == 15).count();
        long canceled = orders.stream().filter(o -> o.getValidCode() != 16 && o.getValidCode() != 17).count();
        long completed = orders.stream().filter(o -> o.getValidCode() == 17).count();

        return new OrderStats(orders.size(), orders.size() - canceled, paid, orders.stream().filter(o -> o.getValidCode() == 16).mapToDouble(OrderRow::getEstimateFee).sum(), pending, orders.stream().filter(o -> o.getValidCode() == 15).mapToDouble(OrderRow::getEstimateFee).sum(), canceled, completed, orders.stream().filter(o -> o.getValidCode() == 17).mapToDouble(OrderRow::getEstimateFee).sum(), getStreamForWeiGui(orders).count(), getStreamForWeiGui(orders).mapToDouble(o -> o.getEstimateCosPrice() * o.getCommissionRate() * 0.01).sum());
    }
    private String buildStatsContent(String title, OrderStats stats) {
        StringBuilder content = new StringBuilder();
        content//[爱心][Wow][Packet][Party][Broken][心碎][亲亲][色]
                .append(title).append("    \n").append("[爱心] 订单总数：").append(stats.getTotalOrders()).append("\n")  // [文件]
                .append("[Party] 有效订单：").append(stats.getValidOrders()).append("\n")  // [OK]
                .append("[心碎]已取消：").append(stats.getCanceledOrders()).append("\n")  // [禁止]
                .append("[爱心]已付款：").append(stats.getPaidOrders()).append("\n")  // [钱袋]
                .append("[Packet] 已付款佣金：").append(String.format("%.2f", stats.getPaidCommission())).append("\n")  // [钞票]
                .append("[Wow] 待付款：").append(stats.getPendingOrders()).append("\n")  // [时钟]
                .append("[Packet] 待付款佣金：").append(String.format("%.2f", stats.getPendingCommission())).append("\n").append("━━━━━━━━━━━━\n");
        return content.toString();
    }
    private Stream<OrderRow> getStreamForWeiGui(List<OrderRow> todayOrders) {
        return todayOrders.stream().filter(orderRow -> orderRow.getValidCode() == 13 || orderRow.getValidCode() == 25 || orderRow.getValidCode() == 26 || orderRow.getValidCode() == 27 || orderRow.getValidCode() == 28 || orderRow.getValidCode() == 29);
    }

    // 统计指标DTO
    @Getter
    @AllArgsConstructor
    static
    class OrderStats {
        private long totalOrders;          // 总订单数
        private long validOrders;          // 有效订单数（不含取消）
        private long paidOrders;           // 已付款订单
        private double paidCommission;     // 已付款佣金
        private long pendingOrders;        // 待付款订单
        private double pendingCommission;  // 待付款佣金
        private long canceledOrders;       // 已取消订单
        private long completedOrders;      // 已完成订单
        private double completedCommission;// 已完成佣金
        private long violations;           // 违规订单数
        private double violationCommission;// 违规佣金
    }
}
