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

import java.math.BigDecimal;
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.information.domain.PcdeDetail;
import com.zg.project.information.mapper.PcdeDetailMapper;
import com.zg.project.wisdom.domain.RkInfo;
import com.zg.project.wisdom.domain.RkRecord;
import com.zg.project.wisdom.domain.dto.MoveRequestDTO;
import com.zg.project.wisdom.domain.dto.MoveTargetItem;
import com.zg.project.wisdom.mapper.MoveRecordMapper;
import com.zg.project.wisdom.domain.MoveRecord;
import com.zg.project.wisdom.mapper.RkInfoMapper;
import com.zg.project.wisdom.mapper.RkRecordMapper;
import com.zg.project.wisdom.service.IMoveRecordService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 移库记录Service业务层处理
 * 
 * @author zg
 * @date 2025-06-20
 */
@Service
public class MoveRecordServiceImpl implements IMoveRecordService 
{
    @Autowired
    private MoveRecordMapper moveRecordMapper;

    @Autowired
    private RkInfoMapper rkInfoMapper;

    @Autowired
    private RkRecordMapper rkRecordMapper;

    @Autowired
    private PcdeDetailMapper pcdeDetailMapper;
    /**
     * 查询移库记录
     * 
     * @param id 移库记录主键
     * @return 移库记录
     */
    @Override
    public MoveRecord selectMoveRecordById(Long id)
    {
        return moveRecordMapper.selectMoveRecordById(id);
    }

    /**
     * 查询移库记录列表
     * 
     * @param moveRecord 查询条件
     * @return 移库记录
     */
    @Override
    public List<MoveRecord> selectMoveRecordList(MoveRecord moveRecord)
    {
        return moveRecordMapper.selectMoveRecordList(moveRecord);
    }

    /**
     * 新增移库记录
     * 
     * @param moveRecord 移库记录
     * @return 结果
     */

    /**
     * 修改移库记录
     * 
     * @param moveRecord 移库记录
     * @return 结果
     */
    @Override
    public int updateMoveRecord(MoveRecord moveRecord)
    {
        return moveRecordMapper.updateMoveRecord(moveRecord);
    }

    /**
     * 批量删除移库记录
     * 
     * @param ids 需要删除的移库记录主键
     * @return 结果
     */
    @Override
    public int deleteMoveRecordByIds(Long[] ids)
    {
        return moveRecordMapper.deleteMoveRecordByIds(ids);
    }

    /**
     * 删除移库记录信息
     * 
     * @param id 移库记录主键
     * @return 结果
     */
    @Override
    public int deleteMoveRecordById(Long id)
    {
        return moveRecordMapper.deleteMoveRecordById(id);
    }

    /**
     * 处理库存移库操作
     *
     * @param dto 移库请求参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void processMove(MoveRequestDTO dto) {

        /* ====================== 0. 基础校验 ====================== */
        if (dto == null || dto.getFromRkId() == null) {
            throw new ServiceException("原库存ID不能为空");
        }
        if (dto.getTargets() == null || dto.getTargets().isEmpty()) {
            throw new ServiceException("目标位置列表不能为空");
        }

        /* ====================== 1. 查询原库存 ====================== */
        RkInfo original = rkInfoMapper.selectRkInfoById(dto.getFromRkId());
        if (original == null || "1".equals(original.getIsDelete())) {
            throw new ServiceException("原库存不存在或已删除");
        }

        BigDecimal originQty = original.getRealQty();
        if (originQty == null || originQty.compareTo(BigDecimal.ZERO) <= 0) {
            throw new ServiceException("原库存数量异常");
        }

        /* ====================== 2. 计算移库总量 ====================== */
        BigDecimal moveTotalQty = dto.getTargets().stream()
                .map(MoveTargetItem::getRealQty)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        if (moveTotalQty.compareTo(originQty) > 0) {
            throw new ServiceException("移库数量不能大于原库存数量");
        }

        String userId = String.valueOf(SecurityUtils.getUserId());
        Date now = DateUtils.getNowDate();

        /* ====================== 3. 原库存快照 ====================== */
        RkInfo snapshot = new RkInfo();
        BeanUtils.copyProperties(original, snapshot);

        /* ====================== 4. 全量移库（不拆分） ====================== */
        if (dto.getTargets().size() == 1 && moveTotalQty.compareTo(originQty) == 0) {

            MoveTargetItem target = dto.getTargets().get(0);

            // 4.1 更新原库存（仅换库位）
            original.setCangku(target.getToCangku());
            original.setPcode(target.getToPcode());
            original.setTrayCode(target.getToTrayCode());
            original.setHasMoved("1");
            original.setUpdateBy(userId);
            original.setUpdateTime(now);
            rkInfoMapper.updateRkInfo(original);

            // 4.2 移库流水（全量移库，无新库存）
            MoveRecord record = new MoveRecord();
            record.setRkInfoId(snapshot.getId());
            record.setNewRkInfoId(null);          // ✅ 关键：全量移库没有新库存
            record.setEntityId(snapshot.getEntityId());
            record.setRealQty(originQty);

            record.setFromCangku(snapshot.getCangku());
            record.setFromPcode(snapshot.getPcode());
            record.setFromTrayCode(snapshot.getTrayCode());

            record.setToCangku(target.getToCangku());
            record.setToPcode(target.getToPcode());
            record.setToTrayCode(target.getToTrayCode());

            record.setMoveReason(dto.getMoveReason());
            record.setMovedBy(userId);
            record.setMovedAt(now);

            record.setCreateBy(userId);
            record.setCreateTime(now);
            record.setUpdateBy(userId);
            record.setUpdateTime(now);
            record.setIsDelete("0");

            moveRecordMapper.insertMoveRecord(record);
            return;
        }

        /* ====================== 5. 部分移库（拆分库存） ====================== */

        // 5.1 原库存扣减数量
        original.setRealQty(originQty.subtract(moveTotalQty));
        original.setHasMoved("1");
        original.setUpdateBy(userId);
        original.setUpdateTime(now);
        rkInfoMapper.updateRkInfo(original);

        // 5.2 生成新库存 + 移库流水
        for (MoveTargetItem target : dto.getTargets()) {

            /* ---------- 新库存 ---------- */
            RkInfo newInfo = new RkInfo();
            BeanUtils.copyProperties(snapshot, newInfo, "id");

            newInfo.setCangku(target.getToCangku());
            newInfo.setPcode(target.getToPcode());
            newInfo.setTrayCode(target.getToTrayCode());
            newInfo.setRealQty(target.getRealQty());
            newInfo.setHasMoved("1");

            newInfo.setCreateBy(userId);
            newInfo.setCreateTime(now);
            newInfo.setUpdateBy(userId);
            newInfo.setUpdateTime(now);

            rkInfoMapper.insertRkInfo(newInfo);

            /* ---------- 移库流水（重点） ---------- */
            MoveRecord record = new MoveRecord();
            record.setRkInfoId(snapshot.getId());         // 原库存
            record.setNewRkInfoId(newInfo.getId());       // ✅ 关键：新库存ID
            record.setEntityId(snapshot.getEntityId());
            record.setRealQty(target.getRealQty());

            record.setFromCangku(snapshot.getCangku());
            record.setFromPcode(snapshot.getPcode());
            record.setFromTrayCode(snapshot.getTrayCode());

            record.setToCangku(target.getToCangku());
            record.setToPcode(target.getToPcode());
            record.setToTrayCode(target.getToTrayCode());

            record.setMoveReason(dto.getMoveReason());
            record.setMovedBy(userId);
            record.setMovedAt(now);

            record.setCreateBy(userId);
            record.setCreateTime(now);
            record.setUpdateBy(userId);
            record.setUpdateTime(now);
            record.setIsDelete("0");

            moveRecordMapper.insertMoveRecord(record);
        }
    }

    /**
     * 撤销移库
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void rollbackMove(Long moveRecordId) {

        if (moveRecordId == null) {
            throw new ServiceException("移库记录ID不能为空");
        }

        /* ====================== 1. 查询移库记录 ====================== */
        MoveRecord record = moveRecordMapper.selectMoveRecordById(moveRecordId);
        if (record == null || "1".equals(record.getIsDelete())) {
            throw new ServiceException("移库记录不存在或已撤销");
        }

        Long originRkInfoId = record.getRkInfoId();
        Long newRkInfoId = record.getNewRkInfoId();

        /* ====================== 2. 查询原库存 ====================== */
        RkInfo origin = rkInfoMapper.selectRkInfoById(originRkInfoId);
        if (origin == null || "1".equals(origin.getIsDelete())) {
            throw new ServiceException("原库存不存在或已删除，无法撤销");
        }

        String userId = String.valueOf(SecurityUtils.getUserId());
        Date now = DateUtils.getNowDate();

        /* ====================== 3. 分情况处理 ====================== */

        // ---------- 情况一：全量移库 ----------
        if (newRkInfoId == null) {

            // 回滚库位
            origin.setCangku(record.getFromCangku());
            origin.setPcode(record.getFromPcode());
            origin.setTrayCode(record.getFromTrayCode());
            origin.setHasMoved("0");
            origin.setUpdateBy(userId);
            origin.setUpdateTime(now);

            rkInfoMapper.updateRkInfo(origin);
        }
        // ---------- 情况二：部分移库 ----------
        else {

            /* 3.1 原库存回补数量 */
            BigDecimal qty = record.getRealQty();
            if (qty == null || qty.compareTo(BigDecimal.ZERO) <= 0) {
                throw new ServiceException("移库数量异常，无法撤销");
            }

            origin.setRealQty(origin.getRealQty().add(qty));
            origin.setHasMoved("0");
            origin.setUpdateBy(userId);
            origin.setUpdateTime(now);
            origin.setHasMoved("0");

            rkInfoMapper.updateRkInfo(origin);

            /* 3.2 删除移库生成的新库存 */
            RkInfo newInfo = rkInfoMapper.selectRkInfoById(newRkInfoId);
            if (newInfo != null && !"1".equals(newInfo.getIsDelete())) {
                newInfo.setIsDelete("1");
                newInfo.setUpdateBy(userId);
                newInfo.setUpdateTime(now);
                rkInfoMapper.updateRkInfo(newInfo);
            }
        }

        /* ====================== 4. 标记移库记录已撤销 ====================== */
        record.setIsDelete("1");
        record.setUpdateBy(userId);
        record.setUpdateTime(now);
        moveRecordMapper.updateMoveRecord(record);
    }
}
