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

import java.util.List;
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.project.wisdom.domain.GysJh;
import com.zg.project.wisdom.domain.RkInfo;
import com.zg.project.wisdom.mapper.RkInfoMapper;
import com.zg.project.wisdom.service.IRkInfoService;
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.getLocationCode();

        // 将 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.getLocationCode();

            // 检查该库位是否仍有关联货物
            int count = rkInfoMapper.countRkInfoByLocationCode(locationCode);
            if (count > 0) {
                throw new ServiceException("库位 [" + locationCode + "] 上还有货物，无法批量删除");
            }
        }

        // 全部校验通过后再执行删除
        return pcdeDetailMapper.deletePcdeDetailByIds(ids);
    }

    /**
     * 删除库位明细信息
     * 
     * @param id 库位明细主键
     * @return 结果
     */
    @Override
    public int deletePcdeDetailById(Long id)
    {
        // 根据主键获取库位明细
        PcdeDetail pcdeDetail = pcdeDetailMapper.selectPcdeDetailById(id);
        if (pcdeDetail == null) {
            throw new ServiceException("库位信息不存在，无法删除");
        }

        // 获取库位编号
        String locationCode = pcdeDetail.getLocationCode();

        // 查询该库位上是否存在库存
        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("导入数据不能为空！");
        }

        int successNum = 0;
        int failureNum = 0;
        StringBuilder failureMsg = new StringBuilder();

        for (PcdeDetail detail : pcdeList) {
            try {
                PcdeDetail exist = pcdeDetailMapper.selectByLocationCode(detail.getLocationCode());
                if (exist == null) {
                    detail.setCreateBy(operName);
                    detail.setCreateTime(DateUtils.getNowDate());
                    pcdeDetailMapper.insertPcdeDetail(detail);
                    successNum++;
                } else {
                    failureNum++;
                    failureMsg.append("<br/>库位编号 ").append(detail.getLocationCode()).append(" 已存在");
                }
            } catch (Exception e) {
                failureNum++;
                failureMsg.append("<br/>库位编号 ").append(detail.getLocationCode()).append(" 导入失败：").append(e.getMessage());
            }
        }

        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据有误，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            return "恭喜您，数据已全部导入成功！共 " + successNum + " 条。";
        }
    }

    /**
     * 获取未被入库单据使用的库位列表
     */
    @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.getLocationCode()))
                .collect(Collectors.toList());

        return availableList;
    }
}
