package com.dayou.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.dayou.common.BaseEntity;
import com.dayou.dto.*;
import com.dayou.entity.*;
import com.dayou.exception.ErrorCode;
import com.dayou.mapper.AssetsProductionMapper;
import com.dayou.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;

import org.springframework.transaction.annotation.Transactional;

import static com.dayou.enums.MainBusinessEnum.ASSET_BUSINESS;
import static com.dayou.enums.ProductionEnum.STATEMENT;

/**
 * <p>
 * 资产产品表 服务实现类
 * </p>
 *
 * @author GouGengquan
 * @since 2024-03-28
 */
@Service
public class AssetsProductionServiceImpl extends ServiceImpl<AssetsProductionMapper, AssetsProduction> implements IAssetsProductionService {

    @Autowired
    private AssetsProductionMapper assetsProductionMapper;

    @Autowired
    private IAssetsService assetsService;

    @Autowired
    private IBusinessProductionService businessProductionService;

    @Autowired
    private IOrderFundService orderFundService;

    @Autowired
    private IProductionOutWarehouseService productionOutWarehouseService;

    @Autowired
    private IProductionFundService productionFundService;

    /**
     * 根据资产业务id查询资产业务产品
     *
     * @param id 资产业务id
     * @return List<AssetsProduction>
     */
    @Override
    public List<AssetsProduction> getAroductionByAssetsId(Long id) {
        return this.list(new LambdaQueryWrapper<AssetsProduction>().eq(AssetsProduction::getBusinessId, id));
    }

    @Override
    @SuppressWarnings("unchecked")
    public Page<AssetsProduction> selectPage(Page page, AssetsProduction assetsProduction) {
        return this.page(page, new QueryWrapper<AssetsProduction>(assetsProduction));
    }


    @Override
    public AssetsProduction detail(Long id) {
        return this.getById(id);
    }

    @Override
    public Boolean add(TaskRecordDTO<AssetsProduction> taskRecordDTO) {
        return this.save(taskRecordDTO.getTaskData());
    }

    @Override
    public Boolean update(AssetsProduction assetsProduction) {
        return this.updateById(assetsProduction);
    }

    @Override
    public Boolean delete(Long id) {
        //逻辑删除
        return this.removeById(id);
    }

    /**
     * 根据业务id获取产品信息类型集合
     *
     * @param businessId 资产业务id
     * @return List<String>
     */
    public List<String> getProductionTypes(Long businessId) {
        return assetsProductionMapper.getProductionTypes(businessId);
    }

    /**
     * 根据业务id获取已选择产品
     *
     * @param businessId 资产业务id
     * @return AssetsProduction
     */
    @Override
    public AssetsProduction getProductionByBusinessId(Long businessId) {
        return assetsProductionMapper.getProductionByBusinessId(businessId);
    }

    /**
     * 撰写产品信息
     *
     * @param assetsProduction 产品信息字段
     * @return Boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean writeAssetsProduction(AssetsProduction assetsProduction) {
        int count = this.count(new LambdaQueryWrapper<AssetsProduction>().select(AssetsProduction::getCreateProductionDate).eq(AssetsProduction::getProductionNo, assetsProduction.getProductionNo())
                .eq(AssetsProduction::getId, assetsProduction.getId()));
        if (count > 0) {
            return null;
        }
        // 生成产品二维码
        assetsProduction.setQrCode(businessProductionService.doCreateNormalCode(assetsProduction.getProductionType(), assetsProduction.getProductionNo()));
        // 新增收款信息
//        AssetsProduction productionType = this.getOne(new LambdaQueryWrapper<AssetsProduction>()
//                .select(AssetsProduction::getProductionType)
//                .eq(AssetsProduction::getProductionNo, assetsProduction.getProductionNo())
//                .eq(AssetsProduction::getId, assetsProduction.getId()));
//        if (ObjectUtil.isNotNull(productionType) && !productionType.getProductionType().equals("STATEMENT")){
//            addAssetsShouldAmount(assetsProduction);
//        }
        return assetsProductionMapper.writeAssetsProduction(assetsProduction);
    }

    /**
     * 根据业务id与产品号获取资产产品详细信息
     *
     * @param dto 查询dto
     * @return AssetsProduction
     */
    @Override
    public AssetsProduction getAssetsProductionDetail(AssetsProductionDetailDTO dto) {
        return this.getOne(new LambdaQueryWrapper<AssetsProduction>().eq(AssetsProduction::getBusinessId, dto.getBusinessId()).eq(AssetsProduction::getProductionNo, dto.getProductionNo()));
    }

    /**
     * 根据业务id与产品号查询产品信息
     *
     * @param aProListSelectDTO 查询dto
     * @return List<AssetsProduction>
     */
    @Override
    public List<AssetsProduction> getProductionList(AProListSelectDTO aProListSelectDTO) {
        return assetsProductionMapper.getProductionList(aProListSelectDTO);
    }

    /**
     * 根据业务id与产品号查询该产品是否已有提交的流程实例信息
     *
     * @param aProListSelectDTO 查询dto
     * @return Integer
     */
    @Override
    public Integer getInatanceCount(AProListSelectDTO aProListSelectDTO) {
        return assetsProductionMapper.getInatanceCount(aProListSelectDTO);
    }

    /**
     * 根据业务id与产品号集合获取每个产品是否有提交过的流程实例信息
     *
     * @return List<Integer>
     */
    @Override
    public List<Integer> getInatanceCountList(AProListSelectDTO aProListSelectDTO) {
        List<Integer> countList = new ArrayList<>();
        for (String productionNo : aProListSelectDTO.getProductionNos()) {
            countList.add(assetsProductionMapper.getInatanceCountByIdAndProNo(aProListSelectDTO.getBusinessId(), productionNo));
        }
        return countList;
    }

    /**
     * 产品出入库
     *
     * @param wareHouseDTO 出入库信息dto
     * @return Boolean
     */
    @Override
    public Boolean assetsProRepertory(AssetsProWareHouseDTO wareHouseDTO) {
        AssetsProduction assetsProduction = this.getOne(new LambdaQueryWrapper<AssetsProduction>()
                .select(BaseEntity::getId, AssetsProduction::getRepertoryState,
                        AssetsProduction::getProductionNo,
                        AssetsProduction::getBusinessId,
                        AssetsProduction::getProductionType)
                .eq(BaseEntity::getId, wareHouseDTO.getProductionId())
                .eq(BaseEntity::getDeleted, Boolean.FALSE));
        if (ObjectUtil.isNull(assetsProduction)) {
            ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR, "产品不存在，操作失败。");
        } else if (!assetsProduction.getProductionNo().equals(wareHouseDTO.getProductionNo())) {
            ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR, "操作的产品报告号与当前操作的产品报告号不一致，请检查。");
        } else if (!assetsProduction.getProductionType().equals(wareHouseDTO.getProductionType())) {
            ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR, "操作的产品类型与当前操作的产品类型不符，请检查。");
        } else {
            // true出库,false入库
            if (wareHouseDTO.getRepertoryState()) { // 出库
                if (ObjectUtil.isNull(assetsProduction.getRepertoryState())) {
                    ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR, "产品还未入库，无法出库。");
                } else if (assetsProduction.getRepertoryState()) {
                    ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR, "产品还已出库，无需出库。");
                }
                OrderFund orderFund = orderFundService.getOne(new LambdaQueryWrapper<OrderFund>()
                        .select(BaseEntity::getId, OrderFund::getRealAmount)
                        .eq(OrderFund::getBusinessId, wareHouseDTO.getBusinessId())
                        .eq(OrderFund::getBusinessType, ASSET_BUSINESS.getCode()));
                // 非意见书,且实收款未认领(订单实收款为NULL)
                if (!assetsProduction.getProductionType().equals(STATEMENT.name()) && ObjectUtil.isNull(orderFund)) {
                    int passCount = productionOutWarehouseService.count(new LambdaQueryWrapper<ProductionOutWarehouse>()
                            .select(ProductionOutWarehouse::getDepartmentCheckState)
                            .eq(ProductionOutWarehouse::getReportNo, wareHouseDTO.getProductionNo())
                            .eq(ProductionOutWarehouse::getBusinessType, "ASSET_BUSINESS")
                            .eq(ProductionOutWarehouse::getDepartmentCheckState, "审核通过")
                            .eq(BaseEntity::getDeleted, 0));
                    // 判断出库审核是否通过
                    if (passCount < 1) { // 不通过提示
                        ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR, "不满足出库条件，该产品需客户经理申请产品出库通过后方可出库。");
                    } else { // 通过则出库
                        return this.update(new LambdaUpdateWrapper<AssetsProduction>()
                                .set(AssetsProduction::getRepertoryState, 1)
                                .set(AssetsProduction::getRepertoryOutTime, new Date())
                                .eq(BaseEntity::getId, wareHouseDTO.getProductionId())
                                .eq(AssetsProduction::getProductionNo, wareHouseDTO.getProductionNo()));
                    }
                } else { // 意见书可以直接出库
                    return this.update(new LambdaUpdateWrapper<AssetsProduction>()
                            .set(AssetsProduction::getRepertoryState, 1)
                            .set(AssetsProduction::getRepertoryInTime, new Date())
                            .eq(BaseEntity::getId, wareHouseDTO.getProductionId())
                            .eq(AssetsProduction::getProductionNo, wareHouseDTO.getProductionNo()));
                }
            } else { // 入库
                return this.update(new LambdaUpdateWrapper<AssetsProduction>()
                        .set(AssetsProduction::getRepertoryState, 0)
                        .set(AssetsProduction::getRepertoryInTime, new Date())
                        .eq(BaseEntity::getId, wareHouseDTO.getProductionId())
                        .eq(AssetsProduction::getProductionNo, wareHouseDTO.getProductionNo()));
            }
        }
        return Boolean.FALSE;
    }

    /**
     * 根据资产产品id更新文件路由信息
     *
     * @param assetsProduction 产品信息dto
     * @return Boolean
     */
    @Override
    public Boolean updateProductionFileInfo(AssetsProduction assetsProduction) {
        return assetsProductionMapper.updateProductionFileInfo(assetsProduction);
    }

    /**
     * 获取产品实收款
     *
     * @param productionNo 产品号
     * @return BigDecimal
     */
    @Override
    public BigDecimal getProductionRealAmount(String productionNo) {
        return assetsProductionMapper.getProductionRealAmount(productionNo);
    }

    /**
     * 产品标记送达
     * @param productionNo 产品号
     * @return Boolean
     */
    @Override
    public Boolean markDelivery(String productionNo) {
        return assetsProductionMapper.markDelivery(productionNo);
    }

    /**
     * 新增订单收款信息
     *
     * @param assetsProduction 资产订单信息
     */
    public void addAssetsShouldAmount(AssetsProduction assetsProduction) {
        // 从订单收款表获取应收款信息
        OrderFund orderFund = new OrderFund();
        orderFund = orderFundService.getOne(new LambdaQueryWrapper<OrderFund>()
                .select(OrderFund::getOrderId, OrderFund::getShouldAmount)
                .eq(OrderFund::getBusinessId, assetsProduction.getBusinessId())
                .eq(OrderFund::getBusinessType, "ASSET_BUSINESS"));

        if (ObjectUtil.isNotNull(orderFund) && ObjectUtil.isNotNull(orderFund.getShouldAmount())) {
            ProductionFund productionFund = new ProductionFund();
            productionFund.setOrderFundId(orderFund.getId());
            productionFund.setProductionShouldAmount(orderFund.getShouldAmount());
            productionFund.setProductionNo(assetsProduction.getProductionNo());
            // 新增产品的收款信息
            productionFundService.save(productionFund);
        } else {
            Assets assets = assetsService.getById(assetsProduction.getBusinessId());
            orderFund.setBusinessId(assets.getId());
            orderFund.setOrderId(assets.getOrderId());
            orderFund.setOrderName(assets.getName());
            orderFund.setBusinessType("ASSET_BUSINESS");
            orderFund.setShouldAmount(BigDecimal.valueOf(0));
            orderFundService.save(orderFund);
            // 订单应收款新增后 继续调用方法添加产品收款信息
            addAssetsShouldAmount(assetsProduction);
        }
    }
}
