package com.ruoyi.oa.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.BeanCopyUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.oa.domain.SysOaWarehouse;
import com.ruoyi.oa.domain.SysOaWarehouseDetail;
import com.ruoyi.oa.domain.bo.SysOaWarehouseBo;
import com.ruoyi.oa.domain.bo.SysOaWarehouseDetailBo;
import com.ruoyi.oa.domain.vo.SysOaWarehouseDetailVo;
import com.ruoyi.oa.domain.vo.SysOaWarehouseVo;
import com.ruoyi.oa.mapper.SysOaWarehouseDetailMapper;
import com.ruoyi.oa.mapper.SysOaWarehouseMapper;
import com.ruoyi.oa.service.ISysOaWarehouseDetailService;
import com.ruoyi.oa.service.ISysOaWarehouseService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.oa.domain.bo.SysOaWarehouseMasterBo;
import com.ruoyi.oa.domain.vo.SysOaWarehouseMasterVo;
import com.ruoyi.oa.domain.SysOaWarehouseMaster;
import com.ruoyi.oa.mapper.SysOaWarehouseMasterMapper;
import com.ruoyi.oa.service.ISysOaWarehouseMasterService;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import static cn.hutool.core.bean.BeanUtil.toBean;

/**
 * 出库单管理Service业务层处理
 *
 * @author hdak
 * @date 2025-03-19
 */
@RequiredArgsConstructor
@Service
public class SysOaWarehouseMasterServiceImpl implements ISysOaWarehouseMasterService {

    private final SysOaWarehouseMasterMapper baseMapper;

    private final ISysOaWarehouseDetailService warehouseDetailService;

    @Autowired
    private SysOaWarehouseMapper warehouseMapper;


    /**
     * 查询出库单管理
     */
    @Override
    public SysOaWarehouseMasterVo queryById(Long masterId) {
        return baseMapper.selectVoById(masterId);
    }

    /**
     * 查询出库单管理列表
     */
    @Override
    public TableDataInfo<SysOaWarehouseMasterVo> queryPageList(SysOaWarehouseMasterBo bo, PageQuery pageQuery) {
        QueryWrapper<SysOaWarehouseMaster> lqw = buildQueryWrapper(bo);
        Page<SysOaWarehouseMasterVo> result = baseMapper.selectVoPagePlus(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询出库单管理列表
     */
    @Override
    public List<SysOaWarehouseMasterVo> queryList(SysOaWarehouseMasterBo bo) {
        QueryWrapper<SysOaWarehouseMaster> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private QueryWrapper<SysOaWarehouseMaster> buildQueryWrapper(SysOaWarehouseMasterBo bo) {
        Map<String, Object> params = bo.getParams();
        QueryWrapper<SysOaWarehouseMaster> lqw = Wrappers.query();
        lqw.eq(bo.getType()    != null, "sowm.type",       bo.getType())
                .eq(bo.getProjectId()!= null, "sowm.project_id", bo.getProjectId())
                // 其他过滤……
                .eq("sowm.del_flag",     0)
                .orderByDesc("sowm.create_time");

      // 只有在 type = 2 时，才附带这个子查询字段
        if (bo.getType()    != null && bo.getType() == 2L) {
            lqw.select(
                    "sowm.*",   // 先选出主表所有列
                    // 然后选出子查询，重命名为 nearest_end_time（实体上需要有对应的 @TableField(exist = false) 字段）
                    "(SELECT COALESCE(\n" +
                            "    MIN(CASE WHEN sowt.end_time > NOW() THEN sowt.end_time END),\n" +
                            "    MAX(CASE WHEN sowt.end_time <= NOW() THEN sowt.end_time END)\n" +
                            ")\n" +
                            "FROM sys_oa_warehouse_task sowt\n" +
                            "WHERE sowt.master_id = sowm.master_id\n" +
                            "  AND sowt.task_status IN (0,1)\n" +
                            ") AS nearest_end_time"
            );
        } else {
            // 否则只选主表列
            lqw.select("sowm.*");
        }

        return lqw;
    }

    /**
     * 新增单管理
     */
    @Override
    public Boolean insertByBo(SysOaWarehouseMasterBo bo) {

        SysOaWarehouseMaster add = BeanUtil.toBean(bo, SysOaWarehouseMaster.class);
        validEntityBeforeSave(add);
        add.setSignUser(LoginHelper.getNickName());
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            // 单子新增后 新增出库元素同时减去现有的，这里要记录一个出库时单价
            for (SysOaWarehouseDetailBo sysOaWarehouseDetailBo : bo.getWarehouseList()) {
                sysOaWarehouseDetailBo.setMasterId(add.getMasterId());
                sysOaWarehouseDetailBo.setType(bo.getType());
                warehouseDetailService.insertByBo(sysOaWarehouseDetailBo);
            }
        }
        return flag;
    }

    /**
     * 修改出库单管理
     */
    @Override
    public Boolean updateByBo(SysOaWarehouseMasterBo bo) {

        // 判断是否为采购单，采购单，用户是直接点击完成按钮，所以直接更新单子状态就可以
        if (bo.getType() != 2L) {
            SysOaWarehouseMaster update = BeanUtil.toBean(bo, SysOaWarehouseMaster.class);
            validEntityBeforeSave(update);
            boolean flag = baseMapper.updateById(update) > 0;
            if (flag) {
                List<SysOaWarehouseDetailBo> warehouseList = bo.getWarehouseList();
                for (SysOaWarehouseDetailBo sysOaWarehouseDetailBo : warehouseList) {
                    sysOaWarehouseDetailBo.setMasterId(bo.getMasterId());
                    sysOaWarehouseDetailBo.setType(bo.getType());
                    warehouseDetailService.insertByBo(sysOaWarehouseDetailBo);
                }
            }

            return flag;
        } else {

            SysOaWarehouseMaster update = BeanUtil.toBean(bo, SysOaWarehouseMaster.class);
            validEntityBeforeSave(update);
            return baseMapper.updateById(update) > 0;
        }

    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(SysOaWarehouseMaster entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除出库单管理
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public int insertInWarehouse(SysOaWarehouseBo bo, Long id) {
        SysOaWarehouseMaster sysOaWarehouseMaster = new SysOaWarehouseMaster();
        sysOaWarehouseMaster.setMasterNum(UUID.randomUUID().toString());
        sysOaWarehouseMaster.setRemark(bo.getRemark());
        sysOaWarehouseMaster.setCreateBy(LoginHelper.getNickName());
        sysOaWarehouseMaster.setUpdateBy(LoginHelper.getNickName());
        sysOaWarehouseMaster.setSignTime(new Date());
        sysOaWarehouseMaster.setSignUser(LoginHelper.getNickName());
        sysOaWarehouseMaster.setType(1L);
        int flag = baseMapper.insert(sysOaWarehouseMaster);
        SysOaWarehouseDetailBo sysOaWarehouseDetailBo = new SysOaWarehouseDetailBo();
        sysOaWarehouseDetailBo.setWarehouseId(bo.getId());
        sysOaWarehouseDetailBo.setAmount(bo.getInventory());
        sysOaWarehouseDetailBo.setSignPrice(bo.getPrice());
        sysOaWarehouseDetailBo.setCreateBy(LoginHelper.getNickName());
        sysOaWarehouseDetailBo.setUpdateBy(LoginHelper.getNickName());
        sysOaWarehouseDetailBo.setMasterId(sysOaWarehouseMaster.getMasterId());
        sysOaWarehouseDetailBo.setType(sysOaWarehouseMaster.getType());
        sysOaWarehouseDetailBo.setWarehouseId(id);
        warehouseDetailService.insertByBo(sysOaWarehouseDetailBo);

        return flag;
    }

    @Override
    public int updateMasterAndInsertBatchWare(SysOaWarehouseMasterBo bo) {
        // 判断是否为采购单，采购单，用户是直接点击完成按钮，所以直接更新单子状态就可以


        if (bo.getType() == 2L) {
            SysOaWarehouseMaster update = BeanUtil.toBean(bo, SysOaWarehouseMaster.class);
            validEntityBeforeSave(update);
            int flag =  baseMapper.updateById(update);
            bo.getWarehouseList().forEach(warehouse -> {

            });
            // 判断是否为采购单，采购单，用户是直接点击完成按钮，所以直接更新单子状态就可以
            // 我认为首先要先判断是否已经有此单子的入库单 如果有的话应该直接根据入库单id从而将其他的新增进去就可以了

            return flag;

        }


        // 如果不是2应该进不来
         return 0;

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int redoMaster(Long masterId) {
        SysOaWarehouseDetailBo sysOaWarehouseDetailBo = new SysOaWarehouseDetailBo();
        sysOaWarehouseDetailBo.setMasterId(masterId);
        List<SysOaWarehouseDetailVo> sysOaWarehouseDetailVos = warehouseDetailService.queryList(sysOaWarehouseDetailBo);
        for (SysOaWarehouseDetailVo sysOaWarehouseDetailVo : sysOaWarehouseDetailVos) {
            SysOaWarehouseVo sysOaWarehouseVo = warehouseMapper.selectVoById(sysOaWarehouseDetailVo.getWarehouseId());
            // 拿到原有的物料
            if (sysOaWarehouseVo != null) {
                // 如果还存在此物料就把库存恢复  然后把价格加权计算
                Long newInventory = sysOaWarehouseDetailVo.getAmount()+sysOaWarehouseVo.getInventory();
                Double newPrice = (sysOaWarehouseDetailVo.getSignPrice()*sysOaWarehouseDetailVo.getAmount()+sysOaWarehouseVo.getPrice()*sysOaWarehouseVo.getInventory())/(newInventory);
                sysOaWarehouseVo.setPrice(newPrice);
                sysOaWarehouseVo.setInventory(newInventory);
                warehouseMapper.updateById(sysOaWarehouseVo);
            }
            warehouseDetailService.deleteById(sysOaWarehouseDetailVo.getId());
        }
        // 全部做完之后删除此出库单

        return  baseMapper.deleteById(masterId);
    }
}
