package com.zg.project.information.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.zg.common.exception.ServiceException;
import com.zg.common.utils.DateUtils;
import com.zg.common.utils.StringUtils;
import com.zg.project.wisdom.mapper.RkInfoMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zg.project.information.mapper.PcdeDetailMapper;
import com.zg.project.information.domain.PcdeDetail;
import com.zg.project.information.service.IPcdeDetailService;

/**
 * 库位明细Service业务层处理
 * 
 * @author zg
 * @date 2025-05-29
 */
@Service
public class PcdeDetailServiceImpl implements IPcdeDetailService 
{
    @Autowired
    private PcdeDetailMapper pcdeDetailMapper;

    @Autowired
    private RkInfoMapper rkInfoMapper;

    /**
     * 查询库位明细
     * 
     * @param id 库位明细主键
     * @return 库位明细
     */
    @Override
    public PcdeDetail selectPcdeDetailById(Long id)
    {
        return pcdeDetailMapper.selectPcdeDetailById(id);
    }

    /**
     * 查询库位明细列表
     * 
     * @param pcdeDetail 库位明细
     * @return 库位明细
     */
    @Override
    public List<PcdeDetail> selectPcdeDetailList(PcdeDetail pcdeDetail)
    {
        return pcdeDetailMapper.selectPcdeDetailList(pcdeDetail);
    }

    /**
     * 新增库位明细
     * 
     * @param pcdeDetail 库位明细
     * @return 结果
     */
    @Override
    public int insertPcdeDetail(PcdeDetail pcdeDetail) {
        // 原始 locationCode
        String locationCode = pcdeDetail.getPcode();

        // 将 locationCode 转换为十六进制字符串
        StringBuilder hex = new StringBuilder();
        for (int i = 0; i < locationCode.length(); i++) {
            char c = locationCode.charAt(i);
            String hexPart = Integer.toHexString(c).toUpperCase();
            hex.append(hexPart);
        }

        pcdeDetail.setEncodedId( hex.toString());

        // 继续插入操作
        return pcdeDetailMapper.insertPcdeDetail(pcdeDetail);
    }
    /**
     * 修改库位明细
     * 
     * @param pcdeDetail 库位明细
     * @return 结果
     */
    @Override
    public int updatePcdeDetail(PcdeDetail pcdeDetail)
    {
        return pcdeDetailMapper.updatePcdeDetail(pcdeDetail);
    }

    /**
     * 批量删除库位明细
     * 
     * @param ids 需要删除的库位明细主键
     * @return 结果
     */
//    @Override
//    public int deletePcdeDetailByIds(Long[] ids)
//    {
//        for (Long id : ids) {
//            // 获取库位信息
//            PcdeDetail pcdeDetail = pcdeDetailMapper.selectPcdeDetailById(id);
//            if (pcdeDetail == null) {
//                throw new ServiceException("ID为 " + id + " 的库位不存在，无法删除");
//            }
//
//            // 获取库位编号
//            String locationCode = pcdeDetail.getPcode();
//
//            // 检查该库位是否仍有关联货物
//            int count = rkInfoMapper.countRkInfoByLocationCode(locationCode);
//            if (count > 0) {
//                throw new ServiceException("库位 [" + locationCode + "] 上还有货物，无法批量删除");
//            }
//        }
//
//        // 全部校验通过后再执行删除
//        return pcdeDetailMapper.deletePcdeDetailByIds(ids);
//    }

    /**
     * 删除库位明细信息
     * 
     * @param
     * @return 结果
     */
//    @Override
//    public int deletePcdeDetailById(Long id)
//    {
//        // 根据主键获取库位明细
//        PcdeDetail pcdeDetail = pcdeDetailMapper.selectPcdeDetailById(id);
//        if (pcdeDetail == null) {
//            throw new ServiceException("库位信息不存在，无法删除");
//        }
//
//        // 获取库位编号
//        String locationCode = pcdeDetail.getPcode();
//
//        // 查询该库位上是否存在库存
//        int count = rkInfoMapper.countRkInfoByLocationCode(locationCode);
//        if (count > 0) {
//            throw new ServiceException("该库位上还有货物，无法删除");
//        }
//
//        // 删除库位信息
//        return pcdeDetailMapper.deletePcdeDetailById(id);
//    }

    @Override
    public String importPcdeDetail(List<PcdeDetail> pcdeList, String operName) {
        if (CollectionUtils.isEmpty(pcdeList)) {
            throw new ServiceException("导入数据不能为空！");
        }

        final Date now = DateUtils.getNowDate();

        // 1) 清洗 + 本地生成 encodedId（逐字符→Unicode→HEX大写→拼接）
        List<PcdeDetail> cleaned = new ArrayList<>(pcdeList.size());
        for (PcdeDetail d : pcdeList) {
            if (d == null) continue;
            String p = d.getPcode() == null ? null : d.getPcode().trim();
            if (StringUtils.isEmpty(p)) {
                // 跳过空 pcode
                continue;
            }
            d.setPcode(p);
            d.setEncodedId(toHexStringFromPcode(p));

            // 审计字段（与你实体保持一致：createdBy/createdAt/updatedBy/updatedAt）
            d.setCreatedBy(operName);
            d.setCreatedAt(now);
            d.setUpdatedBy(operName);
            d.setUpdatedAt(now);

            // 业务兜底
            if (d.getIsDelete() == null) d.setIsDelete("0");

            cleaned.add(d);
        }

        if (cleaned.isEmpty()) {
            throw new ServiceException("有效的库位编号为空，请检查导入文件！");
        }

        // 2) 批量写库（分片，避免 SQL 过大；配合 uk_pcode + INSERT IGNORE 实现幂等忽略）
        final int batchSize = 1000;
        int totalTried = cleaned.size();
        int totalInserted = 0;

        for (int i = 0; i < cleaned.size(); i += batchSize) {
            int end = Math.min(i + batchSize, cleaned.size());
            List<PcdeDetail> slice = cleaned.subList(i, end);
            int affected = pcdeDetailMapper.batchInsertIgnore(slice);
            totalInserted += affected;
        }

        int skipped = totalTried - totalInserted;
        return String.format("导入完成：共读取 %d 条，成功导入 %d 条，跳过(可能重复) %d 条。",
                totalTried, totalInserted, skipped);
    }

    /** 将 pcode 按字符转大写十六进制（与新增接口保持一致） */
    private String toHexStringFromPcode(String pcode) {
        StringBuilder hex = new StringBuilder(pcode.length() * 2);
        for (int i = 0; i < pcode.length(); i++) {
            char c = pcode.charAt(i);
            hex.append(Integer.toHexString(c).toUpperCase());
        }
        return hex.toString();
    }

    /**
     * 获取未被入库单据使用的库位列表
     */
//    @Override
//    public List<PcdeDetail> getAllPcde() {
//        // 查询所有库位
//        List<PcdeDetail> pcdeList = pcdeDetailMapper.selectPcdeDetailList(new PcdeDetail());
//
//        // 查询已被使用过的库位码（pcode）
//        List<String> usedPcodeList = rkInfoMapper.selectUsedPcodes();
//
//        // 过滤掉已使用的
//        List<PcdeDetail> availableList = pcdeList.stream()
//                .filter(p -> !usedPcodeList.contains(p.getPcode()))
//                .collect(Collectors.toList());
//
//        return availableList;
//    }

    @Override
    public List<PcdeDetail> selectByWarehouseCode(String warehouseCode)
    {
        return pcdeDetailMapper.selectByWarehouseCode(warehouseCode);
    }
}
