package com.hfkj.service.gas.impl;

import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.utils.RedisUtil;
import com.hfkj.dao.BsMerchantMapper;
import com.hfkj.entity.*;
import com.hfkj.model.GasListModel;
import com.hfkj.model.GasModel;
import com.hfkj.model.GasOilPriceModel;
import com.hfkj.model.GasPayPriceModel;
import com.hfkj.service.agent.BsAgentPriceService;
import com.hfkj.service.discount.BsDiscountUserService;
import com.hfkj.service.gas.BsGasChannelPriceWeekService;
import com.hfkj.service.gas.BsGasOilGunNoService;
import com.hfkj.service.gas.BsGasOilPriceService;
import com.hfkj.service.gas.BsGasService;
import com.hfkj.service.merchant.BsMerchantService;
import com.hfkj.sysenum.agent.AgentPriceTypeEnum;
import com.hfkj.sysenum.discount.DiscountTypeEnum;
import com.hfkj.sysenum.gas.GasOilPriceStatusEnum;
import com.hfkj.sysenum.merchant.MerchantSourceTypeEnum;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

/**
 * @className: BsGasServiceImpl
 * @author: HuRui
 * @date: 2024/6/4
 **/
@Service("gasService")
public class BsGasServiceImpl implements BsGasService {
    @Resource
    private BsMerchantMapper merchantMapper;
    @Resource
    private BsMerchantService merchantService;
    @Resource
    private BsGasOilPriceService gasOilPriceService;
    @Resource
    private BsGasOilGunNoService gasOilGunNoService;
    @Resource
    private BsAgentPriceService agentPriceService;
    @Resource
    private BsDiscountUserService discountUserService;
    @Resource
    private BsGasChannelPriceWeekService gasChannelPriceWeekService;
    @Resource
    private RedisUtil redisUtil;
    private final static String CACHE_GAS_KEY = "GAS:";

    @Override
    public void cache(GasModel data) {
        redisUtil.set(CACHE_GAS_KEY + data.getMerNo(), data);
    }

    @Override
    public void clean(String merNo) {
        redisUtil.del(CACHE_GAS_KEY+merNo);
    }

    @Override
    public GasPayPriceModel refuelPriceCompute(BigDecimal refuelPrice, String merNo, String oilNo, Long agentMerId, Long userDiscountId) {
        // 查询油站信息
        BsMerchant merchant = merchantService.getMerchant(merNo);
        if (merchant == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到油站");
        }
        BsDiscountUser discountUser = null;
        GasPayPriceModel payPriceModel = new GasPayPriceModel();
        payPriceModel.setDeductionCouponPrice(new BigDecimal("0"));

        // 优惠比例
        BigDecimal discount = new BigDecimal("100");
        BigDecimal serviceFeeRate = new BigDecimal("0");

        if (agentMerId != null) {
            // 查询代理价格
            BsAgentPrice agentPrice = agentPriceService.getDetail(agentMerId, oilNo);
            if (agentPrice != null) {
                discount = agentPrice.getPriceRate();
                serviceFeeRate = agentPrice.getServiceFeeRate();
            }
        } else {
            // 查询渠道优惠
            BsGasChannelPriceWeek gasChannelPriceWeek = gasChannelPriceWeekService.getDetail(MerchantSourceTypeEnum.getDataByType(merchant.getSourceType()), LocalDate.now().getDayOfWeek().getValue(), oilNo);
            if (gasChannelPriceWeek != null) {
                discount = gasChannelPriceWeek.getPriceRate();
                serviceFeeRate = gasChannelPriceWeek.getServiceFeeRate();
            }
           /* // 查询平台价格
            BsAgentPrice agentPrice = agentPriceService.getDetail(AgentPriceTypeEnum.type1, merNo, oilNo);
            if (agentPrice != null) {
                discount = agentPrice.getPriceRate();
                serviceFeeRate = agentPrice.getServiceFeeRate();
            }*/
        }

        if (userDiscountId != null) {
            // 查询用户优惠券
            discountUser = discountUserService.getDetail(userDiscountId);
            if (discountUser == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到用户优惠券");
            }
            if (discountUser.getOverlayDiscount().equals(false)) {
                // 优惠券与油价不叠加
                discount = new BigDecimal("100");
            }
            // 查询平台服务费
            BsAgentPrice agentPrice = agentPriceService.getDetail(AgentPriceTypeEnum.type1, merNo, oilNo);
            if (agentPrice != null) {
                serviceFeeRate = agentPrice.getServiceFeeRate();
            }
            if (DiscountTypeEnum.type1.getCode().equals(discountUser.getDiscountType())) {
                // 如果订单总额 小于 满减价格
                if (refuelPrice.compareTo(discountUser.getDiscountCondition()) < 0) {
                    throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未达到满减金额,无法使用此优惠券");
                }
                payPriceModel.setDeductionCouponPrice(discountUser.getDiscountPrice());

            } else if (DiscountTypeEnum.type2.getCode().equals(discountUser.getDiscountType())) {
                payPriceModel.setDeductionCouponPrice(discountUser.getDiscountPrice());

            } else if (DiscountTypeEnum.type3.getCode().equals(discountUser.getDiscountType())) {
                // 加油金额 - （加油金额 * 折扣） = 优惠金额
                payPriceModel.setDeductionCouponPrice(refuelPrice.subtract(
                        refuelPrice.multiply(discountUser.getDiscountPrice().divide(new BigDecimal("100"))).setScale(2, BigDecimal.ROUND_HALF_DOWN)
                ));
            } else {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的优惠券类型");
            }
        }

        discount = discount.divide(new BigDecimal("100"));

        // 查询油站价格
        BsGasOilPrice gasOilPrice = gasOilPriceService.getGasOilPrice(merchant.getId(), oilNo);
        if (gasOilPrice == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到油站价格");
        }
        // 国标价
        BigDecimal priceOfficial = gasOilPrice.getPriceOfficial();
        // 油站价
        BigDecimal priceGun = gasOilPrice.getPriceGun();
        // 油站直降
        BigDecimal gasStationDrop = gasOilPrice.getGasStationDrop();
        // 油站优惠价
        BigDecimal priceVip = gasOilPrice.getPriceVip();
        // 嗨森逛平台价    油站优惠价 * 折扣
        BigDecimal pricePlatform = priceVip.multiply(discount).setScale(2, BigDecimal.ROUND_HALF_UP);
        if (discountUser != null && discountUser.getOverlayDiscount().equals(false)) {
            // 优惠券与油价不叠加
            pricePlatform = priceGun;
            priceVip = priceGun;
        }

        // 加油金额
        payPriceModel.setOilingPrice(refuelPrice);

        // 成本价
        payPriceModel.setPriceCost(gasOilPrice.getPriceCost());

        // 油站枪价
        payPriceModel.setPriceGun(priceGun);

        // 油站优惠价
        payPriceModel.setPriceVip(priceVip);

        // 油站国标价
        payPriceModel.setPriceOfficial(priceOfficial);

        // 油站直降
        payPriceModel.setGasStationDrop(gasStationDrop);

        // 平台补贴
        payPriceModel.setPreferentialMargin(gasOilPrice.getPreferentialMargin());

        // 平台价
        payPriceModel.setPricePlatform(pricePlatform);

        // 加油升数，计算方式：加油金额 / 油枪价
        payPriceModel.setOilLiters(refuelPrice.divide(priceGun, 2, BigDecimal.ROUND_HALF_UP));

        // 平台折扣，我们平台或者代理商设置的折扣
        payPriceModel.setDiscount(discount.compareTo(new BigDecimal("1.00")) == 0 ? new BigDecimal("1.00") : discount);

        // 优惠价格  油站VIP价 * 系统折扣
        payPriceModel.setPricePreferences(priceVip.multiply(discount).setScale(2, BigDecimal.ROUND_HALF_UP));

        // 每升优惠  国标价 - 优惠价格
        payPriceModel.setLitersPreferences(payPriceModel.getPriceGun().subtract(payPriceModel.getPricePreferences()));

        // 加油优惠
        payPriceModel.setDeductionOilPrice(payPriceModel.getOilLiters().multiply(payPriceModel.getLitersPreferences()).setScale(2, BigDecimal.ROUND_HALF_UP));

        // 服务费费率
        payPriceModel.setServiceFeeRate(serviceFeeRate);

        // 总优惠 = 优惠券 + 加油优惠
        BigDecimal totalPreferences = payPriceModel.getDeductionCouponPrice().add(payPriceModel.getDeductionOilPrice());

        // 服务费金额【总优惠 * 服务费费率】
        //payPriceModel.setServiceFeePrice(totalPreferences.multiply(serviceFeeRate.divide(new BigDecimal("100"))).setScale(2, BigDecimal.ROUND_HALF_UP));
        // 服务费金额【加油金额 * 服务费费率】
        payPriceModel.setServiceFeePrice(payPriceModel.getOilingPrice().multiply(serviceFeeRate.divide(new BigDecimal("100"))).setScale(2, BigDecimal.ROUND_HALF_UP));

        // 本次优惠  总优惠 - 服务费
        payPriceModel.setTotalPreferences(totalPreferences.subtract(payPriceModel.getServiceFeePrice()));

        // 支付价格  加油金额 - 本次优惠
        payPriceModel.setPayPrice(refuelPrice.subtract(payPriceModel.getTotalPreferences()));

        return payPriceModel;
    }

    @Override
    public GasModel getGasDetail(String merNo) {
        // 缓存
        Object cacheObj = redisUtil.get(CACHE_GAS_KEY + merNo);
        if (cacheObj != null) {
            return (GasModel) cacheObj;
        }
        // 查询商户
        BsMerchant merchant = merchantService.getMerchant(merNo);
        if (merchant == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到油站");
        }
        GasModel gasModel = new GasModel();
        BeanUtils.copyProperties(merchant, gasModel);

        // 查询油品
        List<BsGasOilPrice> oilNoList = gasOilPriceService.getGasOilPriceList(merchant.getId());

        List<GasOilPriceModel> oilNoModelList = new ArrayList<>();
        for (BsGasOilPrice gasOilPrice : oilNoList) {
            if (gasOilPrice.getStatus().equals(GasOilPriceStatusEnum.status1.getNumber())) {
                GasOilPriceModel oilNo = new GasOilPriceModel();
                BeanUtils.copyProperties(gasOilPrice, oilNo);
                // 查询抢号
                oilNo.setGasOilGunNo(gasOilGunNoService.getOilGunNoList(merNo, gasOilPrice.getOilNo()));

                oilNoModelList.add(oilNo);
            }
        }
        gasModel.setGasOilPrice(oilNoModelList);
        // 存入缓存
        cache(gasModel);
        return gasModel;
    }

    @Override
    public List<GasListModel> getGasList(String longitude, String latitude, String oilNo, String gasName, Integer distanceLimit, Boolean listShow) {
        return merchantMapper.queryGasList(longitude,latitude,oilNo,gasName,distanceLimit,listShow);
    }

    @Override
    public List<GasListModel> getGasListByDiscount(String discountNo, String longitude, String latitude, String oilNo, String gasName, Integer distanceLimit, Boolean listShow) {
        return merchantMapper.queryGasListByDiscount(discountNo,longitude,latitude,oilNo,gasName,distanceLimit,listShow);
    }

}
