package com.ruoyi.web.controller.jarvis;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.RequestParam;

import com.ruoyi.jarvis.domain.SuperAdmin;
import com.ruoyi.jarvis.service.SuperAdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.jarvis.domain.JDOrder;
import com.ruoyi.jarvis.domain.OrderRows;
import com.ruoyi.jarvis.domain.dto.LinkedJdOrderBrief;
import com.ruoyi.jarvis.service.IGoodsInfoService;
import com.ruoyi.jarvis.service.IJDOrderService;
import com.ruoyi.jarvis.service.IOrderRowsService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.jarvis.enums.ValidCodeConverter;

/**
 * 京粉订单Controller
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/jarvis/orderrows")
public class OrderRowsController extends BaseController
{
    @Autowired
    private IOrderRowsService orderRowsService;

    @Autowired
    private IGoodsInfoService goodsInfoService;

    @Autowired
    private IJDOrderService jdOrderService;

    @Autowired
    private SuperAdminService superAdminService;

    /**
     * 查询京粉订单列表
     */
    @GetMapping("/list")
    public TableDataInfo list(OrderRows orderRows, @RequestParam(required = false) String orderBy, @RequestParam(required = false) String orderSort)
    {
        // 处理排序参数：将 orderBy 和 orderSort 转换为 params 中的 orderBy 和 isAsc
        if (orderBy != null && !orderBy.isEmpty()) {
            if (orderRows.getParams() == null) {
                orderRows.setParams(new HashMap<>());
            }
            Map<String, Object> params = orderRows.getParams();
            // 将字段名转换为数据库列名
            if ("estimateCosPrice".equals(orderBy)) {
                params.put("orderBy", "estimate_cos_price");
            } else {
                params.put("orderBy", orderBy);
            }
            // 将 orderSort (asc/desc) 转换为 isAsc (asc/desc)
            if ("asc".equals(orderSort)) {
                params.put("isAsc", "asc");
            } else if ("desc".equals(orderSort)) {
                params.put("isAsc", "desc");
            }
        }
        
        startPage();
        List<OrderRows> list = orderRowsService.selectOrderRowsList(orderRows);
        enrichLinkedJdOrders(list);
        TableDataInfo dataTable = getDataTable(list);
        Date beginTime = getDateFromParams(orderRows.getParams(), "beginTime");
        Date endTime = getDateFromParams(orderRows.getParams(), "endTime");
        // 与列表同数据源，不排除 isCount=0，保证总订单数与分页 total 一致
        dataTable.setStatistics(buildStatistics(orderRows, beginTime, endTime, true));
        return dataTable;
    }

    private static Date getDateFromParams(Map<String, Object> params, String key) {
        if (params == null) return null;
        Object v = params.get(key);
        if (v == null) return null;
        if (v instanceof Date) return (Date) v;
        if (v instanceof String) {
            String s = ((String) v).trim();
            if (s.isEmpty()) return null;
            try {
                return new SimpleDateFormat("yyyy-MM-dd").parse(s);
            } catch (Exception e) {
                return null;
            }
        }
        return null;
    }

     /**
     * 导出京粉订单列表
     */
    @Log(title = "京粉订单", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, OrderRows orderRows) throws IOException
    {
        String fileName = "京粉订单数据";

        List<OrderRows> list = orderRowsService.selectOrderRowsList(orderRows);
        if (!list.isEmpty()){
            Long unionId = list.get(0).getUnionId();
            SuperAdmin superAdmin = superAdminService.selectSuperAdminByUnionId(unionId);
            if (superAdmin != null && superAdmin.getName() != null) {
                String name = superAdmin.getName();
                String unionIdStr = String.valueOf(superAdmin.getUnionId());
                fileName = name + "-" + unionIdStr + "-订单";
            }
        }

        // 设置响应头，指定文件名
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String encodedFileName = java.net.URLEncoder.encode(fileName + ".xlsx", "UTF-8");
        response.setHeader("Content-Disposition", "attachment; filename=" + encodedFileName);
        // 添加download-filename响应头，以支持前端工具类
        response.setHeader("download-filename", encodedFileName);

        ExcelUtil<OrderRows> util = new ExcelUtil<OrderRows>(OrderRows.class);
        util.exportExcel(response, list, fileName);
    }


    /**
     * 获取京粉订单详细信息
     */
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") String id)
    {
        OrderRows orderRows = orderRowsService.selectOrderRowsById(id);
        if (orderRows != null && orderRows.getGoodsInfoId() != null) {
            orderRows.setGoodsInfo(goodsInfoService.selectGoodsInfoById(orderRows.getGoodsInfoId()));
        }
        if (orderRows != null) {
            enrichLinkedJdOrders(Collections.singletonList(orderRows));
        }
        return success(orderRows);
    }

    /**
     * 新增京粉订单
     */
    @Log(title = "京粉订单", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody OrderRows orderRows)
    {
        return toAjax(orderRowsService.insertOrderRows(orderRows));
    }

    /**
     * 修改京粉订单
     */
    @Log(title = "京粉订单", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody OrderRows orderRows)
    {
        return toAjax(orderRowsService.updateOrderRows(orderRows));
    }

    /**
     * 删除京粉订单
     */
    @Log(title = "京粉订单", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable String[] ids)
    {
        return toAjax(orderRowsService.deleteOrderRowsByIds(ids));
    }

    /**
     * 获取订单有效性下拉选项
     */
    @GetMapping("/select/validCode")
    public AjaxResult getValidCodeOptions() {
        List<Map<String, Object>> options = ValidCodeConverter.getAllValidCodeOptions();
        return AjaxResult.success(options);
    }
    /**
     * 根据联盟ID或日期范围统计订单数据，按validCode分组（独立接口，与列表同条件时建议用 list 返回的 statistics）
     */
    @GetMapping("/statistics")
    public AjaxResult getStatistics(OrderRows orderRows, Date beginTime, Date endTime) {
        return AjaxResult.success(buildStatistics(orderRows, beginTime, endTime, false));
    }

    /**
     * 构建统计数据。
     * <p>汇总口径：{@code totalCommission} 为预估佣金合计，排除取消单(validCode=3)；{@code totalActualFee} 为实际佣金，仅统计已完成(validCode=17)；
     * {@code estimatePaidPending} 为已付款待收货(validCode=16)的预估佣金，与分组 {@code paid} 一致。</p>
     * @param forList true=与列表同数据源（不排除 isCount=0），保证总订单数与分页一致；false=独立统计（排除 isCount=0）
     */
    private Map<String, Object> buildStatistics(OrderRows orderRows, Date beginTime, Date endTime, boolean forList) {
        Map<String, Object> result = new HashMap<>();
        List<Long> excludeUnionIds = new ArrayList<>();
        if (!forList) {
            List<SuperAdmin> superAdminList = superAdminService.selectSuperAdminList(null);
            for (SuperAdmin superAdmin : superAdminList) {
                if (superAdmin.getIsCount() != null && superAdmin.getIsCount() == 0 && superAdmin.getUnionId() != null) {
                    try {
                        excludeUnionIds.add(Long.parseLong(superAdmin.getUnionId()));
                    } catch (NumberFormatException e) {
                    }
                }
            }
        }
        List<OrderRows> filteredList = orderRowsService.selectOrderRowsListWithFilter(orderRows, beginTime, endTime, excludeUnionIds);

        Map<String, List<String>> groups = new HashMap<>();
        groups.put("cancel", Arrays.asList("3"));
        groups.put("invalid", ValidCodeConverter.toCodeStrings(ValidCodeConverter.INVALID_CODES));
        groups.put("pending", Arrays.asList("15"));
        groups.put("paid", Arrays.asList("16"));
        groups.put("finished", Arrays.asList("17"));
        groups.put("deposit", Arrays.asList("24"));
        groups.put("illegal", ValidCodeConverter.toCodeStrings(ValidCodeConverter.ILLEGAL_CODES));

        Map<String, Map<String, Object>> groupStats = new HashMap<>();
        groupStats.put("cancel", createGroupStat("取消", "cancel"));
        groupStats.put("invalid", createGroupStat("无效", "invalid"));
        groupStats.put("pending", createGroupStat("待付款", "pending"));
        groupStats.put("paid", createGroupStat("已付款（待结算）", "paid"));
        groupStats.put("finished", createGroupStat("已完成", "finished"));
        groupStats.put("deposit", createGroupStat("已付定金", "deposit"));
        groupStats.put("illegal", createGroupStat("违规", "illegal"));

        int totalOrders = 0;
        double totalCosPrice = 0;
        double totalCommission = 0;
        double totalActualFee = 0;
        long totalSkuNum = 0;
        long violationOrders = 0;
        double violationCommission = 0.0;

        for (OrderRows row : filteredList) {
            totalOrders++;
            if (row.getEstimateCosPrice() != null) {
                totalCosPrice += row.getEstimateCosPrice();
            }
            if (row.getSkuNum() != null) {
                totalSkuNum += row.getSkuNum();
            }

            String validCode = row.getValidCode() != null ? String.valueOf(row.getValidCode()) : null;
            boolean isCancel = "3".equals(validCode);
            boolean isIllegal = ValidCodeConverter.isIllegal(row.getValidCode());

            double commissionAmount = 0.0;
            double actualFeeAmount = 0.0;

            if (isIllegal) {
                if (row.getEstimateCosPrice() != null && row.getCommissionRate() != null) {
                    commissionAmount = row.getEstimateCosPrice() * row.getCommissionRate() * 0.01;
                    actualFeeAmount = commissionAmount;
                } else if (row.getEstimateFee() != null) {
                    commissionAmount = row.getEstimateFee();
                    actualFeeAmount = commissionAmount;
                }
            } else if (isCancel) {
                if (row.getActualFee() != null && row.getActualFee() > 0) {
                    actualFeeAmount = row.getActualFee();
                    commissionAmount = row.getEstimateFee() != null ? row.getEstimateFee() : 0;
                } else if (row.getEstimateCosPrice() != null && row.getCommissionRate() != null) {
                    commissionAmount = row.getEstimateCosPrice() * row.getCommissionRate() * 0.01;
                    actualFeeAmount = commissionAmount;
                } else {
                    commissionAmount = row.getEstimateFee() != null ? row.getEstimateFee() : 0;
                    actualFeeAmount = row.getActualFee() != null ? row.getActualFee() : 0;
                }
            } else {
                commissionAmount = row.getEstimateFee() != null ? row.getEstimateFee() : 0;
                actualFeeAmount = row.getActualFee() != null ? row.getActualFee() : 0;
            }

            // 顶部「预估佣金」汇总：排除取消单（validCode=3），其余状态累加单条 commissionAmount
            if (!"3".equals(validCode)) {
                totalCommission += commissionAmount;
            }
            // 顶部「实际佣金」汇总：仅已完成（validCode=17），与联盟「已结算」口径一致
            if ("17".equals(validCode)) {
                totalActualFee += actualFeeAmount;
            }

            if (validCode != null) {
                for (Map.Entry<String, List<String>> group : groups.entrySet()) {
                    if (group.getValue().contains(validCode)) {
                        Map<String, Object> stat = groupStats.get(group.getKey());
                        stat.put("count", (Integer) stat.get("count") + 1);
                        stat.put("commission", (Double) stat.get("commission") + commissionAmount);
                        stat.put("actualFee", (Double) stat.get("actualFee") + actualFeeAmount);
                        if (row.getSkuNum() != null) {
                            stat.put("skuNum", (Long) stat.get("skuNum") + row.getSkuNum());
                        }
                        if ("illegal".equals(group.getKey())) {
                            violationOrders++;
                            violationCommission += commissionAmount;
                        }
                        break;
                    }
                }
            }
        }

        result.put("totalOrders", totalOrders);
        result.put("totalCosPrice", totalCosPrice);
        result.put("totalCommission", totalCommission);
        result.put("totalActualFee", totalActualFee);
        // 已付款待结算：与分组 paid 的预估佣金口径一致，便于独立展示卡片
        result.put("estimatePaidPending", (Double) groupStats.get("paid").get("commission"));
        result.put("totalSkuNum", totalSkuNum);
        result.put("violationOrders", violationOrders);
        result.put("violationCommission", violationCommission);
        result.put("groupStats", groupStats);
        return result;
    }


    /**
     * 创建分组统计对象
     */
    private Map<String, Object> createGroupStat(String label, String value) {
        Map<String, Object> stat = new HashMap<>();
        stat.put("label", label);
        stat.put("value", value);
        stat.put("count", 0);
        stat.put("commission", 0.0);
        stat.put("actualFee", 0.0);
        stat.put("skuNum", 0L);
        return stat;
    }

    private void enrichLinkedJdOrders(List<OrderRows> rows) {
        if (rows == null || rows.isEmpty()) {
            return;
        }
        List<String> orderIds = new ArrayList<>();
        for (OrderRows row : rows) {
            if (row.getOrderId() != null) {
                String oid = String.valueOf(row.getOrderId());
                if (!orderIds.contains(oid)) {
                    orderIds.add(oid);
                }
            }
        }
        if (orderIds.isEmpty()) {
            return;
        }
        List<JDOrder> jdOrders = jdOrderService.selectLatestJDOrdersByOrderIds(orderIds);
        if (jdOrders == null || jdOrders.isEmpty()) {
            return;
        }
        Map<String, JDOrder> jdOrderMap = new HashMap<>();
        for (JDOrder jdOrder : jdOrders) {
            if (jdOrder != null && jdOrder.getOrderId() != null) {
                jdOrderMap.put(jdOrder.getOrderId(), jdOrder);
            }
        }
        for (OrderRows row : rows) {
            if (row.getOrderId() == null) {
                continue;
            }
            JDOrder jdOrder = jdOrderMap.get(String.valueOf(row.getOrderId()));
            if (jdOrder != null) {
                row.setLinkedJdOrder(toLinkedJdOrderBrief(jdOrder));
            }
        }
    }

    private LinkedJdOrderBrief toLinkedJdOrderBrief(JDOrder jdOrder) {
        LinkedJdOrderBrief brief = new LinkedJdOrderBrief();
        brief.setId(jdOrder.getId());
        brief.setRemark(jdOrder.getRemark());
        brief.setOrderId(jdOrder.getOrderId());
        brief.setBuyer(jdOrder.getBuyer());
        brief.setModelNumber(jdOrder.getModelNumber());
        brief.setModelShop(jdOrder.getModelShop());
        brief.setPaymentAmount(jdOrder.getPaymentAmount());
        brief.setRebateAmount(jdOrder.getRebateAmount());
        brief.setAddress(jdOrder.getAddress());
        brief.setStatus(jdOrder.getStatus());
        brief.setOrderTime(jdOrder.getOrderTime());
        return brief;
    }

}
