package com.microservices.pms.product.service.impl;

import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.utils.DateUtils;
import com.microservices.common.core.utils.PageUtils;
import com.microservices.common.core.web.page.GenericsTableDataInfo;
import com.microservices.common.security.utils.SecurityUtils;
import com.microservices.pms.product.domain.PmsProduct;
import com.microservices.pms.product.domain.PmsProductPlan;
import com.microservices.pms.product.domain.vo.PmsProductPlanDataVo;
import com.microservices.pms.product.mapper.PmsProductPlanMapper;
import com.microservices.pms.product.service.*;
import com.microservices.pms.utils.PmsConstants;
import com.microservices.pms.utils.PmsUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;

/**
 * 产品计划Service业务层处理
 *
 * @author microservices
 * @date 2023-10-10
 */
@Service
public class PmsProductPlanServiceImpl implements IPmsProductPlanService {
    @Autowired
    private PmsProductPlanMapper pmsProductPlanMapper;
    @Autowired
    private IPmsProductPriorityService pmsProductPriorityService;
    @Autowired
    private IPmsProductStatusService pmsProductStatusService;
    @Autowired
    private IPmsProductService pmsProductService;
    @Autowired
    @Lazy
    private IPmsProductRequirementService pmsProductRequirementService;

    /**
     * 查询产品计划
     *
     * @param id        产品计划主键
     * @param checkRole 是否校验角色（仅允许组织管理员和产品负责人操作当前产品）
     * @return 产品计划
     */
    @Override
    public PmsProductPlan selectPmsProductPlanById(Long id, boolean checkRole) {
        PmsProductPlan pmsProductPlan = pmsProductPlanMapper.selectPmsProductPlanById(id);
        if (pmsProductPlan == null) {
            throw new ServiceException("该产品计划不存在(产品计划Id[%d])", id);
        }
        PmsProduct pmsProduct = pmsProductService.selectPmsProductByIdentifier(pmsProductPlan.getPmsProductIdentifier());
        if (checkRole) {
            pmsProductService.checkManageRole(pmsProduct);
        }
        return pmsProductPlan;
    }

    /**
     * 查询产品计划列表
     *
     * @param pmsProductPlan 产品计划
     * @return 产品计划
     */
    @Override
    public GenericsTableDataInfo<PmsProductPlanDataVo> selectPmsProductPlanList(PmsProductPlan pmsProductPlan) {
        pmsProductService.selectPmsProductByIdentifier(pmsProductPlan.getPmsProductIdentifier());

        HashMap<String, Object> selectCache = new HashMap<>();
        PageUtils.startPage();
        return PageUtils.toPage(pmsProductPlanMapper.selectPmsProductPlanList(pmsProductPlan), x -> toPmsProductPlanDataVo(x, selectCache));
    }

    /**
     * 新增产品计划
     *
     * @param pmsProductPlan 产品计划
     * @return 结果
     */
    @Override
    public Long insertPmsProductPlan(PmsProductPlan pmsProductPlan) {
        // 校验产品是否存在
        PmsProduct pmsProduct = pmsProductService.selectPmsProductByIdentifier(pmsProductPlan.getPmsProductIdentifier());
        pmsProductService.checkManageRole(pmsProduct);
        // 设置产品计划优先级，若未传入则设置为默认优先级
        Long priorityId =
                pmsProductPriorityService.selectPmsProductPriorityIdByInputId(pmsProductPlan.getPriorityId(), PmsConstants.PRODUCT_STATUS_OR_PRIORITY_PLAN_TYPE);
        pmsProductPlan.setPriorityId(priorityId);
        checkProductPlan(pmsProductPlan);
        if (pmsProductPlan.getStartTime() == null || pmsProductPlan.getEndTime() == null) {
            throw new ServiceException("产品计划的开始时间和结束时间不能为空");
        }
        // 设置产品计划状态
        Long statusId =
                pmsProductStatusService.selectPmsProductPlanStatusByDateOrStatusId(pmsProductPlan.getStartTime(), pmsProductPlan.getEndTime(), null, null, pmsProductPlan.getStatusId(), null);
        pmsProductPlan.setStatusId(statusId);

        Date now = DateUtils.getNowDate();
        String currentUsername = SecurityUtils.getUsername();
        pmsProductPlan.setCreateBy(currentUsername);
        pmsProductPlan.setCreateTime(now);
        pmsProductPlan.setUpdateBy(currentUsername);
        pmsProductPlan.setUpdateTime(now);
        pmsProductService.updatePmsProductChange(pmsProductPlan.getPmsProductIdentifier());
        pmsProductPlanMapper.insertPmsProductPlan(pmsProductPlan);
        return pmsProductPlan.getId();
    }

    private void checkProductPlan(PmsProductPlan pmsProductPlan) {
        //校验结束时间需大于开始时间
        if (pmsProductPlan.getStartTime() != null && pmsProductPlan.getEndTime() != null) {
            if (pmsProductPlan.getStartTime().after(pmsProductPlan.getEndTime())) {
                throw new ServiceException("结束时间不能早于开始时间");
            }
        }
    }

    /**
     * 修改产品计划
     *
     * @param pmsProductPlan 产品计划
     * @return 结果
     */
    @Override
    public int updatePmsProductPlan(PmsProductPlan pmsProductPlan) {
        // 通过id检查需修改的产品计划是否存在
        PmsProductPlan oldPmsProductPlan = selectPmsProductPlanById(pmsProductPlan.getId(), true);
        if (pmsProductPlan.getPriorityId() != null) {
            // 设置产品计划优先级
            Long priorityId =
                    pmsProductPriorityService.selectPmsProductPriorityIdByInputId(pmsProductPlan.getPriorityId(), PmsConstants.PRODUCT_STATUS_OR_PRIORITY_PLAN_TYPE);
            pmsProductPlan.setPriorityId(priorityId);
        }
        if (pmsProductPlan.getStartTime() != null && pmsProductPlan.getEndTime() == null) {
            if (pmsProductPlan.getStartTime().after(oldPmsProductPlan.getEndTime())) {
                throw new ServiceException("开始时间不能晚于结束时间");
            }
        }
        if (pmsProductPlan.getStartTime() == null && pmsProductPlan.getEndTime() != null) {
            if (oldPmsProductPlan.getStartTime().after(pmsProductPlan.getEndTime())) {
                throw new ServiceException("结束时间不能早于开始时间");
            }
        }
        // 设置产品计划状态
        Long statusId =
                pmsProductStatusService.selectPmsProductPlanStatusByDateOrStatusId(
                        pmsProductPlan.getStartTime(), pmsProductPlan.getEndTime(), oldPmsProductPlan.getStartTime(), oldPmsProductPlan.getEndTime(), pmsProductPlan.getStatusId(), oldPmsProductPlan.getStatusId());
        pmsProductPlan.setStatusId(statusId);
        checkProductPlan(pmsProductPlan);

        pmsProductPlan.setUpdateBy(SecurityUtils.getUsername());
        pmsProductPlan.setUpdateTime(DateUtils.getNowDate());
        pmsProductService.updatePmsProductChange(oldPmsProductPlan.getPmsProductIdentifier());
        return pmsProductPlanMapper.updatePmsProductPlan(pmsProductPlan);
    }

    @Override
    public int updatePmsProductPlanChange(Long id) {
        PmsProductPlan oldPmsProductPlan = selectPmsProductPlanById(id, false);
        oldPmsProductPlan.setUpdateBy(SecurityUtils.getUsername());
        oldPmsProductPlan.setUpdateTime(DateUtils.getNowDate());
        pmsProductService.updatePmsProductChange(oldPmsProductPlan.getPmsProductIdentifier());
        return pmsProductPlanMapper.updatePmsProductPlan(oldPmsProductPlan);
    }

    /**
     * 批量删除产品计划
     *
     * @param ids 需要删除的产品计划主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deletePmsProductPlanByIds(Long[] ids) {
        int success = 0;
        for (Long id : ids) {
            success += deletePmsProductPlanById(id);
        }
        return success;
    }

    /**
     * 删除产品计划信息
     *
     * @param id 产品计划主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deletePmsProductPlanById(Long id) {
        PmsProductPlan oldPmsProductPlan = selectPmsProductPlanById(id, true);
        pmsProductRequirementService.updatePmsProductRequirementNoPlanByPlanId(id);
        pmsProductService.updatePmsProductChange(oldPmsProductPlan.getPmsProductIdentifier());
        return pmsProductPlanMapper.deletePmsProductPlanById(id);
    }

    @Override
    public PmsProductPlanDataVo selectPmsProductPlanDataById(Long id) {
        PmsProductPlan pmsProductPlan = selectPmsProductPlanById(id, false);
        return toPmsProductPlanDataVo(pmsProductPlan, null);
    }

    @Override
    public Integer selectPmsProductPlanCount(PmsProductPlan pmsProductPlan) {
        return pmsProductPlanMapper.selectPmsProductPlanCount(pmsProductPlan);
    }

    @Override
    public void deletePmsProductPlanByProductIdentifier(String productIdentifier) {
        pmsProductPlanMapper.deletePmsProductPlanByProductIdentifier(productIdentifier);
    }

    private PmsProductPlanDataVo toPmsProductPlanDataVo(PmsProductPlan pmsProductPlan, HashMap<String, Object> hashMap) {
        PmsProductPlanDataVo pmsProductPlanDataVo = pmsProductPlan.toPmsProductPlanDataVo();
        // 设置优先级
        pmsProductPlanDataVo.setPriority(
                PmsUtils.getSelectObjectInCache(
                        hashMap
                        , pmsProductPriorityService::selectPmsProductPriorityById
                        , pmsProductPlan.getPriorityId()));
        // 设置状态
        pmsProductPlanDataVo.setStatus(
                PmsUtils.getSelectObjectInCache(
                        hashMap
                        , pmsProductStatusService::selectPmsProductStatusById
                        , pmsProductPlan.getStatusId()));
        // 设置产品
        pmsProductPlanDataVo.setPmsProduct(
                PmsUtils.getSelectObjectInCache(
                        hashMap
                        , pmsProductService::selectPmsProductByIdentifier
                        , pmsProductPlan.getPmsProductIdentifier()));
        return pmsProductPlanDataVo;
    }
}
