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

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.WornDeclareFile;
import com.shzg.project.worn.domain.WornDeclareItem;
import com.shzg.project.worn.mapper.WornDeclareFileMapper;
import com.shzg.project.worn.mapper.WornDeclareItemMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.shzg.project.worn.mapper.WornDeclareBillMapper;
import com.shzg.project.worn.domain.WornDeclareBill;
import com.shzg.project.worn.service.IWornDeclareBillService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 申报单查看Service业务层处理
 * 
 * @author shzg
 * @date 2026-04-14
 */
@Service
public class WornDeclareBillServiceImpl implements IWornDeclareBillService 
{
    @Autowired
    private WornDeclareBillMapper wornDeclareBillMapper;

    @Autowired
    private WornDeclareItemMapper wornDeclareItemMapper;

    @Autowired
    private WornDeclareFileMapper wornDeclareFileMapper;
    @Autowired
    private WornUniqueCodeMapper wornUniqueCodeMapper;
    @Autowired
    private WornUniqueCodeMaterialMapper wornUniqueCodeMaterialMapper;
    @Autowired
    private WornUniqueCodeEventMapper eventMapper;
    /**
     * 查询申报单查看
     * 
     * @param id 申报单查看主键
     * @return 申报单查看
     */
    @Override
    public WornDeclareBill selectWornDeclareBillById(Long id)
    {
        return wornDeclareBillMapper.selectWornDeclareBillById(id);
    }

    /**
     * 查询申报单查看列表
     * 
     * @param wornDeclareBill 申报单查看
     * @return 申报单查看
     */
    @Override
    public List<WornDeclareBill> selectWornDeclareBillList(WornDeclareBill wornDeclareBill)
    {
        return wornDeclareBillMapper.selectWornDeclareBillList(wornDeclareBill);
    }

    /**
     * 新增申报单查看
     * 
     * @param wornDeclareBill 申报单查看
     * @return 结果
     */
    /**
     * 新增申报单
     *
     * @param wornDeclareBill 申报单
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertWornDeclareBill(WornDeclareBill wornDeclareBill)
    {
        /* ================== 1. 参数校验 ================== */
        if (wornDeclareBill == null)
        {
            throw new RuntimeException("申报单参数不能为空");
        }
        if (StringUtils.isEmpty(wornDeclareBill.getContactName()))
        {
            throw new RuntimeException("联系人不能为空");
        }
        if (StringUtils.isEmpty(wornDeclareBill.getContactPhone()))
        {
            throw new RuntimeException("联系电话不能为空");
        }
        if (StringUtils.isEmpty(wornDeclareBill.getDeliveryTime()))
        {
            throw new RuntimeException("交付时间不能为空");
        }
        if (StringUtils.isEmpty(wornDeclareBill.getAddress()))
        {
            throw new RuntimeException("存放地址不能为空");
        }
        if (wornDeclareBill.getItemList() == null || wornDeclareBill.getItemList().isEmpty())
        {
            throw new RuntimeException("申报单明细不能为空");
        }

        /* ================== 2. 当前用户 ================== */
        Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
        Long deptId = SecurityUtils.getLoginUser().getUser().getDeptId();
        Date now = DateUtils.getNowDate();

        wornDeclareBill.setProjectId(deptId);

        /* ================== 3. 主表赋值 ================== */
        wornDeclareBill.setCreateTime(now);
        wornDeclareBill.setCreateBy(String.valueOf(userId));
        wornDeclareBill.setStatus("1");   // 1=已提交
        wornDeclareBill.setIsDelete("0");

        if (StringUtils.isEmpty(wornDeclareBill.getBillNo())){
            wornDeclareBill.setBillNo("DR" + System.currentTimeMillis());
        }

        /* ================== 4. 插入主表 ================== */
        int rows = wornDeclareBillMapper.insertWornDeclareBill(wornDeclareBill);
        if (rows <= 0){
            throw new RuntimeException("申报单新增失败");
        }

        Long billId = wornDeclareBill.getId();
        String billNo = wornDeclareBill.getBillNo();
        if (billId == null){
            throw new RuntimeException("申报单新增失败，ID未回填");
        }

        /* ================== 5. 插入明细 ================== */
        List<WornDeclareItem> itemList = wornDeclareBill.getItemList();
        for (WornDeclareItem item : itemList)
        {
            if (item == null)
            {
                continue;
            }

            item.setBillId(billId);
            item.setBillNo(billNo);
            item.setCreateTime(now);
            item.setCreateBy(String.valueOf(userId));
            item.setStatus("1"); // 1正常
            item.setIsDelete("0");

            int itemRows = wornDeclareItemMapper.insertWornDeclareItem(item);
            if (itemRows <= 0)
            {
                throw new RuntimeException("申报单明细新增失败");
            }
        }

        /* ================== 7. 插入附件 ================== */
        List<WornDeclareFile> fileList = wornDeclareBill.getFileList();
        if (fileList != null && !fileList.isEmpty()){
            Long sortNum = 1L;
            for (WornDeclareFile file : fileList){
                if (file == null || StringUtils.isEmpty(file.getUrl())){
                    continue;
                }

                file.setBillId(billId);
                file.setBillNo(billNo);
                file.setSortNum(sortNum++);
                file.setCreateBy(String.valueOf(userId));
                file.setCreateTime(now);
                file.setIsDelete("0");
                file.setFileUrl(file.getUrl());
                file.setFileName(file.getFileName());
                String fileType = "";

                if (StringUtils.isNotEmpty(file.getName()) && file.getName().contains(".")) {
                    fileType = file.getName().substring(file.getName().lastIndexOf(".") + 1).toLowerCase();
                }
                file.setFileType(fileType);
                int fileRows = wornDeclareFileMapper.insertWornDeclareFile(file);
                if (fileRows <= 0)
                {
                    throw new RuntimeException("申报单附件新增失败：" + file.getFileName());
                }
            }
        }

        return 1;
    }
    @Override
    public WornDeclareBill selectWornDeclareBillDetailByBillNo(String billNo)
    {
        if (StringUtils.isEmpty(billNo))
        {
            throw new RuntimeException("申报单号不能为空");
        }

        // 1. 查主表
        WornDeclareBill bill = wornDeclareBillMapper.selectWornDeclareBillByBillNo(billNo);
        if (bill == null)
        {
            throw new RuntimeException("申报单不存在");
        }

        // 2. 查明细
        List<WornDeclareItem> itemList = wornDeclareItemMapper.selectWornDeclareItemDetailByBillNo(billNo);
        bill.setItemList(itemList);

        // 3. 查附件
        List<WornDeclareFile> fileList = wornDeclareFileMapper.selectWornDeclareFileByBillId(bill.getId());
        bill.setFileList(fileList);

        return bill;
    }
    /**
     * 修改申报单查看
     * 
     * @param wornDeclareBill 申报单查看
     * @return 结果
     */
    /**
     * 修改申报单
     *
     * @param wornDeclareBill 申报单
     * @return 结果
     */
    /**
     * 修改申报单
     *
     * @param dto 申报单
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateWornDeclareBill(WornDeclareBill dto){
        /* ================== 1. 参数校验 ================== */
        if (dto == null)
        {
            throw new RuntimeException("申报单参数不能为空");
        }
        if (dto.getId() == null)
        {
            throw new RuntimeException("申报单ID不能为空");
        }
        if (StringUtils.isEmpty(dto.getBillNo()))
        {
            throw new RuntimeException("申报单号不能为空");
        }
        if (StringUtils.isEmpty(dto.getContactName()))
        {
            throw new RuntimeException("联系人不能为空");
        }
        if (StringUtils.isEmpty(dto.getContactPhone()))
        {
            throw new RuntimeException("联系电话不能为空");
        }
        if (StringUtils.isEmpty(dto.getDeliveryTime()))
        {
            throw new RuntimeException("交付时间不能为空");
        }
        if (StringUtils.isEmpty(dto.getAddress()))
        {
            throw new RuntimeException("存放地址不能为空");
        }

        /* ================== 2. 当前用户 ================== */
        Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
        Long deptId = SecurityUtils.getLoginUser().getUser().getDeptId();
        Date now = DateUtils.getNowDate();

        /* ================== 3. 查询原单 ================== */
        WornDeclareBill billUp = wornDeclareBillMapper.selectWornDeclareBillById(dto.getId());
        if (billUp == null)
        {
            throw new RuntimeException("申报单不存在");
        }

        /* ================== 4. 更新主表 ================== */
        billUp.setProjectId(deptId);
        billUp.setContactName(dto.getContactName());
        billUp.setContactPhone(dto.getContactPhone());
        billUp.setDeliveryTime(dto.getDeliveryTime());
        billUp.setAddress(dto.getAddress());
        billUp.setRemark(dto.getRemark());
        billUp.setUpdateBy(String.valueOf(userId));
        billUp.setUpdateTime(now);

        int rows = wornDeclareBillMapper.updateWornDeclareBill(billUp);
        if (rows <= 0)
        {
            throw new RuntimeException("申报单修改失败");
        }

        /* ================== 5. 更新 / 新增 / 删除明细 ================== */
        if (dto.getItemList() != null && !dto.getItemList().isEmpty()){
            for (WornDeclareItem itemDTO : dto.getItemList()){
                if (itemDTO == null){
                    continue;
                }

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

                            int deleteRows = wornDeclareItemMapper.updateWornDeclareItem(oldItem);
                            if (deleteRows <= 0)
                            {
                                throw new RuntimeException("申报单明细删除失败");
                            }

//                            // 删除时，如果有唯一码，再回滚
//                            if (oldItem.getUniqueCode() != null){
//                                rollbackDeclareUniqueCode(userId, oldItem.getUniqueCode().intValue(), now);
//                            }
                        }
                    }
                    continue;
                }

                // ===== 新增 =====
                if (itemDTO.getId() == null){
                    WornDeclareItem newItem = new WornDeclareItem();
                    newItem.setBillId(billUp.getId());
                    newItem.setBillNo(billUp.getBillNo());

                    newItem.setMaterialId(itemDTO.getMaterialId());
                    newItem.setMaterialName(itemDTO.getMaterialName());
                    newItem.setMaterialCode(itemDTO.getMaterialCode());
                    newItem.setMaterialShortName(itemDTO.getMaterialShortName());
                    newItem.setSpecification(itemDTO.getSpecification());
                    newItem.setModel(itemDTO.getModel());
                    newItem.setTypeName(itemDTO.getTypeName());
                    newItem.setTypeParentNames(itemDTO.getTypeParentNames());
                    newItem.setUniqueCode(itemDTO.getUniqueCode());
                    newItem.setQuantity(itemDTO.getQuantity());
                    newItem.setUnitId(itemDTO.getUnitId());
                    newItem.setUnitName(itemDTO.getUnitName());
                    newItem.setRemark(itemDTO.getRemark());

                    newItem.setStatus("1");
                    newItem.setIsDelete("0");
                    newItem.setCreateBy(String.valueOf(userId));
                    newItem.setCreateTime(now);

                    int itemRows = wornDeclareItemMapper.insertWornDeclareItem(newItem);
                    if (itemRows <= 0)
                    {
                        throw new RuntimeException("申报单明细新增失败");
                    }
                }else{
                    // ===== 修改 =====
                    WornDeclareItem oldItem = wornDeclareItemMapper.selectWornDeclareItemById(itemDTO.getId());
                    if (oldItem == null)
                    {
                        throw new RuntimeException("申报单明细不存在，ID：" + itemDTO.getId());
                    }
                    Integer newCode = 0;
                    if (itemDTO.getUniqueCode() !=null){
                        newCode = itemDTO.getUniqueCode().intValue();;

                    }
                    oldItem.setMaterialId(itemDTO.getMaterialId());
                    oldItem.setMaterialName(itemDTO.getMaterialName());
                    oldItem.setMaterialCode(itemDTO.getMaterialCode());
                    oldItem.setMaterialShortName(itemDTO.getMaterialShortName());
                    oldItem.setSpecification(itemDTO.getSpecification());
                    oldItem.setModel(itemDTO.getModel());
                    oldItem.setTypeName(itemDTO.getTypeName());
                    oldItem.setTypeParentNames(itemDTO.getTypeParentNames());
                    oldItem.setUniqueCode(newCode);
                    oldItem.setQuantity(itemDTO.getQuantity());
                    oldItem.setUnitId(itemDTO.getUnitId());
                    oldItem.setUnitName(itemDTO.getUnitName());
                    oldItem.setRemark(itemDTO.getRemark());
                    oldItem.setUpdateBy(String.valueOf(userId));
                    oldItem.setUpdateTime(now);

                    int itemRows = wornDeclareItemMapper.updateWornDeclareItem(oldItem);
                    if (itemRows <= 0)
                    {
                        throw new RuntimeException("申报单明细更新失败");
                    }
                }
            }
        }

        /* ================== 6. 处理附件 ================== */
        // 这里先简单处理：删旧附件再重插
        wornDeclareFileMapper.deleteWornDeclareFileByBillId(billUp.getId());

        List<WornDeclareFile> fileList = dto.getFileList();
        if (fileList != null && !fileList.isEmpty())
        {
            Long sortNum = 1L;
            for (WornDeclareFile file : fileList){
                if (file == null || StringUtils.isEmpty(file.getUrl()))
                {
                    continue;
                }

                if (StringUtils.isEmpty(file.getName()))
                {
                    file.setFileName("附件" + sortNum);
                }

                file.setBillId(billUp.getId());
                file.setBillNo(billUp.getBillNo());
                file.setSortNum(sortNum++);
                file.setCreateBy(String.valueOf(userId));
                file.setCreateTime(now);
                file.setIsDelete("0");
                file.setFileUrl(file.getUrl());
                int fileRows = wornDeclareFileMapper.insertWornDeclareFile(file);
                if (fileRows <= 0)
                {
                    throw new RuntimeException("申报单附件保存失败：" + file.getFileName());
                }
            }
        }

        return 1;
    }
//    private void handleDeclareUniqueCode(Long userId, WornDeclareItem item, Date now, String billNo)
//    {
//        if (item == null || item.getUniqueCode() == null)
//        {
//            return;
//        }
//
//        Integer code = item.getUniqueCode().intValue();
//
//        // 1. 查询唯一码是否存在
//        Long uniqueId = wornUniqueCodeMapper.selectIdByCode(code);
//        if (uniqueId == null)
//        {
//            throw new RuntimeException("唯一码不存在：" + code);
//        }
//
//        // 2. 同步唯一码物料表（保留）
//        WornUniqueCodeMaterial material = new WornUniqueCodeMaterial();
//        material.setUniqueCodeId(uniqueId);
//        material.setMaterialId(item.getMaterialId());
//
//        material.setQuantity(item.getQuantity());
//        material.setUnitId(item.getUnitId());
//        material.setRemark(item.getRemark());
//        material.setIsDelete("0");
//
//        WornUniqueCodeMaterial dbMaterial = wornUniqueCodeMaterialMapper.selectByUniqueCodeId(uniqueId);
//        if (dbMaterial == null)
//        {
//            material.setCreateBy(String.valueOf(userId));
//            material.setCreateTime(now);
//
//            int materialRows = wornUniqueCodeMaterialMapper.insertWornUniqueCodeMaterial(material);
//            if (materialRows <= 0)
//            {
//                throw new RuntimeException("唯一码物料表新增失败：" + code);
//            }
//        }
//        else
//        {
//            material.setId(dbMaterial.getId());
//            material.setUpdateBy(String.valueOf(userId));
//            material.setUpdateTime(now);
//
//            int materialRows = wornUniqueCodeMaterialMapper.updateWornUniqueCodeMaterial(material);
//            if (materialRows <= 0)
//            {
//                throw new RuntimeException("唯一码物料表更新失败：" + code);
//            }
//        }
//
//        // 3. 记录事件（保留）
//        WornUniqueCodeEvent event = new WornUniqueCodeEvent();
//        event.setUniqueCodeId(uniqueId);
//        event.setEventType("2"); // 这里你自己按事件字典调整，别和status混了
//        event.setEventStatus("1");
//        event.setEventDesc("生成/修改申报单：" + billNo);
//        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 rollbackDeclareUniqueCode(Long userId, Integer code, Date now)
//    {
//        if (code == null)
//        {
//            return;
//        }
//
////        // 1. 回滚唯一码状态
////        WornUniqueCode rollback = new WornUniqueCode();
////        rollback.setCode(code);
////        rollback.setStatus("0"); // 这里按你们实际状态改
////        rollback.setUpdateBy(String.valueOf(userId));
////        rollback.setUpdateTime(now);
////
////        int rollbackRows = wornUniqueCodeMapper.updateByCode(rollback);
////        if (rollbackRows <= 0)
////        {
////            throw new RuntimeException("唯一码状态回滚失败：" + code);
////        }
//
//        // 2. 唯一码物料表逻辑删除
//        Long uniqueId = wornUniqueCodeMapper.selectIdByCode(code);
//        if (uniqueId != null)
//        {
//            wornUniqueCodeMaterialMapper.deleteByUniqueCodeId(uniqueId);
//        }
//    }
//    /**
//     * 唯一码不变时，只同步唯一码物料表，不改唯一码状态
//     */
//    private void syncDeclareUniqueCodeMaterialByCode(Long userId, Integer code, WornDeclareItem item, Date now)
//    {
//        if (code == null || item == null)
//        {
//            return;
//        }
//
//        Long uniqueId = wornUniqueCodeMapper.selectIdByCode(code);
//        if (uniqueId == null)
//        {
//            throw new RuntimeException("唯一码不存在：" + code);
//        }
//
//        WornUniqueCodeMaterial dbMaterial = wornUniqueCodeMaterialMapper.selectByUniqueCodeId(uniqueId);
//        if (dbMaterial == null)
//        {
//            WornUniqueCodeMaterial material = new WornUniqueCodeMaterial();
//            material.setUniqueCodeId(uniqueId);
//            material.setMaterialId(item.getMaterialId());
//
//            material.setQuantity(item.getQuantity());
//            material.setUnitId(item.getUnitId());
//            material.setRemark(item.getRemark());
//            material.setCreateBy(String.valueOf(userId));
//            material.setCreateTime(now);
//            material.setIsDelete("0");
//
//            int rows = wornUniqueCodeMaterialMapper.insertWornUniqueCodeMaterial(material);
//            if (rows <= 0)
//            {
//                throw new RuntimeException("唯一码物料表新增失败：" + code);
//            }
//        }
//        else
//        {
//            WornUniqueCodeMaterial material = new WornUniqueCodeMaterial();
//            material.setId(dbMaterial.getId());
//            material.setUniqueCodeId(uniqueId);
//            material.setMaterialId(item.getMaterialId());
//
//            material.setQuantity(item.getQuantity());
//            material.setUnitId(item.getUnitId());
//            material.setRemark(item.getRemark());
//            material.setUpdateBy(String.valueOf(userId));
//            material.setUpdateTime(now);
//            material.setIsDelete("0");
//
//            int rows = wornUniqueCodeMaterialMapper.updateWornUniqueCodeMaterial(material);
//            if (rows <= 0)
//            {
//                throw new RuntimeException("唯一码物料表更新失败：" + code);
//            }
//        }
//    }
    /**
     * 批量删除申报单查看
     * 
     * @param ids 需要删除的申报单查看主键
     * @return 结果
     */
    @Override
    public int deleteWornDeclareBillByIds(Long[] ids)
    {
        return wornDeclareBillMapper.deleteWornDeclareBillByIds(ids);
    }

    /**
     * 删除申报单查看信息
     * 
     * @param id 申报单查看主键
     * @return 结果
     */
    @Override
    public int deleteWornDeclareBillById(Long id)
    {
        return wornDeclareBillMapper.deleteWornDeclareBillById(id);
    }
    /**
     * 作废申报单
     *
     * @param id 申报单ID
     * @return 结果
     */

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int cancelWornDeclareBill(Long id)
    {
        if (id == null)
        {
            throw new RuntimeException("申报单ID不能为空");
        }

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

        // 1. 查询主表
        WornDeclareBill bill = wornDeclareBillMapper.selectWornDeclareBillById(id);
        if (bill == null)
        {
            throw new RuntimeException("申报单不存在");
        }

        // 2. 重复作废校验
        if ("9".equals(bill.getStatus()))
        {
            throw new RuntimeException("申报单已作废，请勿重复操作");
        }

        // 3. 主表作废
        bill.setStatus("9");
        bill.setUpdateBy(String.valueOf(userId));
        bill.setUpdateTime(now);

        int billRows = wornDeclareBillMapper.cancelWornDeclareBill(bill);
        if (billRows <= 0)
        {
            throw new RuntimeException("申报单作废失败");
        }

        // 4. 明细作废
        wornDeclareItemMapper.cancelWornDeclareItemByBillId(
                id,
                String.valueOf(userId),
                now
        );

        return 1;
    }
}
