package com.zt.plat.module.contractorder.service.salesorder;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONException;
import com.alibaba.fastjson2.JSONObject;
import com.zt.plat.framework.common.exception.ErrorCode;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.util.spring.SpringUtils;
import com.zt.plat.module.base.api.materialinfomation.MaterialInfomationApi;
import com.zt.plat.module.base.api.materialinfomation.dto.MaterialInfomationPageReqDTO;
import com.zt.plat.module.base.api.materialinfomation.dto.MaterialInfomationRespDTO;
import com.zt.plat.module.base.dal.dataobject.base.ElementDO;
import com.zt.plat.module.base.service.base.ElementService;
import com.zt.plat.module.contractorder.controller.admin.salesorder.vo.SalesOrderDetailPageReqVO;
import com.zt.plat.module.contractorder.controller.admin.salesorder.vo.SalesOrderDetailRespVO;
import com.zt.plat.module.contractorder.controller.admin.salesorder.vo.SalesOrderDetailSaveReqVO;
import com.zt.plat.module.contractorder.dal.dataobject.purchaseorder.PrchOrdDtlDO;
import com.zt.plat.module.contractorder.dal.dataobject.salesorder.SalesOrderDO;
import com.zt.plat.module.contractorder.dal.dataobject.salesorder.SalesOrderDetailDO;
import com.zt.plat.module.contractorder.dal.mysql.salesorder.SalesOrderDetailMapper;
import com.zt.plat.module.contractorder.dal.mysql.salesorder.SalesOrderMapper;
import com.zt.plat.module.contractorder.enums.ErpConstants;
import com.zt.plat.module.erp.controller.admin.erp.vo.SalesDocumentRequestVO;
import com.zt.plat.module.erp.service.erp.ErpOrderService;
import com.zt.plat.module.receivedeliver.api.bill.BillMainApi;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.format.DateTimeFormatter;
import java.util.*;

import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.pojo.PageParam;
import com.zt.plat.framework.common.util.object.BeanUtils;


import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;

import static com.zt.plat.module.contractorder.enums.purchaseorder.ErrorCodeConstants.MTRL_CODE_NOT_EXISTS;
import static com.zt.plat.module.contractorder.enums.salesorder.ErrorCodeConstants.SALES_ORDER_DETAIL_NOT_EXISTS;

/**
 * 销售订单明细 Service 实现类
 *
 * @author 后台管理-1
 */
@Service
@Validated
@Slf4j
public class SalesOrderDetailServiceImpl implements SalesOrderDetailService {

    @Resource
    private SalesOrderDetailMapper salesOrderDetailMapper;
    @Resource
    private BillMainApi billMainApi;
    @Resource
    private ElementService elementService;

    @Override
    @Transactional
    public SalesOrderDetailRespVO createSalesOrderDetail(SalesOrderDetailSaveReqVO createReqVO) {
        // 插入
        SalesOrderDetailDO salesOrderDetail = BeanUtils.toBean(createReqVO, SalesOrderDetailDO.class);
        salesOrderDetail.setTrfQty(BigDecimal.ZERO);
        salesOrderDetail.setOrderId(Long.valueOf(createReqVO.getOrderId()));
        // 设置物料信息
        setElemInfo(salesOrderDetail);
        salesOrderDetailMapper.insert(salesOrderDetail);
        // 返回
        return BeanUtils.toBean(salesOrderDetail, SalesOrderDetailRespVO.class);
    }

    private void setElemInfo(SalesOrderDetailDO salesOrderDetail) {
        if (salesOrderDetail.getElementAbbreviation() == null) {
            return;
        }
        ElementDO elementBySymbol = elementService.getElementBySymbol(salesOrderDetail.getElementAbbreviation());
        if (elementBySymbol != null) {
            salesOrderDetail.setElementName(elementBySymbol.getName());
            salesOrderDetail.setElementNumber(elementBySymbol.getCoding());
        } else {
            log.warn("元素编号【{}】不存在,订单号【{}】", salesOrderDetail.getElementAbbreviation(), salesOrderDetail.getOrderId());
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<SalesOrderDetailRespVO> createSalesOrderDetail(List<SalesOrderDetailSaveReqVO> createReqVOS) {
        // 1. VO转DO，同时修复orderId赋值：通过索引一一对应，避免覆盖
        List<SalesOrderDetailDO> salesOrderDetailDOS = new ArrayList<>();
        for (SalesOrderDetailSaveReqVO reqVO : createReqVOS) {
            SalesOrderDetailDO detailDO = BeanUtils.toBean(reqVO, SalesOrderDetailDO.class);
            // 一一对应设置orderId，从当前VO获取，避免循环覆盖
            detailDO.setOrderId(Long.valueOf(reqVO.getOrderId()));
            salesOrderDetailDOS.add(detailDO);
        }

        // 2. 处理每个明细的物料信息+价格条件（扁平化+标准JSON）
        salesOrderDetailDOS.forEach(salesOrderDetail -> {
            // 设置物料信息
            setElemInfo(salesOrderDetail);
            String priceConditionDetail = salesOrderDetail.getPriceConditionDetail();
            // 空值校验，避免空指针
            if (priceConditionDetail == null || priceConditionDetail.isEmpty()) {
                return;
            }

            // 定义一维集合，收集扁平化后的JSON对象（直接存对象，而非字符串）
            List<JSONObject> flatJsonList = new ArrayList<>();
            // 解析原嵌套JSON数组
            List<JSONArray> jsonArrays = JSONArray.parseArray(priceConditionDetail, JSONArray.class);
            for (JSONArray jsonArray : jsonArrays) {
                if (jsonArray == null || jsonArray.isEmpty()) {
                    continue;
                }
                for (int i = 0; i < jsonArray.size(); i++) {
                    String originalJsonStr = jsonArray.getString(i);
                    if (originalJsonStr == null || originalJsonStr.isEmpty()) {
                        continue;
                    }
                    JSONObject jsonObject = JSONObject.parseObject(originalJsonStr);
                    // 添加flag为U
                    jsonObject.put("flag", ErpConstants.SALES_DOCUMENT_REQUEST_FLAG_U);
                    log.info(jsonObject.toString());
                    // 收集处理后的JSON对象
                    flatJsonList.add(jsonObject);
                }
            }

            // 核心修复：将一维JSON对象集合转为【标准JSON一维数组字符串】
            JSONArray standardJsonArray = new JSONArray(flatJsonList);
            salesOrderDetail.setPriceConditionDetail(standardJsonArray.toJSONString());
        });

        // 3. 批量插入
        salesOrderDetailMapper.insertBatch(salesOrderDetailDOS);
        // 4. DO转VO返回
        return BeanUtils.toBean(salesOrderDetailDOS, SalesOrderDetailRespVO.class);
    }

    @Override
    public void updateSalesOrderDetail(SalesOrderDetailSaveReqVO updateReqVO) {
        // 校验存在
        validateSalesOrderDetailExists(updateReqVO.getId());
        // 更新
        SalesOrderDetailDO updateObj = BeanUtils.toBean(updateReqVO, SalesOrderDetailDO.class);
        salesOrderDetailMapper.updateById(updateObj);
    }

    @Override
    public void updateSalesOrderDetailList(List<SalesOrderDetailSaveReqVO> updateReqVO) {
        // 1. VO转DO
        List<SalesOrderDetailDO> beanList = BeanUtils.toBean(updateReqVO, SalesOrderDetailDO.class);
        beanList.forEach(this::setElemInfo);

        beanList.forEach(item -> {
            String priceConditionDetail = item.getPriceConditionDetail();
            // 空值校验，避免空指针异常
            if (priceConditionDetail == null || priceConditionDetail.isEmpty()) {
                return;
            }

            // 2. 解析外层JSON数组（原嵌套数组）
            List<JSONArray> outerJsonArrays = JSONArray.parseArray(priceConditionDetail, JSONArray.class);
            if (item.getId() != null && !outerJsonArrays.isEmpty()) {
                // 核心修改：定义一维集合，收集所有扁平后的元素
                List<Object> flatProcessedElements = new ArrayList<>();

                // 遍历外层数组，扁平化所有内层元素
                for (JSONArray innerJsonArray : outerJsonArrays) {
                    if (innerJsonArray == null || innerJsonArray.isEmpty()) {
                        continue;
                    }
                    // 遍历当前内层数组的每个元素，做flag处理
                    for (int innerIdx = 0; innerIdx < innerJsonArray.size(); innerIdx++) {
                        String originalJsonStr = innerJsonArray.getString(innerIdx);
                        if (originalJsonStr == null || originalJsonStr.isEmpty()) {
                            continue;
                        }
                        JSONObject jsonObject = JSONObject.parseObject(originalJsonStr);
                        String flag = jsonObject.getString("flag");

                        // 根据flag处理：D删除，I改U，其他保留
                        if (ErpConstants.SALES_DOCUMENT_REQUEST_FLAG_D.equals(flag)) {
                            continue; // D直接跳过（删除）
                        } else if (ErpConstants.SALES_DOCUMENT_REQUEST_FLAG_I.equals(flag)) {
                            jsonObject.put("flag", ErpConstants.SALES_DOCUMENT_REQUEST_FLAG_U);
                            flatProcessedElements.add(jsonObject); // 加入一维集合
                        } else {
                            flatProcessedElements.add(jsonObject); // 其他flag直接加入
                        }
                    }
                }

                // 3. 把扁平后的一维集合转为JSON数组，直接作为最终结果
                JSONArray finalOneDimensionalArray = JSONArray.parseArray(JSONArray.toJSONString(flatProcessedElements));
                // 4. 重新设置处理后的JSON字符串（此时就是[{},{}]格式）
                item.setPriceConditionDetail(finalOneDimensionalArray.toString());
            } else {
                // 无外层数组/无ID时，保持原空值（避免写入空数组[]，可根据业务调整）
                item.setPriceConditionDetail(priceConditionDetail);
            }
        });
        // 6. 批量插入/更新
        salesOrderDetailMapper.insertOrUpdate(beanList);
    }
    @Override
    public void deleteSalesOrderDetail(Long id) {
        // 校验存在
        validateSalesOrderDetailExists(id);
        // 删除
        salesOrderDetailMapper.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteSalesOrderDetailListByIds(List<Long> ids) {
        //校验是否可以删除
        validateBillMainCanDelete(ids);
        // 校验存在
        validateSalesOrderDetailExists(ids);
        //
        // 提交erp删除
        submitErpDelete092(ids);
        // 删除
        salesOrderDetailMapper.deleteByIds(ids);
    }

    private void submitErpDelete092(List<Long> ids) {
        //删除订单明细提交erp
        log.info("开始处理ERP 092 删除订单明细：{}", ids);
        //根据订单明细查询订单
        SalesOrderDO salesOrderDO = SpringUtils.getBean(SalesOrderMapper.class).selectById(ids.get(0));
        if (salesOrderDO.getOrderSAPNumber() == null) {
            log.warn("订单编号【{}】尚未提交erp", ids.get(0));
            return;
        }
        List<SalesOrderDetailDO> salesOrderDetailDOS = salesOrderDetailMapper.selectByIds(ids);
        SalesDocumentRequestVO salesDocumentRequestVO = new SalesDocumentRequestVO();
        buildSalesDocumentRequestData(salesDocumentRequestVO, salesOrderDO, salesOrderDetailDOS);
        String result = SpringUtils.getBean(ErpOrderService.class).submitOrderToErp092(salesDocumentRequestVO);
        log.info("ERP 092 删除订单明细结果：{}", result);
    }

    public void buildSalesDocumentRequestData(SalesDocumentRequestVO salesDocumentRequestVO, SalesOrderDO salesOrderDO, List<SalesOrderDetailDO> salesOrderDetailList) {
        //head-抬头
        salesDocumentRequestVO.setSalesdocument(salesOrderDO.getOrderSAPNumber());
        salesDocumentRequestVO.setUpdateflag(ErpConstants.SALES_DOCUMENT_REQUEST_FLAG_U);
        salesDocumentRequestVO.setPartn_es(salesOrderDO.getPayerNum());
        //Head
        SalesDocumentRequestVO.Head head = new SalesDocumentRequestVO.Head();
        head.setSales_org(salesOrderDO.getSaleOrgzCd());//销售组织
        head.setDistr_chan(salesOrderDO.getSaleAcsCdg());//销售渠道
        head.setDivision(salesOrderDO.getPdtGrpCdg());//产品组编码
        head.setReq_date_h(salesOrderDO.getVoucherDate().format(DateTimeFormatter.ofPattern("yyyyMMdd")));//凭证日期
        //item
        List<SalesDocumentRequestVO.Item> items = new ArrayList<>();
        salesOrderDetailList.forEach(salesOrderDetail -> {
            MaterialInfomationPageReqDTO infomationPageReqDTO = new MaterialInfomationPageReqDTO();
            infomationPageReqDTO.setPageSize(10000);
            infomationPageReqDTO.setCode(salesOrderDetail.getMaterialNumber());
            CommonResult<PageResult<MaterialInfomationRespDTO>> materialInfomationPage = SpringUtils.getBean(MaterialInfomationApi.class).getMaterialInfomationPage(infomationPageReqDTO);
            if (materialInfomationPage.getData() == null || materialInfomationPage.getData().getList().isEmpty()) {
                throw exception(MTRL_CODE_NOT_EXISTS);

            }
            MaterialInfomationRespDTO materialInfomationRespDTO = materialInfomationPage.getData().getList().get(0);
            Map<String, Object> flatAttributes = materialInfomationRespDTO.getFlatAttributes();
            //获取中铜物料编码
            String mtrlZhongtongCode = flatAttributes.getOrDefault("mtrlZhongtongCode", "").toString();
            if (mtrlZhongtongCode.isEmpty()) {
                throw exception(MTRL_CODE_NOT_EXISTS);
            }
            SalesDocumentRequestVO.Item item = getItem(salesOrderDetail, mtrlZhongtongCode);
            items.add(item);
        });
        List<String> conds = new ArrayList<>();
        salesOrderDetailList.forEach(salesOrderDetailRespVO -> {
            String priceConditionDetail = salesOrderDetailRespVO.getPriceConditionDetail();
            if (priceConditionDetail == null || priceConditionDetail.trim().isEmpty()) {
                return; // 空字符串直接跳过
            }
            try {
                List<String> strList = new ArrayList<>();
                // 解析 JSON 数组
                List<JSONArray> jsonArrays = JSONArray.parseArray(priceConditionDetail, JSONArray.class);
                if (salesOrderDetailRespVO.getId() != null) {
                    for (JSONArray jsonArray : jsonArrays) {
                        for (int i = 0; i < jsonArray.size(); i++) {
                            // 解析单个JSON字符串为JSONObject
                            JSONObject jsonObject = JSONObject.parseObject(jsonArray.getString(i));
                            // 添加updateflag字段
                            jsonObject.put("updateflag", ErpConstants.SALES_DOCUMENT_REQUEST_FLAG_D);
                            // 将处理后的JSON对象转为字符串并加入strList
                            String processedJson = jsonObject.toString();
                            strList.add(processedJson);
                        }
                    }
                }
                // 将处理后的JSON字符串列表合并到conds
                conds.addAll(strList);
            } catch (JSONException e) {
                // 处理解析失败（例如打日志、忽略错误数据等）
                log.error("解析价格条件详情失败，内容：{}", priceConditionDetail, e);
            }
        });
        salesDocumentRequestVO.setItemList(items);// 设置订单明细列表
        salesDocumentRequestVO.setCondList(conds); // 设置价格条件列表
    }

    private SalesDocumentRequestVO.@NotNull Item getItem(SalesOrderDetailDO salesOrderDetail, String mtrlZhongtongCode) {
        SalesDocumentRequestVO.Item item = new SalesDocumentRequestVO.Item();
        item.setItm_number(Math.toIntExact(salesOrderDetail.getLineNumber()));
        item.setUpdateflag(ErpConstants.SALES_DOCUMENT_REQUEST_FLAG_D);//更新标志
        item.setMaterial(mtrlZhongtongCode);//物料号
        item.setPlant(salesOrderDetail.getFactoryNumber());//工厂编码
        item.setStore_loc(salesOrderDetail.getWarehouseNumber());//库存地点
        item.setSales_unit(salesOrderDetail.getUnt());//单位
        //item.setDlvschduse();//开票类型
        item.setTarget_qty(salesOrderDetail.getQuantity()); //目标数量（暂估数量）
        item.setShip_point(salesOrderDetail.getShippingPlace());//装运地点
        return item;
    }

    private void validateBillMainCanDelete(List<Long> ids) {
        ids.forEach(id -> {
            CommonResult<Boolean> booleanCommonResult = billMainApi.notOffsetIsExistOrderDetailId(id);
            if (booleanCommonResult.isSuccess() && booleanCommonResult.getData()) {
                SalesOrderDetailDO salesOrderDetailDO = salesOrderDetailMapper.selectById(id);
                throw exception(new ErrorCode(1_008_00_600, "订单明细【" + salesOrderDetailDO.getLineNumber() + "】已生成收发货单，不能删除"));
            }
        });
    }

    private void validateSalesOrderDetailExists(List<Long> ids) {
        List<SalesOrderDetailDO> list = salesOrderDetailMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(SALES_ORDER_DETAIL_NOT_EXISTS);
        }
    }

    private void validateSalesOrderDetailExists(Long id) {
        if (salesOrderDetailMapper.selectById(id) == null) {
            throw exception(SALES_ORDER_DETAIL_NOT_EXISTS);
        }
    }

    @Override
    public SalesOrderDetailDO getSalesOrderDetail(Long id) {
        return salesOrderDetailMapper.selectById(id);
    }

    @Override
    public PageResult<SalesOrderDetailDO> getSalesOrderDetailPage(SalesOrderDetailPageReqVO pageReqVO) {
        return salesOrderDetailMapper.selectPage(pageReqVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteSalesOrderDetailByOrderIds(List<Long> orderIds) {
        salesOrderDetailMapper.deleteBatch(SalesOrderDetailDO::getOrderId, orderIds);
    }

    @Override
    public List<SalesOrderDetailRespVO> getSalesOrderDetailByOrderId(Long orderId) {
        List<SalesOrderDetailRespVO> salesOrderDetailRespVOS = BeanUtils.toBean(salesOrderDetailMapper.selectList(SalesOrderDetailDO::getOrderId, orderId), SalesOrderDetailRespVO.class);
        salesOrderDetailRespVOS.forEach(salesOrderDetailRespVO -> salesOrderDetailRespVO.setUnit(salesOrderDetailRespVO.getUnt()));
        return salesOrderDetailRespVOS;
    }


}
