package com.shzg.project.worn.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.shzg.common.utils.DateUtils;
import com.shzg.common.utils.SecurityUtils;
import com.shzg.common.utils.StringUtils;
import com.shzg.project.unique.domain.WornUniqueCode;
import com.shzg.project.unique.domain.WornUniqueCodeEvent;
import com.shzg.project.unique.domain.WornUniqueCodeMaterial;
import com.shzg.project.unique.mapper.WornUniqueCodeEventMapper;
import com.shzg.project.unique.mapper.WornUniqueCodeMapper;
import com.shzg.project.unique.mapper.WornUniqueCodeMaterialMapper;
import com.shzg.project.worn.domain.WornInboundBill;
import com.shzg.project.worn.domain.WornMaterial;
import com.shzg.project.worn.domain.dto.WornInboundItemDTO;
import com.shzg.project.worn.domain.dto.WornInboundUpdateDTO;
import com.shzg.project.worn.mapper.WornInboundBillMapper;
import com.shzg.project.worn.service.IWornMaterialService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.shzg.project.worn.mapper.WornInboundItemMapper;
import com.shzg.project.worn.domain.WornInboundItem;
import com.shzg.project.worn.service.IWornInboundItemService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 入库单明细Service业务层处理
 * 
 * @author shzg
 * @date 2026-03-26
 */
@Service
public class WornInboundItemServiceImpl implements IWornInboundItemService 
{
    @Autowired
    private WornInboundItemMapper wornInboundItemMapper;
    @Autowired
    private IWornMaterialService wornMaterialService;
    @Autowired
    private WornUniqueCodeMapper wornUniqueCodeMapper;
    @Autowired
    private WornUniqueCodeEventMapper eventMapper;
    @Autowired
    private WornInboundBillMapper wornInboundBillMapper;
    @Autowired
    private WornUniqueCodeMaterialMapper wornUniqueCodeMaterialMapper;
    /**
     * 查询入库单明细
     * 
     * @param id 入库单明细主键
     * @return 入库单明细
     */
    @Override
    public WornInboundItem selectWornInboundItemById(Long id)
    {
        return wornInboundItemMapper.selectWornInboundItemById(id);
    }

    /**
     * 查询入库单明细列表
     * 
     * @param wornInboundItem 入库单明细
     * @return 入库单明细
     */
    @Override
    public WornInboundUpdateDTO  selectWornInboundItemByBillNo(WornInboundItem wornInboundItem)
    {
        String billNo = wornInboundItem.getBillNo();
        if (billNo == null || "".equals(billNo.trim()))
        {
            return null;
        }

        // 1. 查询明细列表
        WornInboundItem param = new WornInboundItem();
        param.setBillNo(billNo);

        List<WornInboundItem> itemList = wornInboundItemMapper.selectWornInboundItemList(param);

        if (itemList == null || itemList.isEmpty())
        {
            return null;
        }

        // 2. 取第一条作为主数据（bill信息）
        WornInboundItem first = itemList.get(0);

        // 3. 构建 DTO
        WornInboundUpdateDTO dto = new WornInboundUpdateDTO();
        dto.setBillId(first.getBillId());
        dto.setBillNo(first.getBillNo());
        dto.setBillType(first.getBillType());
        dto.setWarehouseCode(first.getWarehouseCode());
        dto.setWarehouseName(first.getWarehouseName());
        dto.setAreaCode(first.getAreaCode());
        dto.setAreaName(first.getAreaName());
        dto.setBillRemark(first.getBillRemark());
        dto.setInboundTime(first.getInboundTime());
        dto.setStatus(first.getBillStatus());
        dto.setCreateTime(first.getCreateTime());

        List<WornInboundItemDTO> dtoList = new ArrayList<>();

        // 4. 组装明细
        for (WornInboundItem item : itemList)
        {
            WornInboundItemDTO itemDTO = new WornInboundItemDTO();

            itemDTO.setId(item.getId());
            itemDTO.setMaterialId(item.getMaterialId());
            itemDTO.setMaterialName(item.getMaterialName());
            itemDTO.setMaterialCode(item.getMaterialCode());
            itemDTO.setMaterialShortName(item.getMaterialShortName());
            itemDTO.setModel(item.getModel());
            itemDTO.setSpecification(item.getSpecification());
            itemDTO.setTypeName(item.getTypeName());
            itemDTO.setQuantity(item.getQuantity());
            itemDTO.setRemark(item.getRemark());
            itemDTO.setUniqueCode(item.getUniqueCode());
            itemDTO.setIsDelete(StringUtils.isEmpty(item.getIsDelete()) ? "0" : item.getIsDelete());
            itemDTO.setTypeParentNames(item.getTypeParentNames());
            itemDTO.setUnitId(item.getUnitId());
            itemDTO.setUnitName(item.getUnitName());
            itemDTO.setStatus(item.getStatus());
            dtoList.add(itemDTO);
        }

        dto.setItemList(dtoList);

        return dto;
    }

    /**
     * 新增入库单明细
     * 
     * @param wornInboundItem 入库单明细
     * @return 结果
     */
    @Override
    public int insertWornInboundItem(WornInboundItem wornInboundItem)
    {
        wornInboundItem.setCreateTime(DateUtils.getNowDate());
        return wornInboundItemMapper.insertWornInboundItem(wornInboundItem);
    }

    /**
     * 修改入库单明细
     * 
     * @param dto 入库单明细
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateWornInboundItem(WornInboundUpdateDTO dto ) {
        if (dto == null) {
            throw new RuntimeException("入库单参数不能为空");
        }

        Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
        Date now = DateUtils.getNowDate();

        // 1. 更新主表
        WornInboundBill bill = new WornInboundBill();
        bill.setBillNo(dto.getBillNo());
        bill.setWarehouseCode(dto.getWarehouseCode());
        bill.setWarehouseName(dto.getWarehouseName());
        bill.setAreaCode(dto.getAreaCode());
        bill.setAreaName(dto.getAreaName());
        bill.setRemark(dto.getBillRemark());
//        bill.setBillType(dto.getBillType());
        bill.setInboundTime(dto.getInboundTime());
        bill.setStatus("0");
        bill.setUpdateBy(String.valueOf(userId));
        bill.setUpdateTime(now);

        int billRows = wornInboundBillMapper.updateWornInboundBill(bill);
        if (billRows <= 0){
            throw new RuntimeException("入库单更新失败");
        }

        WornInboundBill billUp = wornInboundBillMapper.selectWornInboundBillByBillNo(dto.getBillNo());
        // 2. 更新 / 新增 / 删除明细
        if (dto.getItemList() != null && !dto.getItemList().isEmpty()){
            for (WornInboundItemDTO itemDTO : dto.getItemList()){
                if (itemDTO == null){
                    continue;
                }

                // 删除
                if ("1".equals(itemDTO.getIsDelete())){
                    if (itemDTO.getId() != null){
                        WornInboundItem oldItem = wornInboundItemMapper.selectWornInboundItemById(itemDTO.getId());
                        if (oldItem != null){
                            oldItem.setIsDelete("1");
                            oldItem.setUpdateBy(String.valueOf(userId));
                            oldItem.setUpdateTime(now);

                            int deleteRows = wornInboundItemMapper.updateWornInboundItem(oldItem);
                            if (deleteRows <= 0){
                                throw new RuntimeException("入库明细删除失败");
                            }

                            if (oldItem.getUniqueCode() != null){
                                rollbackUniqueCode(userId, oldItem.getUniqueCode(), now);
                            }
                        }
                    }
                    continue;
                }

                // 新增
                if (itemDTO.getId() == null){
                    WornInboundItem newItem = new WornInboundItem();
                    newItem.setBillId(billUp.getId());
                    newItem.setBillNo(dto.getBillNo());
                    newItem.setMaterialId(itemDTO.getMaterialId());
                    newItem.setQuantity(itemDTO.getQuantity());
                    newItem.setRemark(itemDTO.getRemark());
                    newItem.setUniqueCode(itemDTO.getUniqueCode());
                    newItem.setIsDelete("0");
                    newItem.setCreateBy(String.valueOf(userId));
                    newItem.setCreateTime(now);

                    int itemRows = wornInboundItemMapper.insertWornInboundItem(newItem);
                    if (itemRows <= 0)
                    {
                        throw new RuntimeException("入库明细新增失败");
                    }

                    if (newItem.getUniqueCode() != null)
                    {
                        handleUniqueCodeIn(userId, newItem.getUniqueCode(), now);
                    }
                }else{
                    // 更新
                    WornInboundItem oldItem = wornInboundItemMapper.selectWornInboundItemById(itemDTO.getId());
                    if (oldItem == null)
                    {
                        throw new RuntimeException("入库明细不存在，ID：" + itemDTO.getId());
                    }

                    Integer oldCode = oldItem.getUniqueCode();
                    Integer newCode = itemDTO.getUniqueCode();

                    oldItem.setMaterialId(itemDTO.getMaterialId());
                    oldItem.setQuantity(itemDTO.getQuantity());
                    oldItem.setRemark(itemDTO.getRemark());
                    oldItem.setUniqueCode(newCode);
//                    oldItem.setUpdateBy(String.valueOf(userId));
//                    oldItem.setUpdateTime(now);

                    int itemRows = wornInboundItemMapper.updateWornInboundItem(oldItem);
                    if (itemRows <= 0)
                    {
                        throw new RuntimeException("入库明细更新失败");
                    }
                    //唯一码物料表更改
                    WornUniqueCode wornUniqueCode = new WornUniqueCode();
                    wornUniqueCode.setCode(oldCode);
                    List<WornUniqueCode> list = wornUniqueCodeMapper.selectWornUniqueCodeList(wornUniqueCode);
                    if (list != null && list.size() > 0){
                        //一个唯一码只有一条
                        Long uniqueCodeId = list.get(0).getId();
                        WornUniqueCodeMaterial wornUniqueCodeMaterial = new WornUniqueCodeMaterial();
                        wornUniqueCodeMaterial.setUniqueCodeId(uniqueCodeId);
                        wornUniqueCodeMaterial.setQuantity(itemDTO.getQuantity());
                        wornUniqueCodeMaterial.setRemark(itemDTO.getRemark());
                        int uniqueRow = wornUniqueCodeMaterialMapper.updateWornUniqueCodeMaterial(wornUniqueCodeMaterial);
                    }
                    // 唯一码变更处理
                    if (oldCode != null && !oldCode.equals(newCode)){
                        rollbackUniqueCode(userId, oldCode, now);
                    }
                    if (newCode != null && !newCode.equals(oldCode)){
                        handleUniqueCodeIn(userId, newCode, now);
                    }
                }
            }
        }

        return 1;
    }



/**
 * 唯一码入库联动
 */
private void handleUniqueCodeIn(Long userId, Integer code, Date now)
{
    Long uniqueId = wornUniqueCodeMapper.selectIdByCode(code);
    if (uniqueId == null)
    {
        throw new RuntimeException("唯一码不存在：" + code + "，请添加唯一码");
    }

    WornUniqueCode update = new WornUniqueCode();
    update.setCode(code);
    update.setStatus("1");
    update.setUpdateBy(String.valueOf(userId));
    update.setUpdateTime(now);

    int updateRows = wornUniqueCodeMapper.updateByCode(update);
    if (updateRows <= 0)
    {
        throw new RuntimeException("唯一码状态更新失败：" + code);
    }

    WornUniqueCodeEvent event = new WornUniqueCodeEvent();
    event.setUniqueCodeId(uniqueId);
    event.setEventType("1");
    event.setEventStatus("1");
    event.setEventDesc("入库单入库");
    event.setOperatorId(userId);
    event.setCreateBy(String.valueOf(userId));
    event.setCreateTime(now);
    event.setIsDelete("0");

    int eventRows = eventMapper.insertWornUniqueCodeEvent(event);
    if (eventRows <= 0)
    {
        throw new RuntimeException("唯一码事件记录失败：" + code);
    }
}

/**
 * 唯一码回退
 */
private void rollbackUniqueCode(Long userId, Integer code, Date now)
{
    WornUniqueCode update = new WornUniqueCode();
    update.setCode(code);
    update.setStatus("0");
    update.setUpdateBy(String.valueOf(userId));
    update.setUpdateTime(now);

    int updateRows = wornUniqueCodeMapper.updateByCode(update);
    if (updateRows <= 0)
    {
        throw new RuntimeException("唯一码状态回退失败：" + code);
    }
}
    /**
     * 批量删除入库单明细
     * 
     * @param ids 需要删除的入库单明细主键
     * @return 结果
     */
    @Override
    public int deleteWornInboundItemByIds(Long[] ids)
    {
        return wornInboundItemMapper.deleteWornInboundItemByIds(ids);
    }

    /**
     * 删除入库单明细信息
     * 
     * @param id 入库单明细主键
     * @return 结果
     */
    @Override
    public int deleteWornInboundItemById(Long id)
    {
        return wornInboundItemMapper.deleteWornInboundItemById(id);
    }
}
