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

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.zg.common.exception.ServiceException;
import com.zg.common.utils.DateUtils;
import com.zg.common.utils.SecurityUtils;
import com.zg.project.wisdom.domain.RkBill;
import com.zg.project.wisdom.domain.dto.*;
import com.zg.project.wisdom.mapper.GysJhMapper;
import com.zg.project.wisdom.mapper.RkBillMapper;
import com.zg.project.wisdom.utils.BillNoUtil;
import com.zg.project.wisdom.utils.CodeConvertUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zg.project.wisdom.mapper.RkInfoMapper;
import com.zg.project.wisdom.domain.RkInfo;
import com.zg.project.wisdom.service.IRkInfoService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 库存单据主Service业务层处理
 * 
 * @author zg
 * @date 2025-05-28
 */
@Service
public class RkInfoServiceImpl implements IRkInfoService 
{

    @Autowired
    private RkInfoMapper rkInfoMapper;

    @Autowired
    private GysJhMapper gysJhMapper;

    @Autowired
    private RkBillMapper rkBillMapper;

    /**
     * 查询库存单据主
     * 
     * @param id 库存单据主主键
     * @return 库存单据主
     */
    @Override
    public RkInfo selectRkInfoById(Long id)
    {
        return rkInfoMapper.selectRkInfoById(id);
    }

    /**
     * 查询库存单据主列表
     * 
     * @param rkInfo 库存单据主
     * @return 库存单据主
     */
    @Override
    public List<RkInfo> selectRkInfoList(RkInfo rkInfo) {
        List<RkInfo> list = rkInfoMapper.selectRkInfoList(rkInfo);
        LocalDate today = LocalDate.now();

        for (RkInfo info : list) {
            if (info.getRkTime() != null) {
                LocalDate rkDate = info.getRkTime().toInstant()
                        .atZone(ZoneId.systemDefault())
                        .toLocalDate();
                long days = ChronoUnit.DAYS.between(rkDate, today);
                info.setStockAge(days);
            }
        }

        return list;
    }


    /**
     * 修改库存单据主
     * 
     * @param rkInfo 库存单据主
     * @return 结果
     */
    @Override
    public int updateRkInfo(RkInfo rkInfo)
    {
        rkInfo.setUpdateTime(DateUtils.getNowDate());
        return rkInfoMapper.updateRkInfo(rkInfo);
    }

    /**
     * 批量删除库存单据主
     * 
     * @param ids 需要删除的库存单据主主键
     * @return 结果
     */
    @Override
    public int deleteRkInfoByIds(Long[] ids)
    {
        return rkInfoMapper.deleteRkInfoByIds(ids);
    }

    /**
     * 删除库存单据主信息
     * 
     * @param id 库存单据主主键
     * @return 结果
     */
    @Override
    public int deleteRkInfoById(Long id)
    {
        return rkInfoMapper.deleteRkInfoById(id);
    }

    /**
     * 新增入库单据
     * @param dto
     * @return
     */
    @Override
    public int batchInsert(PcRkInfoBatchDTO dto) {
        List<RkInfo> saveList = new ArrayList<>();
        String username = SecurityUtils.getUsername();
        Date now = DateUtils.getNowDate();

        if (dto.getRkList() == null || dto.getRkList().isEmpty()) {
            throw new ServiceException("rkList 入库明细列表不能为空");
        }

        // ✅ 生成统一单据号
        String billNo = BillNoUtil.generateTodayBillNo();

        // ✅ 插入单据主表
        RkBill bill = new RkBill();
        bill.setBillNo(billNo);
        bill.setRkType(dto.getRkType());
        bill.setWlType(dto.getWlType());
        bill.setCangku(dto.getCangku());
        bill.setRkTime(now);
        bill.setLihuoY(dto.getLihuoY());
        bill.setIsChuku("0");
        bill.setIsDelete("0");
        bill.setCreateBy(username);
        bill.setCreateTime(now);
        rkBillMapper.insertRkBill(bill);

        // ✅ 构建明细列表
        for (PcRkInfoItemDTO item : dto.getRkList()) {
            RkInfo entity = new RkInfo();

            entity.setRkType(dto.getRkType());
            entity.setWlType(dto.getWlType());
            entity.setCangku(dto.getCangku());
            entity.setLihuoY(dto.getLihuoY());

            entity.setBillNo(billNo);

            entity.setXj(item.getXj());
            entity.setXmNo(item.getXmNo());
            entity.setXmMs(item.getXmMs());
            entity.setSapNo(item.getSapNo());
            entity.setJhQty(item.getJhQty());
            entity.setHtQty(item.getHtQty());
            entity.setJhAmt(item.getJhAmt());
            entity.setHtDj(item.getHtDj());
            entity.setDw(item.getDw());
            entity.setWlNo(item.getWlNo());
            entity.setWlMs(item.getWlMs());
            entity.setGysNo(item.getGysNo());
            entity.setGysMc(item.getGysMc());

            entity.setRealQty(item.getRealQty());
            entity.setPcode(item.getPcode());
            if (item.getPcode() != null) {
                entity.setPcodeId(CodeConvertUtil.stringToHex(item.getPcode()));
            }
            entity.setTrayCode(item.getTrayCode());
            entity.setEntityId(item.getEntityId());
            entity.setRemark(item.getRemark());

            // 系统字段
            entity.setIsChuku("0");
            entity.setIsDelete("0");
            entity.setRkTime(now);
            entity.setCreateBy(username);
            entity.setCreateTime(now);

            saveList.add(entity);

            if (item.getGysJhId() != null) {
                gysJhMapper.updateStatusById(item.getGysJhId());
            }
        }

        if (saveList.isEmpty()) {
            throw new ServiceException("未提取到任何可保存的数据");
        }

        return rkInfoMapper.batchInsertRkInfo(saveList);
    }


    /**
     * 新增入库单据（APP）
     * @param dto
     * @return
     */
    @Override
    public int batchInsertApp(RkInfoBatchDTO dto) {
        List<RkInfo> saveList = new ArrayList<>();
        String username = SecurityUtils.getUsername();
        Date now = DateUtils.getNowDate();

        if (dto.getRkList() == null || dto.getRkList().isEmpty()) {
            throw new ServiceException("rkList 入库明细列表不能为空");
        }

        // ✅ 生成统一的单据号
        String billNo = BillNoUtil.generateTodayBillNo();

        RkBill bill = new RkBill();
        bill.setBillNo(billNo);
        bill.setRkType(dto.getRkType());
        bill.setWlType(dto.getWlType());
        bill.setCangku(dto.getCangku());
        bill.setRkTime(now);
        bill.setLihuoY(dto.getLihuoY());
        bill.setIsChuku("0");
        bill.setIsDelete("0");
        bill.setCreateBy(username);
        bill.setCreateTime(now);

        rkBillMapper.insertRkBill(bill);

        for (RkInfoItemDTO item : dto.getRkList()) {
            List<RkInfoScanDTO> scanList = item.getScanList();
            if (scanList == null || scanList.isEmpty()) {
                continue;
            }

            for (RkInfoScanDTO scan : scanList) {

                RkInfo entity = new RkInfo();

                // 批次字段
                entity.setRkType(dto.getRkType());
                entity.setWlType(dto.getWlType());
                entity.setCangku(dto.getCangku());
                entity.setLihuoY(dto.getLihuoY());

                entity.setBillNo(billNo);

                // 明细字段（RkInfoItemDTO）
                entity.setXj(item.getXj());
                entity.setXmMs(item.getXmMs());
                entity.setXmNo(item.getXmNo());
                entity.setSapNo(item.getSapNo());
                entity.setJhQty(item.getJhQty());
                entity.setHtQty(item.getHtQty());
                entity.setJhAmt(item.getJhAmt());
                entity.setHtDj(item.getHtDj());
                entity.setDw(item.getDw());
                entity.setWlNo(item.getWlNo());
                entity.setWlMs(item.getWlMs());
                entity.setGysNo(item.getGysNo());
                entity.setGysMc(item.getGysMc());

                // 扫码记录（RkInfoScanDTO）
                entity.setPcode(scan.getPcode());
                if (scan.getPcode() != null) {
                    entity.setPcodeId(CodeConvertUtil.stringToHex(scan.getPcode()));
                }
                entity.setTrayCode(scan.getTrayCode());
                entity.setRealQty(scan.getRealQty());
                entity.setEntityId(scan.getEntityId());
                entity.setRemark(scan.getRemark());

                // 系统字段
                entity.setIsDelete("0");
                entity.setIsChuku("0");
                entity.setRkTime(now);
                entity.setCreateBy(username);
                entity.setCreateTime(now);

                saveList.add(entity);
            }

            // 每个 item 的 供应计划主键ID 更新一次供应计划状态
            if (item.getGysJhId() != null) {
                gysJhMapper.updateStatusById(item.getGysJhId());
            }

        }

        if (saveList.isEmpty()) {
            throw new ServiceException("未提取到任何可保存的数据");
        }

        return rkInfoMapper.batchInsertRkInfo(saveList);
    }

    @Transactional
    public void deleteByBillNo(String billNo) {
        // 1. 查询 sap_no
        List<String> sapNos = rkInfoMapper.selectSapNoByBillNo(billNo);

        // 2. 更新供应计划状态
        if (sapNos != null && !sapNos.isEmpty()) {
            gysJhMapper.resetGysJhStatusBySapNos(sapNos);
        }

        // 3. 删除入库记录
        rkInfoMapper.deleteByBillNo(billNo);
    }

    /**
     * 统计过期库存
     * @return
     */
    @Override
    public int countOverdueStock() {
        return rkInfoMapper.countOverdueStock();
    }

    /**
     * 获取最新20条逾期库存列表
     * @param i
     * @return
     */
    @Override
    public List<RkInfo> selectTopOverdueStock(int i) {
        return rkInfoMapper.selectTopOverdueStock(i);
    }

    @Override
    public int updateOutStock(StockOutDTO dto) {
        if (dto == null || dto.getIds() == null || dto.getIds().isEmpty()) {
            throw new ServiceException("出库记录ID列表不能为空");
        }

        Date now = dto.getLyTime() != null ? dto.getLyTime() : DateUtils.getNowDate();
        String username = SecurityUtils.getUsername();

        List<RkInfo> list = new ArrayList<>();
        for (Long id : dto.getIds()) {
            RkInfo entity = new RkInfo();
            entity.setId(id);
            entity.setIsChuku("1");
            entity.setLyTime(now);
            entity.setCkType(dto.getCkType());
            entity.setTeamCode(dto.getTeamCode());
            entity.setCkLihuoY(dto.getCkLihuoY());
            entity.setUpdateBy(username);
            entity.setUpdateTime(now);
            list.add(entity);
        }

        rkBillMapper.updateOutStock(dto.getIds());

        return rkInfoMapper.batchUpdateOutStock(list);
    }

}
