package com.ruoyi.project.business.service.quotation.impl;

import static com.ruoyi.project.business.enums.AuditFlowEnum.BARGAIN;
import static com.ruoyi.project.business.service.quotation.impl.QuoteApprovalServiceImpl.ONE_HUNDRED;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.project.business.domain.TqBargainPrice;
import com.ruoyi.project.business.domain.TqQuotation;
import com.ruoyi.project.business.domain.TqSalespersonSetPrice;
import com.ruoyi.project.business.domain.TqSpecification;
import com.ruoyi.project.business.domain.bo.quotation.BargainPriceAddBO;
import com.ruoyi.project.business.domain.bo.quotation.SpecificationQueryBO;
import com.ruoyi.project.business.dto.TaskGenerateParams;
import com.ruoyi.project.business.enums.BargainStatusEnum;
import com.ruoyi.project.business.enums.DelFlagEnum;
import com.ruoyi.project.business.enums.QuotationStatusEnum;
import com.ruoyi.project.business.mapper.quotation.TqBargainPriceMapper;
import com.ruoyi.project.business.mapper.quotation.TqQuotationMapper;
import com.ruoyi.project.business.mapper.quotation.TqSalespersonSetPriceMapper;
import com.ruoyi.project.business.mapper.quotation.TqSpecificationMapper;
import com.ruoyi.project.business.service.flow.IFlowService;
import com.ruoyi.project.business.service.quotation.ITqBargainPriceService;
import com.ruoyi.project.business.service.quotation.ITqSalespersonSetPriceService;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 【请填写功能名称】Service业务层处理
 *
 * @author ruoyi
 * @date 2024-05-21
 */
@Service
public class TqBargainPriceServiceImpl extends ServiceImpl<TqBargainPriceMapper, TqBargainPrice> implements
    ITqBargainPriceService {

    public static final BigDecimal FIFTY = new BigDecimal("50");

    @Resource
    private TqBargainPriceMapper tqBargainPriceMapper;

    @Resource
    private TqSpecificationMapper tqSpecificationMapper;

    @Resource
    private TqQuotationMapper tqQuotationMapper;

    @Resource
    private TqSalespersonSetPriceMapper tqSalespersonSetPriceMapper;

    @Resource
    private IFlowService flowService;

    @Resource
    private ITqSalespersonSetPriceService tqSalespersonSetPriceService;

    /**
     * 查询【请填写功能名称】
     *
     * @param id 【请填写功能名称】主键
     * @return 【请填写功能名称】
     */
    @Override
    public TqBargainPrice selectTqBargainPriceById(Long id) {
        return tqBargainPriceMapper.selectTqBargainPriceById(id);
    }

    /**
     * 查询【请填写功能名称】列表
     *
     * @param tqBargainPrice 【请填写功能名称】
     * @return 【请填写功能名称】
     */
    @Override
    public List<TqBargainPrice> selectTqBargainPriceList(TqBargainPrice tqBargainPrice) {
        return tqBargainPriceMapper.selectTqBargainPriceList(tqBargainPrice);
    }

    /**
     * 新增【请填写功能名称】
     *
     * @param tqBargainPrice 【请填写功能名称】
     * @return 结果
     */
    @Override
    public int insertTqBargainPrice(TqBargainPrice tqBargainPrice) {
        tqBargainPrice.setCreateTime(DateUtils.getNowDate());
        return tqBargainPriceMapper.insertTqBargainPrice(tqBargainPrice);
    }

    /**
     * 修改【请填写功能名称】
     *
     * @param tqBargainPrice 【请填写功能名称】
     * @return 结果
     */
    @Override
    public int updateTqBargainPrice(TqBargainPrice tqBargainPrice) {
        tqBargainPrice.setUpdateTime(DateUtils.getNowDate());
        return tqBargainPriceMapper.updateTqBargainPrice(tqBargainPrice);
    }

    /**
     * 批量删除【请填写功能名称】
     *
     * @param ids 需要删除的【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteTqBargainPriceByIds(Long[] ids) {
        return tqBargainPriceMapper.deleteTqBargainPriceByIds(ids);
    }

    /**
     * 删除【请填写功能名称】信息
     *
     * @param id 【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteTqBargainPriceById(Long id) {
        return tqBargainPriceMapper.deleteTqBargainPriceById(id);
    }

    @Override
    @Transactional
    public void startBargainPrice(BargainPriceAddBO bargainPriceAddBO) {
        TqQuotation tqQuotation = tqQuotationMapper.selectById(bargainPriceAddBO.getQuotationId());
        TqBargainPrice tqBargainPrice = new TqBargainPrice();
        tqBargainPrice.setQuotationId(bargainPriceAddBO.getQuotationId());

        // 统一转换成基价折率
        tqBargainPrice.setDiscountRate(bargainPriceAddBO.getExpectedPrice().subtract(tqQuotation.getOriginalOptionalPrice()).multiply(new BigDecimal(ONE_HUNDRED))
                .divide(tqQuotation.getOriginalBasicPrice(), 4, RoundingMode.HALF_UP));

        tqBargainPrice.setBargainPrice(bargainPriceAddBO.getExpectedPrice());
        tqBargainPrice.setDelFlag(DelFlagEnum.NORMAL.getValue());
        tqBargainPrice.setCreateBy(SecurityUtils.getStrUserId());
        tqBargainPrice.setCreateTime(DateUtils.getNowDate());
        tqBargainPrice.setUpdateBy(SecurityUtils.getStrUserId());
        tqBargainPrice.setUpdateTime(DateUtils.getNowDate());
        this.save(tqBargainPrice);
        Long bargainPriceId = tqBargainPrice.getId();

        // 计算报价的价格  基础价格  选配价格
        List<TqSpecification> tqSpecifications = tqSpecificationMapper.selectList(
            Wrappers.<TqSpecification>lambdaQuery()
                .eq(TqSpecification::getQuotationId, bargainPriceAddBO.getQuotationId())
                .eq(TqSpecification::getDelFlag, DelFlagEnum.NORMAL.getValue()));

        for (TqSpecification specification : tqSpecifications) {
            // 折扣率
            BigDecimal discountRate = tqBargainPrice.getDiscountRate();
           // 折后基价
            BigDecimal discountBasicPrice = specification.getOriginalBasicPrice()
                    .multiply(discountRate).divide(new BigDecimal(ONE_HUNDRED), 0, RoundingMode.HALF_UP);
            BigDecimal discountPrice = discountBasicPrice.add(specification.getOptionalPrice());
            // 新增议价定价表
            TqSalespersonSetPrice tqSalespersonSetPrice = new TqSalespersonSetPrice();
            tqSalespersonSetPrice.setBargainId(bargainPriceId);
            tqSalespersonSetPrice.setSpecificationId(specification.getId());
            tqSalespersonSetPrice.setDiscountbasicPrice(discountBasicPrice);
            tqSalespersonSetPrice.setBasicPrice(specification.getOriginalBasicPrice());
            tqSalespersonSetPrice.setOptionalPrice(specification.getOriginalOptionalPrice());
            tqSalespersonSetPrice.setDiscountRate(discountRate);
            tqSalespersonSetPrice.setDiscountPrice(discountPrice);
            tqSalespersonSetPrice.setDelFlag(DelFlagEnum.NORMAL.getValue());
            tqSalespersonSetPrice.setCreateBy(SecurityUtils.getStrUserId());
            tqSalespersonSetPrice.setCreateTime(DateUtils.getNowDate());
            tqSalespersonSetPrice.setUpdateBy(SecurityUtils.getStrUserId());
            tqSalespersonSetPrice.setUpdateTime(DateUtils.getNowDate());
            tqSalespersonSetPriceService.save(tqSalespersonSetPrice);
        }

        // 更新报价
        tqQuotationMapper.update(null, Wrappers.<TqQuotation>lambdaUpdate()
            .eq(TqQuotation::getId, bargainPriceAddBO.getQuotationId())
            .set(TqQuotation::getQuotationStatus, QuotationStatusEnum.BARGAIN_APPROVAL.getCode())
        );
        // 更新电梯规格
        tqSpecificationMapper.update(null, Wrappers.<TqSpecification>lambdaUpdate()
            .eq(TqSpecification::getQuotationId, bargainPriceAddBO.getQuotationId())
            .set(TqSpecification::getQuotationStatus, QuotationStatusEnum.BARGAIN_APPROVAL.getCode())
        );
        // 启动议价流程
        flowService.generateTasks(
            new TaskGenerateParams(BARGAIN, tqQuotation, SecurityUtils.getUserId(),
                tqQuotation.getQuotationNo()));
    }

    @Override
    @Transactional
    public void acceptBargainPrice(Long quotationId) {
        List<TqBargainPrice> list = this.list(
            Wrappers.<TqBargainPrice>lambdaQuery().eq(TqBargainPrice::getQuotationId, quotationId)
                .orderByDesc(TqBargainPrice::getId));
        TqQuotation tqQuotation = tqQuotationMapper.selectById(quotationId);
        if (CollUtil.isNotEmpty(list)) {
            // 获取最新议价
            TqBargainPrice tqBargainPrice = list.get(0);
            SpecificationQueryBO specificationQueryBO = new SpecificationQueryBO();
            specificationQueryBO.setBargainId(tqBargainPrice.getId());
            specificationQueryBO.setQuotationId(quotationId);
            // 获取全部规格
            List<TqSpecification> tqSpecifications = tqSpecificationMapper.selectList(
                Wrappers.<TqSpecification>lambdaQuery()
                    .eq(TqSpecification::getQuotationId, quotationId)
                    .eq(TqSpecification::getDelFlag, DelFlagEnum.NORMAL.getValue())
            );
            // 电梯型号id 数量Map   key:elevatorId  value:elevatorNumber
            Map<Long, Long> elevatorIdNumberMap = tqSpecifications.stream()
                .collect(Collectors.toMap(TqSpecification::getId, TqSpecification::getElevatorNumber));
            List<Long> specificationIdList = tqSpecifications.stream().map(TqSpecification::getId)
                .collect(Collectors.toList());
            // 获取议价价格明细
            List<TqSalespersonSetPrice> tqSalespersonSetPrices = tqSalespersonSetPriceMapper
                .selectList(Wrappers.<TqSalespersonSetPrice>lambdaQuery()
                    .eq(TqSalespersonSetPrice::getBargainId, tqBargainPrice.getId())
                    .eq(TqSalespersonSetPrice::getDelFlag, DelFlagEnum.NORMAL.getValue())
                    .in(TqSalespersonSetPrice::getSpecificationId, specificationIdList)
                    .orderByDesc(TqSalespersonSetPrice::getId)
                );
            // 获取最新的议价价格明细
            List<TqSalespersonSetPrice> newSalesSetPricesList = new ArrayList<>();
            Map<String, List<TqSalespersonSetPrice>> map = tqSalespersonSetPrices.stream()
                .collect(
                    Collectors.groupingBy(price -> StringUtils.join(price.getBargainId(), price.getSpecificationId())));
            map.forEach((key, value) -> newSalesSetPricesList.add(value.get(0)));
            // 统计接受价格
            BigDecimal acceptPrice = BigDecimal.ZERO;
            for (TqSalespersonSetPrice item : newSalesSetPricesList) {
                BigDecimal discountPrice = item.getDiscountPrice().setScale(0, RoundingMode.HALF_UP);
                // 更新最终价格
                tqSpecificationMapper.update(null,
                    Wrappers.<TqSpecification>lambdaUpdate()
                        .eq(TqSpecification::getId, item.getSpecificationId())
                        .set(TqSpecification::getFinalPrice, discountPrice)
                        .set(TqSpecification::getDiscountRate, item.getDiscountRate())
                        .set(TqSpecification::getQuotationStatus, QuotationStatusEnum.ACCEPT_PRICE.getCode())
                );
                Long elevatorNumber = elevatorIdNumberMap.get(item.getSpecificationId());
                acceptPrice = acceptPrice.add(new BigDecimal(elevatorNumber).multiply(discountPrice));
            }
            BigDecimal finalCurrencyPrice = acceptPrice;
            BigDecimal exchangeRate = tqQuotation.getExchangeRate();
            // 计算人名币的价格
            BigDecimal finalPrice = acceptPrice.divide(exchangeRate, 4, RoundingMode.HALF_UP);

            // 更新议价
            this.update(Wrappers.<TqBargainPrice>lambdaUpdate()
                .eq(TqBargainPrice::getId, tqBargainPrice.getId())
                .set(TqBargainPrice::getBargainStatus, BargainStatusEnum.ACCEPT.getCode())
                .set(TqBargainPrice::getAcceptPrice, finalCurrencyPrice)
            );
            // 更新报价
            tqQuotationMapper.update(null, Wrappers.<TqQuotation>lambdaUpdate()
                .eq(TqQuotation::getId, quotationId)
                .set(TqQuotation::getQuotationStatus, QuotationStatusEnum.ACCEPT_PRICE.getCode())
                .set(TqQuotation::getFinalPrice, finalPrice)
                .set(TqQuotation::getFinalCurrencyPrice, finalCurrencyPrice));
        } else {
            // 获取全部规格
            List<TqSpecification> tqSpecifications = tqSpecificationMapper.selectList(
                    Wrappers.<TqSpecification>lambdaQuery()
                            .eq(TqSpecification::getQuotationId, quotationId)
                            .eq(TqSpecification::getDelFlag, DelFlagEnum.NORMAL.getValue()));
            tqSpecifications.forEach(item ->  {
                // 更新最终价格
                tqSpecificationMapper.update(null,
                        Wrappers.<TqSpecification>lambdaUpdate()
                                .eq(TqSpecification::getId, item.getId())
                                .set(TqSpecification::getFinalPrice, item.getPrice())
                                .set(TqSpecification::getQuotationStatus, QuotationStatusEnum.ACCEPT_PRICE.getCode())
                );
            });

            // 计算人名币的价格
            BigDecimal exchangeRate = tqQuotation.getExchangeRate();
            BigDecimal finalPrice = tqQuotation.getPrice().divide(exchangeRate, 4, RoundingMode.HALF_UP);

            // 更新报价
            tqQuotationMapper.update(null, Wrappers.<TqQuotation>lambdaUpdate()
                    .eq(TqQuotation::getId, quotationId)
                    .set(TqQuotation::getQuotationStatus, QuotationStatusEnum.ACCEPT_PRICE.getCode())
                    .set(TqQuotation::getFinalPrice, finalPrice)
                    .set(TqQuotation::getFinalCurrencyPrice, tqQuotation.getPrice()));
        }
    }

    @Override
    @Transactional
    public void rejectBargainPrice(Long quotationId) {
        // List<TqBargainPrice> list = this.list(
        //     Wrappers.<TqBargainPrice>lambdaQuery().eq(TqBargainPrice::getQuotationId, quotationId)
        //         .orderByDesc(TqBargainPrice::getId));
        // if (CollUtil.isNotEmpty(list)) {
        // 更新报价状态
        tqQuotationMapper.update(null, Wrappers.<TqQuotation>lambdaUpdate()
            .set(TqQuotation::getQuotationStatus, QuotationStatusEnum.BARGAIN_REJECT.getCode())
            .eq(TqQuotation::getId, quotationId));
        // }
        tqSpecificationMapper.update(null, Wrappers.<TqSpecification>lambdaUpdate()
            .set(TqSpecification::getQuotationStatus, QuotationStatusEnum.BARGAIN_REJECT.getCode())
            .eq(TqSpecification::getQuotationId, quotationId));
    }
}
