package org.dromara.erp.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.utils.IdGeneratorUtil;
import org.dromara.erp.domain.ErpOrder;
import org.dromara.erp.domain.query.ErpOrderQuery;
import org.dromara.erp.domain.vo.ErpOrderVo;
import org.dromara.erp.enums.ErpAuditResult;
import org.dromara.erp.enums.ErpOrderStatus;
import org.dromara.erp.mapper.ErpOrderMapper;
import org.dromara.erp.service.IErpOrderService;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 订单 Service 业务层处理
 * @Author: Antigravity
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class ErpOrderServiceImpl implements IErpOrderService {

    private final ErpOrderMapper baseMapper;
    private final org.dromara.erp.mapper.ErpOrderDetailMapper erpOrderDetailMapper;
    private final org.dromara.erp.mapper.ErpOrderAuditMapper erpOrderAuditMapper;
    private final org.dromara.erp.mapper.ErpSaleOrderMasterMapper erpSaleOrderMasterMapper;

    @Override
    public TableDataInfo<ErpOrderVo> queryPageList(ErpOrderQuery query, PageQuery pageQuery) {
        LambdaQueryWrapper<ErpOrder> lqw = buildQueryWrapper(query);
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<ErpOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);

        List<ErpOrderVo> list = result.getRecords();
        if (ObjectUtil.isNotEmpty(list)) {
            fillOrderDetails(list);
        }
        return TableDataInfo.build(result);
    }

    @Override
    public List<ErpOrderVo> queryList(ErpOrderQuery query) {
        LambdaQueryWrapper<ErpOrder> lqw = buildQueryWrapper(query);
        List<ErpOrderVo> list = baseMapper.selectVoList(lqw);
        if (ObjectUtil.isNotEmpty(list)) {
            fillOrderDetails(list);
        }
        return list;
    }

    private LambdaQueryWrapper<ErpOrder> buildQueryWrapper(ErpOrderQuery query) {
        LambdaQueryWrapper<ErpOrder> lqw = Wrappers.lambdaQuery();
        lqw.eq(ObjectUtil.isNotEmpty(query.getCode()), ErpOrder::getCode, query.getCode());
        lqw.eq(ObjectUtil.isNotEmpty(query.getPlacer()), ErpOrder::getPlacer, query.getPlacer());
        lqw.eq(ObjectUtil.isNotEmpty(query.getStatus()), ErpOrder::getStatus, query.getStatus());
        lqw.orderByDesc(ErpOrder::getCreateTime);
        return lqw;
    }

    private void fillOrderDetails(List<ErpOrderVo> list) {
        List<String> orderIds = list.stream().map(ErpOrderVo::getRowId).toList();
        LambdaQueryWrapper<org.dromara.erp.domain.ErpOrderDetail> detailLqw = Wrappers.lambdaQuery();
        detailLqw.in(org.dromara.erp.domain.ErpOrderDetail::getOrderId, orderIds);
        List<org.dromara.erp.domain.vo.ErpOrderDetailVo> allDetails = erpOrderDetailMapper.selectVoList(detailLqw);

        for (ErpOrderVo vo : list) {
            List<org.dromara.erp.domain.vo.ErpOrderDetailVo> details = allDetails.stream()
                    .filter(d -> vo.getRowId().equals(d.getOrderId()))
                    .toList();
            vo.setDetails(details);
            vo.setTotalCount(details.stream().mapToInt(d -> d.getCount() == null ? 0 : d.getCount()).sum());
        }
    }

    @Override
    public ErpOrderVo queryById(String rowId) {
        ErpOrderVo vo = baseMapper.selectVoById(rowId);
        if (vo != null) {
            LambdaQueryWrapper<org.dromara.erp.domain.ErpOrderDetail> detailLqw = Wrappers.lambdaQuery();
            detailLqw.eq(org.dromara.erp.domain.ErpOrderDetail::getOrderId, rowId);
            List<org.dromara.erp.domain.vo.ErpOrderDetailVo> details = erpOrderDetailMapper.selectVoList(detailLqw);
            vo.setDetails(details);
            vo.setTotalCount(details.stream().mapToInt(d -> d.getCount() == null ? 0 : d.getCount()).sum());
        }
        return vo;
    }

    @Override
    public Map<Integer, Long> countByStatus() {
        LambdaQueryWrapper<ErpOrder> lqw = Wrappers.lambdaQuery();
        lqw.select(ErpOrder::getStatus);
        lqw.ne(ErpOrder::getStatus, ErpOrderStatus.CANCELLED.getCode());
        lqw.ne(ErpOrder::getStatus, ErpOrderStatus.REJECTED.getCode());
        List<ErpOrder> list = baseMapper.selectList(lqw);
        return list.stream()
                .collect(Collectors.groupingBy(ErpOrder::getStatus, Collectors.counting()));
    }

    @Override
    @com.baomidou.dynamic.datasource.annotation.DSTransactional
    public String insert(org.dromara.erp.domain.bo.ErpOrderBo bo) {
        ErpOrder entity = MapstructUtils.convert(bo, ErpOrder.class);
        if (ObjectUtil.isEmpty(entity.getRowId())) {
            entity.setRowId(IdUtil.fastUUID());
        }
        if (ObjectUtil.isEmpty(entity.getCode())) {
            entity.setCode(IdGeneratorUtil.nextIdWithPrefix("ORD"));
        }
        if (entity.getPlacer() == null) {
            try {
                log.info("[调试] 开始自动填充 Placer...");
                log.info("[调试] 当前是否登录: {}", org.dromara.common.satoken.utils.LoginHelper.isLogin());
                log.info("[调试] 当前 Token: {}", cn.dev33.satoken.stp.StpUtil.getTokenValue());

                Long userId = org.dromara.common.satoken.utils.LoginHelper.getUserId();
                log.info("[调试] 获取到的用户 ID: {}", userId);

                if (userId != null) {
                    entity.setPlacer(userId);
                    log.info("[调试] 自动填充 Placer 成功: {}", userId);
                } else {
                    log.warn("[调试] 获取到的用户 ID 为空，请检查 Token 是否有效或 Security 上下文是否正确传递");
                }
            } catch (Exception e) {
                log.error("[调试] 自动填充 Placer 发生异常: {}", e.getMessage(), e);
            }
        }
        if (entity.getPlaceTime() == null) {
            entity.setPlaceTime(new Date());
        }
        if (entity.getStatus() == null) {
            entity.setStatus(ErpOrderStatus.WAIT_AUDIT.getCode());
        }

        boolean result = baseMapper.insert(entity) > 0;

        if (result && ObjectUtil.isNotEmpty(bo.getDetailIds())) {
            // 根据前端传递的明细 ID 列表，精确更新这批明细关联的订单 ID
            com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<org.dromara.erp.domain.ErpOrderDetail> luw = Wrappers.lambdaUpdate();
            luw.set(org.dromara.erp.domain.ErpOrderDetail::getOrderId, entity.getRowId())
               .in(org.dromara.erp.domain.ErpOrderDetail::getRowId, bo.getDetailIds());
            erpOrderDetailMapper.update(null, luw);
        }
        return result ? entity.getRowId() : null;
    }

    @Override
    @com.baomidou.dynamic.datasource.annotation.DSTransactional
    public Boolean auditOrder(org.dromara.erp.domain.ErpOrderAudit audit) {
        // 1. 修改订单状态
        ErpOrder order = baseMapper.selectById(audit.getOrderId());
        if (order == null) {
            throw new org.dromara.common.core.exception.ServiceException("订单不存在");
        }

        // 根据审核结果设置订单状态
        if (ErpAuditResult.PASS.getCode().equals(audit.getAuditResult())) { // 通过 → 待签批
            order.setStatus(ErpOrderStatus.WAIT_SIGN.getCode());
        } else if (ErpAuditResult.REJECT.getCode().equals(audit.getAuditResult())) { // 驳回 → 已驳回
            order.setStatus(ErpOrderStatus.REJECTED.getCode());
        }
        baseMapper.updateById(order);

        // 2. 记录审核历史
        if (audit.getRowId() == null) {
            audit.setRowId(IdUtil.fastUUID());
        }
        if (audit.getAuditor() == null) {
            audit.setAuditor(org.dromara.common.satoken.utils.LoginHelper.getUserId());
        }
        if (audit.getAuditTime() == null) {
            audit.setAuditTime(new Date());
        }
        return erpOrderAuditMapper.insert(audit) > 0;
    }

    @Override
    public Boolean cancelOrder(String rowId) {
        ErpOrder order = baseMapper.selectById(rowId);
        if (order == null) {
            throw new org.dromara.common.core.exception.ServiceException("订单不存在");
        }
        if (!ErpOrderStatus.WAIT_AUDIT.getCode().equals(order.getStatus())) {
            throw new org.dromara.common.core.exception.ServiceException("仅待审核状态的订单可以撤销");
        }
        order.setStatus(ErpOrderStatus.CANCELLED.getCode());
        return baseMapper.updateById(order) > 0;
    }

    @Override
    public void syncErpOrderStatus() {
        log.info("[ERP状态同步] 开始同步...");
        // 查询 erpDocCode 不为空且未完成的订单
        LambdaQueryWrapper<ErpOrder> lqw = Wrappers.lambdaQuery();
        lqw.isNotNull(ErpOrder::getErpDocCode)
           .ne(ErpOrder::getErpDocCode, "")
           .ne(ErpOrder::getStatus, ErpOrderStatus.FINISHED.getCode());
        List<ErpOrder> orders = baseMapper.selectList(lqw);

        if (orders.isEmpty()) {
            log.info("[ERP状态同步] 无可同步的订单");
            return;
        }

        int updatedCount = 0;
        for (ErpOrder order : orders) {
            try {
                // 根据 erpDocCode 查询 ERP 销售订单
                LambdaQueryWrapper<org.dromara.erp.domain.ErpSaleOrderMaster> masterLqw = Wrappers.lambdaQuery();
                masterLqw.eq(org.dromara.erp.domain.ErpSaleOrderMaster::getDocCode, order.getErpDocCode());
                org.dromara.erp.domain.ErpSaleOrderMaster master = erpSaleOrderMasterMapper.selectOne(masterLqw);

                if (master == null) {
                    log.warn("[ERP状态同步] 未找到 ERP 单据: {}", order.getErpDocCode());
                    continue;
                }

                Integer newStatus = null;
                if (Integer.valueOf(1).equals(master.getFinished())) {
                    // 已完成
                    newStatus = ErpOrderStatus.FINISHED.getCode();
                } else if (Integer.valueOf(1).equals(master.getReviewed())) {
                    // 已签批
                    newStatus = ErpOrderStatus.PRODUCING.getCode();
                } else if (Integer.valueOf(1).equals(master.getApproved())) {
                    // 已审核
                    newStatus = ErpOrderStatus.WAIT_SIGN.getCode();
                }

                if (newStatus != null && !newStatus.equals(order.getStatus())) {
                    order.setStatus(newStatus);
                    baseMapper.updateById(order);
                    updatedCount++;
                    log.info("[ERP状态同步] 订单 {} (ERP:{}) 状态更新为: {}",
                        order.getCode(), order.getErpDocCode(), newStatus);
                }
            } catch (Exception e) {
                log.error("[ERP状态同步] 处理订单 {} 异常: {}", order.getCode(), e.getMessage(), e);
            }
        }
        log.info("[ERP状态同步] 完成，共处理 {} 条，更新 {} 条", orders.size(), updatedCount);
    }
}
