package com.jeesharp.business.modules.mall.service.impl;

import com.jeesharp.business.modules.mall.convert.MallBargainHelpConvert;
import com.jeesharp.business.modules.mall.entity.MallBargainActivity;
import com.jeesharp.business.modules.mall.entity.MallBargainHelp;
import com.jeesharp.business.modules.mall.entity.MallBargainRecord;
import com.jeesharp.business.modules.mall.mapper.MallBargainHelpMapper;
import com.jeesharp.business.modules.mall.service.MallBargainActivityService;
import com.jeesharp.business.modules.mall.service.MallBargainHelpService;
import com.jeesharp.business.modules.mall.service.MallBargainRecordService;
import com.jeesharp.business.modules.mall.vo.MallBargainHelpInfoVO;
import com.jeesharp.business.modules.mall.vo.MallBargainHelpListVO;
import com.jeesharp.business.modules.mall.vo.MallBargainHelpQueryVO;
import com.jeesharp.framework.pojo.Page;
import com.jeesharp.framework.pojo.query.PageRespVO;
import com.jeesharp.framework.mybatis.core.service.CrudService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * 砍价助力 Service 实现类
 */
@Service
@AllArgsConstructor
@Transactional(readOnly = true)
public class MallBargainHelpServiceImpl extends CrudService<MallBargainHelpMapper, MallBargainHelp, MallBargainHelpQueryVO> implements MallBargainHelpService {

    private static final String IDS_SEPARATOR = ",";

    private final MallBargainRecordService mallBargainRecordService;
    private final MallBargainActivityService mallBargainActivityService;

    @Override
    @Transactional(readOnly = false)
    public void createHelp(MallBargainHelp entity) {
        save(entity);
    }

    @Override
    @Transactional(readOnly = false)
    public void updateHelp(MallBargainHelp entity) {
        update(entity);
    }

    @Override
    public PageRespVO<MallBargainHelpListVO> findHelpPage(Page<MallBargainHelp> page, MallBargainHelpQueryVO query) {
        Page<MallBargainHelp> result = findPage(page, query);
        PageRespVO<MallBargainHelpListVO> pageResp = new PageRespVO<>();
        pageResp.setRecords(result.getRecords().stream()
                .map(MallBargainHelpConvert.INSTANCE::toListSingleVO)
                .toList());
        pageResp.setTotal(result.getTotal());
        pageResp.setPageNo(result.getPageNo());
        pageResp.setPageSize(result.getPageSize());
        return pageResp;
    }

    @Override
    @Transactional(readOnly = false)
    public BigDecimal helpBargain(String recordId, String memberId, Integer helpType) {
        MallBargainRecord record = mallBargainRecordService.get(recordId);
        if (record == null) {
            throw new RuntimeException("砍价记录不存在");
        }

        MallBargainHelpQueryVO query = new MallBargainHelpQueryVO();
        query.setRecordId(recordId);
        query.setMemberId(memberId);
        if (!findList(query).isEmpty()) {
            throw new RuntimeException("您已经助力过了");
        }

        if (record.getEndTime() != null && record.getEndTime().before(new Date())) {
            throw new RuntimeException("该砍价已过期");
        }

        MallBargainActivity activity = mallBargainActivityService.get(record.getActivityId());
        if (activity == null) {
            throw new RuntimeException("砍价活动不存在");
        }

        BigDecimal cutAmount = calculateCutAmount(record, activity);

        MallBargainHelp help = new MallBargainHelp();
        help.setRecordId(recordId);
        help.setMemberId(memberId);
        help.setCutAmount(cutAmount);
        help.setHelpType(helpType != null ? helpType : 0);
        createHelp(help);

        record.setCurrentPrice(record.getCurrentPrice().subtract(cutAmount));
        record.setHelpCount(record.getHelpCount() + 1);
        if (record.getCurrentPrice().compareTo(activity.getBottomPrice()) <= 0) {
            record.setCurrentPrice(activity.getBottomPrice());
            record.setStatus(1);
        }
        mallBargainRecordService.save(record);
        return cutAmount;
    }

    @Override
    public List<MallBargainHelpInfoVO> getBargainHelps(String recordId) {
        MallBargainHelpQueryVO query = new MallBargainHelpQueryVO();
        query.setRecordId(recordId);
        return findList(query).stream()
                .map(MallBargainHelpConvert.INSTANCE::toInfoVO)
                .toList();
    }

    private BigDecimal calculateCutAmount(MallBargainRecord record, MallBargainActivity activity) {
        BigDecimal currentPrice = record.getCurrentPrice();
        BigDecimal bottomPrice = activity.getBottomPrice();
        BigDecimal remainingAmount = currentPrice.subtract(bottomPrice);
        if (remainingAmount.compareTo(BigDecimal.ZERO) <= 0) {
            return BigDecimal.ZERO;
        }
        int remainingHelpCount = activity.getHelpCount() - record.getHelpCount();
        if (remainingHelpCount <= 1) {
            return remainingAmount;
        }
        Random random = new Random();
        double randomFactor = 0.1 + (random.nextDouble() * 0.2);
        BigDecimal maxCutAmount = remainingAmount.divide(BigDecimal.valueOf(remainingHelpCount), 2, RoundingMode.HALF_UP)
                .multiply(BigDecimal.valueOf(2));
        BigDecimal cutAmount = maxCutAmount.multiply(BigDecimal.valueOf(randomFactor)).setScale(2, RoundingMode.HALF_UP);
        if (cutAmount.compareTo(BigDecimal.valueOf(0.01)) < 0) {
            cutAmount = BigDecimal.valueOf(0.01);
        }
        if (cutAmount.compareTo(remainingAmount) > 0) {
            cutAmount = remainingAmount;
        }
        return cutAmount;
    }
}
