package shop.alien.store.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.netease.yidun.sdk.core.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import shop.alien.entity.result.R;
import shop.alien.entity.store.LifePromotionPackage;
import shop.alien.entity.store.StoreAliPayLog;
import shop.alien.entity.store.vo.LifePromotionPackageVo;
import shop.alien.entity.store.vo.LifeUserExpertOrderVo;
import shop.alien.entity.store.vo.LifeUserExpertVo;
import shop.alien.mapper.LifeUserExpertMapper;
import shop.alien.mapper.LifeUserExpertOrderMapper;
import shop.alien.mapper.PromotionPackageMapper;
import shop.alien.store.service.PromotionPackageService;
import shop.alien.store.util.ali.AliApi;
import shop.alien.util.common.ListToPage;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 推广套餐 服务实现类
 *
 * @author fcw
 * @since 2025-03-01
 */

@Service
@RequiredArgsConstructor
public class PromotionPackageServiceImpl extends ServiceImpl<PromotionPackageMapper, LifePromotionPackage> implements PromotionPackageService {

    private final PromotionPackageMapper promotionPackageMapper;

    private final AliApi aliApi;

    private final LifeUserExpertMapper lifeUserExpertMapper;

    private final LifeUserExpertOrderMapper lifeUserExpertOrderMapper;

    /**
     * 获取推广套餐
     *
     * @param expertId 达人Id
     * @return list
     */
    @Override
    public IPage<LifePromotionPackageVo> getByExpertId(Long expertId, Integer page, Integer size) {
        List<LifePromotionPackageVo> promotionPackageVos=promotionPackageMapper.getByExpertId(expertId);
        return ListToPage.setPage(promotionPackageVos,page, size);
    }

    @Override
    public Map<String, Object> buyPromotion(LifePromotionPackageVo lifePromotionPackageVo) {
        Map<String, Object> resultMap = new HashMap<>();

        try {
            // 参数校验
            validatePromotionPackageVo(lifePromotionPackageVo);

            // 获取套餐信息
            LifePromotionPackage promotionPackage = promotionPackageMapper.selectById(lifePromotionPackageVo.getId());
            if (promotionPackage == null) {
                return buildErrorResult(resultMap, "未找到对应的推广套餐记录，套餐ID: " + lifePromotionPackageVo.getId());
            }
            if (promotionPackage.getSoldCount() == null) {
                promotionPackage.setSoldCount("1");
            } else {
                promotionPackage.setSoldCount(String.valueOf(1 + Integer.parseInt(promotionPackage.getSoldCount())));
            }
            promotionPackageMapper.updateById(promotionPackage);

            // 金额计算
            AmountInfo amountInfo = calculateAmounts(String.valueOf(lifePromotionPackageVo.getPayPrice()));

            // 构建订单
            LifeUserExpertOrderVo orderVo = buildOrderVo(lifePromotionPackageVo, promotionPackage, amountInfo);

            // 获取达人身份信息
            LifeUserExpertVo expertInfo = lifeUserExpertMapper.getTalentIdentityInformation(lifePromotionPackageVo.getExpertId());
            if (expertInfo == null) {
                return buildErrorResult(resultMap, "未找到达人身份信息，达人ID: " + lifePromotionPackageVo.getExpertId());
            }

            // 执行首笔打款
            StoreAliPayLog payResult = executeFirstPayment(expertInfo, amountInfo.getFirstArrivalAmount());
            orderVo.setFirstPaymentTime(new Date());

            // 保存订单
            lifeUserExpertOrderMapper.insert(orderVo);

            // 返回成功结果
            resultMap.put("status", "success");
            resultMap.put("message", "推广套餐购买成功，首笔打款已完成");
            resultMap.put("payResult", payResult);
            resultMap.put("orderNo", orderVo.getOrderNo());
            return resultMap;

        } catch (IllegalArgumentException e) {
            return buildErrorResult(resultMap, e.getMessage());
        } catch (Exception e) {
            log.error("推广套餐购买异常", e);
            return buildErrorResult(resultMap, "系统异常，请稍后重试");
        }
    }

    private void validatePromotionPackageVo(LifePromotionPackageVo vo) {
        if (vo == null) {
            throw new IllegalArgumentException("推广套餐信息不能为空");
        }
        if (vo.getId() == null || vo.getStoreId() == null || vo.getExpertId() == null) {
            throw new IllegalArgumentException("套餐ID、店铺ID和达人ID不能为空");
        }
        if (vo.getPayPrice() == null || Double.parseDouble(String.valueOf(vo.getPayPrice())) <= 0) {
            throw new IllegalArgumentException("支付金额必须大于0");
        }
        if (StringUtils.isBlank(vo.getOrderNo())) {
            throw new IllegalArgumentException("订单号不能为空");
        }
    }

    private AmountInfo calculateAmounts(String payPriceStr) {
        try {
            BigDecimal payPrice = new BigDecimal(payPriceStr);

            // 平台收取10%服务费
            BigDecimal serviceFeeRate = new BigDecimal("0.1");
            BigDecimal serviceFee = payPrice.multiply(serviceFeeRate);
            BigDecimal amountAfterServiceFee = payPrice.subtract(serviceFee);

            // 支付合同金额(扣完10%服务费)的50%
            BigDecimal firstPaymentRate = new BigDecimal("0.5");
            BigDecimal firstArrivalAmount = amountAfterServiceFee.multiply(firstPaymentRate)
                    .setScale(2, RoundingMode.HALF_UP);

            return new AmountInfo(payPrice, serviceFee, amountAfterServiceFee, firstArrivalAmount);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("支付金额格式错误: " + payPriceStr);
        }
    }

    private LifeUserExpertOrderVo buildOrderVo(LifePromotionPackageVo packageVo,
                                               LifePromotionPackage promotionPackage,
                                               AmountInfo amountInfo) {
        LifeUserExpertOrderVo orderVo = new LifeUserExpertOrderVo();
        orderVo.setStoreId(packageVo.getStoreId());
        orderVo.setOrderNo(packageVo.getOrderNo());
        orderVo.setExpertId(promotionPackage.getExpertId());
        orderVo.setOrderMoney(amountInfo.getPayPrice());
        orderVo.setAccountMoney(amountInfo.getFirstArrivalAmount());
        orderVo.setOrderTime(new Date());
        orderVo.setOrderPlayCount(Integer.valueOf(promotionPackage.getPlayCount()));
        orderVo.setOrderGmv(new BigDecimal(promotionPackage.getGmv()));
        orderVo.setStatus(1);
        orderVo.setCreatedTime(new Date());
        return orderVo;
    }

    private StoreAliPayLog executeFirstPayment(LifeUserExpertVo expertInfo, BigDecimal amount) {
        StoreAliPayLog payResult = aliApi.pay(
                expertInfo.getRealName(),
                expertInfo.getIdCard(),
                expertInfo.getUserPhone(),
                amount.toPlainString()
        );

        if (payResult == null) {
            throw new IllegalArgumentException("首笔打款失败，请联系平台");
        }
        return payResult;
    }

    private Map<String, Object> buildErrorResult(Map<String, Object> map, String message) {
        map.put("status", "error");
        map.put("message", message);
        return map;
    }

    // 内部类：封装金额计算结果
    private static class AmountInfo {
        private final BigDecimal payPrice;
        private final BigDecimal serviceFee;
        private final BigDecimal amountAfterServiceFee;
        private final BigDecimal firstArrivalAmount;

        public AmountInfo(BigDecimal payPrice, BigDecimal serviceFee,
                          BigDecimal amountAfterServiceFee, BigDecimal firstArrivalAmount) {
            this.payPrice = payPrice;
            this.serviceFee = serviceFee;
            this.amountAfterServiceFee = amountAfterServiceFee;
            this.firstArrivalAmount = firstArrivalAmount;
        }

        // getters
        public BigDecimal getPayPrice() {
            return payPrice;
        }

        public BigDecimal getServiceFee() {
            return serviceFee;
        }

        public BigDecimal getAmountAfterServiceFee() {
            return amountAfterServiceFee;
        }

        public BigDecimal getFirstArrivalAmount() {
            return firstArrivalAmount;
        }
    }
}




