package com.ycwl.basic.pricing.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ycwl.basic.pricing.dto.req.VoucherUsageHistoryReq;
import com.ycwl.basic.pricing.dto.resp.VoucherUsageRecordResp;
import com.ycwl.basic.pricing.dto.resp.VoucherUsageStatsResp;
import com.ycwl.basic.pricing.entity.PriceVoucherBatchConfig;
import com.ycwl.basic.pricing.entity.PriceVoucherCode;
import com.ycwl.basic.pricing.entity.PriceVoucherUsageRecord;
import com.ycwl.basic.pricing.enums.VoucherCodeStatus;
import com.ycwl.basic.pricing.mapper.PriceVoucherBatchConfigMapper;
import com.ycwl.basic.pricing.mapper.PriceVoucherCodeMapper;
import com.ycwl.basic.pricing.mapper.PriceVoucherUsageRecordMapper;
import com.ycwl.basic.pricing.service.IVoucherUsageService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

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

/**
 * 券码使用记录服务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class VoucherUsageServiceImpl implements IVoucherUsageService {
    
    private final PriceVoucherUsageRecordMapper usageRecordMapper;
    private final PriceVoucherCodeMapper voucherCodeMapper;
    private final PriceVoucherBatchConfigMapper batchConfigMapper;
    
    @Override
    public PageInfo<VoucherUsageRecordResp> getUsageHistory(VoucherUsageHistoryReq req) {
        PageHelper.startPage(req.getPageNum(), req.getPageSize());

        List<PriceVoucherUsageRecord> list = usageRecordMapper.selectListWithConditions(
            req.getBatchId(), req.getVoucherCode(), req.getFaceId(),
            req.getScenicId(), req.getStartTime(), req.getEndTime());

        List<VoucherUsageRecordResp> respList = new ArrayList<>();
        for (PriceVoucherUsageRecord record : list) {
            VoucherUsageRecordResp resp = convertToResp(record);
            respList.add(resp);
        }

        return new PageInfo<>(respList);
    }
    
    @Override
    public List<VoucherUsageRecordResp> getUsageRecordsByCode(String voucherCode) {
        List<PriceVoucherUsageRecord> records = usageRecordMapper.selectByVoucherCode(voucherCode);
        List<VoucherUsageRecordResp> respList = new ArrayList<>();
        
        for (PriceVoucherUsageRecord record : records) {
            respList.add(convertToResp(record));
        }
        
        return respList;
    }
    
    @Override
    public List<VoucherUsageRecordResp> getUserUsageRecords(Long faceId, Long scenicId) {
        List<PriceVoucherUsageRecord> records = usageRecordMapper.selectByFaceIdAndScenicId(faceId, scenicId);
        List<VoucherUsageRecordResp> respList = new ArrayList<>();
        
        for (PriceVoucherUsageRecord record : records) {
            respList.add(convertToResp(record));
        }
        
        return respList;
    }
    
    @Override
    public VoucherUsageStatsResp getUsageStats(String voucherCode) {
        PriceVoucherCode voucherCodeEntity = voucherCodeMapper.selectByCode(voucherCode);
        if (voucherCodeEntity == null || voucherCodeEntity.getDeleted() == 1) {
            return null;
        }
        
        PriceVoucherBatchConfig batchConfig = batchConfigMapper.selectById(voucherCodeEntity.getBatchId());
        if (batchConfig == null || batchConfig.getDeleted() == 1) {
            return null;
        }
        
        VoucherUsageStatsResp stats = new VoucherUsageStatsResp();
        stats.setVoucherCodeId(voucherCodeEntity.getId());
        stats.setVoucherCode(voucherCodeEntity.getCode());
        stats.setBatchId(batchConfig.getId());
        stats.setBatchName(batchConfig.getBatchName());
        stats.setScenicId(voucherCodeEntity.getScenicId());
        stats.setStatus(voucherCodeEntity.getStatus());
        
        VoucherCodeStatus statusEnum = VoucherCodeStatus.getByCode(voucherCodeEntity.getStatus());
        if (statusEnum != null) {
            stats.setStatusName(statusEnum.getName());
        }
        
        Integer currentUseCount = voucherCodeEntity.getCurrentUseCount() != null ? 
            voucherCodeEntity.getCurrentUseCount() : 0;
        stats.setCurrentUseCount(currentUseCount);
        stats.setMaxUseCount(batchConfig.getMaxUseCount());
        stats.setMaxUsePerUser(batchConfig.getMaxUsePerUser());
        stats.setUseIntervalHours(batchConfig.getUseIntervalHours());
        
        // 计算是否还能使用
        boolean canUseMore = true;
        if (batchConfig.getMaxUseCount() != null) {
            canUseMore = currentUseCount < batchConfig.getMaxUseCount();
        }
        stats.setCanUseMore(canUseMore);
        
        // 计算剩余使用次数
        if (batchConfig.getMaxUseCount() != null) {
            int remaining = batchConfig.getMaxUseCount() - currentUseCount;
            stats.setRemainingUseCount(Math.max(0, remaining));
        }
        
        // 获取使用记录数
        Integer totalUsageRecords = usageRecordMapper.selectByVoucherCodeId(voucherCodeEntity.getId()).size();
        stats.setTotalUsageRecords(totalUsageRecords);
        
        // 格式化最后使用时间
        if (voucherCodeEntity.getLastUsedTime() != null) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            stats.setLastUsedTime(sdf.format(voucherCodeEntity.getLastUsedTime()));
        }
        
        return stats;
    }
    
    @Override
    public List<VoucherUsageStatsResp> getBatchUsageStats(Long batchId) {
        if (batchId == null) {
            return new ArrayList<>();
        }

        // 查询批次配置
        PriceVoucherBatchConfig batchConfig = batchConfigMapper.selectById(batchId);
        if (batchConfig == null || batchConfig.getDeleted() == 1) {
            log.warn("批次配置不存在或已删除: batchId={}", batchId);
            return new ArrayList<>();
        }

        // 查询该批次下的所有券码
        List<PriceVoucherCode> voucherCodes = voucherCodeMapper.selectByBatchId(batchId);
        if (voucherCodes == null || voucherCodes.isEmpty()) {
            log.info("批次下无券码数据: batchId={}", batchId);
            return new ArrayList<>();
        }

        List<VoucherUsageStatsResp> statsList = new ArrayList<>();

        for (PriceVoucherCode voucherCode : voucherCodes) {
            if (voucherCode.getDeleted() == 1) {
                continue;
            }

            VoucherUsageStatsResp stats = new VoucherUsageStatsResp();
            stats.setVoucherCodeId(voucherCode.getId());
            stats.setVoucherCode(voucherCode.getCode());
            stats.setBatchId(batchConfig.getId());
            stats.setBatchName(batchConfig.getBatchName());
            stats.setScenicId(voucherCode.getScenicId());
            stats.setStatus(voucherCode.getStatus());

            // 设置状态名称
            VoucherCodeStatus statusEnum = VoucherCodeStatus.getByCode(voucherCode.getStatus());
            if (statusEnum != null) {
                stats.setStatusName(statusEnum.getName());
            }

            // 设置使用次数相关信息
            Integer currentUseCount = voucherCode.getCurrentUseCount() != null ?
                voucherCode.getCurrentUseCount() : 0;
            stats.setCurrentUseCount(currentUseCount);
            stats.setMaxUseCount(batchConfig.getMaxUseCount());
            stats.setMaxUsePerUser(batchConfig.getMaxUsePerUser());
            stats.setUseIntervalHours(batchConfig.getUseIntervalHours());

            // 计算是否还能使用
            boolean canUseMore = true;
            if (batchConfig.getMaxUseCount() != null) {
                canUseMore = currentUseCount < batchConfig.getMaxUseCount();
            }
            stats.setCanUseMore(canUseMore);

            // 计算剩余使用次数
            if (batchConfig.getMaxUseCount() != null) {
                int remaining = batchConfig.getMaxUseCount() - currentUseCount;
                stats.setRemainingUseCount(Math.max(0, remaining));
            }

            // 获取使用记录数
            List<PriceVoucherUsageRecord> usageRecords = usageRecordMapper.selectByVoucherCodeId(voucherCode.getId());
            stats.setTotalUsageRecords(usageRecords != null ? usageRecords.size() : 0);

            // 格式化最后使用时间
            if (voucherCode.getLastUsedTime() != null) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                stats.setLastUsedTime(sdf.format(voucherCode.getLastUsedTime()));
            }

            statsList.add(stats);
        }

        log.info("批次统计完成: batchId={}, 券码数量={}", batchId, statsList.size());
        return statsList;
    }
    
    @Override
    public void recordVoucherUsage(String voucherCode, Long faceId, String orderId, 
                                   BigDecimal discountAmount, String remark) {
        PriceVoucherCode voucherCodeEntity = voucherCodeMapper.selectByCode(voucherCode);
        if (voucherCodeEntity == null || voucherCodeEntity.getDeleted() == 1) {
            log.warn("券码不存在或已删除: {}", voucherCode);
            return;
        }
        
        Date now = new Date();
        PriceVoucherUsageRecord record = new PriceVoucherUsageRecord();
        record.setVoucherCodeId(voucherCodeEntity.getId());
        record.setVoucherCode(voucherCode);
        record.setFaceId(faceId);
        record.setScenicId(voucherCodeEntity.getScenicId());
        record.setBatchId(voucherCodeEntity.getBatchId());
        record.setUseTime(now);
        record.setOrderId(orderId);
        record.setDiscountAmount(discountAmount);
        record.setRemark(remark);
        record.setCreateTime(now);
        record.setDeleted(0);
        
        usageRecordMapper.insert(record);
        log.info("券码使用记录已创建: voucherCode={}, faceId={}, orderId={}", 
            voucherCode, faceId, orderId);
    }
    
    /**
     * 转换为响应DTO
     */
    private VoucherUsageRecordResp convertToResp(PriceVoucherUsageRecord record) {
        VoucherUsageRecordResp resp = new VoucherUsageRecordResp();
        BeanUtils.copyProperties(record, resp);
        
        // 查询批次名称
        if (record.getBatchId() != null) {
            PriceVoucherBatchConfig batchConfig = batchConfigMapper.selectById(record.getBatchId());
            if (batchConfig != null) {
                resp.setBatchName(batchConfig.getBatchName());
            }
        }
        
        return resp;
    }
}