package com.ycwl.basic.service.impl;

import com.ycwl.basic.mapper.UserNotificationAuthorizationMapper;
import com.ycwl.basic.mapper.UserNotificationAuthorizationRecordMapper;
import com.ycwl.basic.model.pc.notify.entity.UserNotificationAuthorizationEntity;
import com.ycwl.basic.model.pc.notify.entity.UserNotificationAuthorizationRecordEntity;
import com.ycwl.basic.service.UserNotificationAuthorizationService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户通知授权记录Service实现类
 * 
 * @Author: System
 * @Date: 2024/12/28
 */
@Service
@Slf4j
public class UserNotificationAuthorizationServiceImpl implements UserNotificationAuthorizationService {
    
    @Autowired
    private UserNotificationAuthorizationMapper userNotificationAuthorizationMapper;

    @Autowired
    private UserNotificationAuthorizationRecordMapper userNotificationAuthorizationRecordMapper;
    
    @Override
    public UserNotificationAuthorizationEntity checkAuthorization(Long memberId, String templateId, Long scenicId) {
        log.debug("检查用户授权: memberId={}, templateId={}, scenicId={}", memberId, templateId, scenicId);
        return userNotificationAuthorizationMapper.selectByMemberAndTemplateAndScenic(memberId, templateId, scenicId);
    }
    
    @Override
    public Integer getRemainingCount(Long memberId, String templateId, Long scenicId) {
        log.debug("获取剩余授权次数: memberId={}, templateId={}, scenicId={}", memberId, templateId, scenicId);
        Integer remainingCount = userNotificationAuthorizationMapper.selectRemainingCount(memberId, templateId, scenicId);
        return remainingCount != null ? remainingCount : 0;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserNotificationAuthorizationEntity recordAuthorization(Long memberId, String templateId, Long scenicId) {
        return recordAuthorization(memberId, templateId, scenicId, null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserNotificationAuthorizationEntity recordAuthorization(Long memberId, String templateId, Long scenicId, String requestId) {
        log.info("记录用户授权: memberId={}, templateId={}, scenicId={}", memberId, templateId, scenicId);

        // 幂等：同一次用户授权动作（requestId）只计数一次，避免前端重试导致授权次数虚增
        if (StringUtils.isNotBlank(requestId)) {
            boolean inserted = tryInsertAuthorizationRecord(memberId, templateId, scenicId, requestId);
            if (!inserted) {
                UserNotificationAuthorizationEntity existing =
                        userNotificationAuthorizationMapper.selectByMemberAndTemplateAndScenic(memberId, templateId, scenicId);
                if (existing != null) {
                    return existing;
                }
            }
        }
        
        // 先查询是否已存在记录
        UserNotificationAuthorizationEntity existingRecord = userNotificationAuthorizationMapper
                .selectByMemberAndTemplateAndScenic(memberId, templateId, scenicId);
        
        if (existingRecord != null) {
            // 增加授权次数
            int updated = userNotificationAuthorizationMapper.increaseAuthorizationCount(existingRecord.getId(), 1);
            if (updated > 0) {
                log.info("成功增加授权次数: recordId={}, newCount={}", existingRecord.getId(), 
                        existingRecord.getAuthorizationCount() + 1);
                // 重新查询最新数据
                return userNotificationAuthorizationMapper.selectById(existingRecord.getId());
            } else {
                log.error("增加授权次数失败: recordId={}", existingRecord.getId());
                throw new RuntimeException("增加授权次数失败");
            }
        } else {
            // 创建新记录
            UserNotificationAuthorizationEntity newRecord = new UserNotificationAuthorizationEntity();
            newRecord.setMemberId(memberId);
            newRecord.setTemplateId(templateId);
            newRecord.setScenicId(scenicId);
            newRecord.setAuthorizationCount(1);
            newRecord.setConsumedCount(0);
            newRecord.setLastAuthorizedTime(new Date());
            newRecord.setStatus(1);
            newRecord.setCreateTime(new Date());
            newRecord.setUpdateTime(new Date());
            
            int inserted = userNotificationAuthorizationMapper.insert(newRecord);
            if (inserted > 0) {
                log.info("成功创建授权记录: recordId={}", newRecord.getId());
                return newRecord;
            } else {
                log.error("创建授权记录失败: memberId={}, templateId={}, scenicId={}", memberId, templateId, scenicId);
                throw new RuntimeException("创建授权记录失败");
            }
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<AuthorizationRecord> batchRecordAuthorization(Long memberId, List<String> templateIds, Long scenicId) {
        return batchRecordAuthorization(memberId, templateIds, scenicId, null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<AuthorizationRecord> batchRecordAuthorization(Long memberId, List<String> templateIds, Long scenicId, String requestId) {
        log.info("批量记录用户授权: memberId={}, templateIds={}, scenicId={}", memberId, templateIds, scenicId);
        
        List<AuthorizationRecord> results = new ArrayList<>();
        
        if (templateIds == null || templateIds.isEmpty()) {
            return results;
        }
        
        for (String templateId : templateIds) {
            AuthorizationRecord record = new AuthorizationRecord();
            record.setTemplateId(templateId);
            
            try {
                UserNotificationAuthorizationEntity entity = recordAuthorization(memberId, templateId, scenicId, requestId);
                
                // 转换为响应对象
                record.setSuccess(true);
                record.setId(entity.getId());
                record.setScenicId(entity.getScenicId());
                record.setAuthorizationCount(entity.getAuthorizationCount());
                record.setConsumedCount(entity.getConsumedCount());
                record.setRemainingCount(entity.getRemainingCount());
                record.setLastAuthorizedTime(entity.getLastAuthorizedTime());
                record.setLastConsumedTime(entity.getLastConsumedTime());
                record.setStatus(entity.getStatus());
                record.setCreateTime(entity.getCreateTime());
                
            } catch (Exception e) {
                log.error("批量授权记录失败: memberId={}, templateId={}, scenicId={}", memberId, templateId, scenicId, e);
                record.setSuccess(false);
                record.setFailureReason(e.getMessage());
            }
            
            results.add(record);
        }
        
        return results;
    }

    private boolean tryInsertAuthorizationRecord(Long memberId, String templateId, Long scenicId, String requestId) {
        try {
            UserNotificationAuthorizationRecordEntity record = new UserNotificationAuthorizationRecordEntity();
            record.setMemberId(memberId);
            record.setTemplateId(templateId);
            record.setScenicId(scenicId);
            record.setRequestId(requestId);
            record.setCreateTime(new Date());
            return userNotificationAuthorizationRecordMapper.insert(record) > 0;
        } catch (DuplicateKeyException e) {
            log.debug("授权幂等命中: memberId={}, scenicId={}, templateId={}, requestId={}",
                    memberId, scenicId, templateId, requestId);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean consumeAuthorization(Long memberId, String templateId, Long scenicId) {
        log.info("消费授权: memberId={}, templateId={}, scenicId={}", memberId, templateId, scenicId);
        
        UserNotificationAuthorizationEntity record = userNotificationAuthorizationMapper
                .selectByMemberAndTemplateAndScenic(memberId, templateId, scenicId);
        
        if (record == null) {
            log.warn("未找到授权记录: memberId={}, templateId={}, scenicId={}", memberId, templateId, scenicId);
            return false;
        }
        
        if (record.getRemainingCount() <= 0) {
            log.warn("剩余授权次数不足: recordId={}, remainingCount={}", record.getId(), record.getRemainingCount());
            return false;
        }
        
        int updated = userNotificationAuthorizationMapper.increaseConsumedCount(record.getId(), 1);
        if (updated > 0) {
            log.info("成功消费授权: recordId={}, newConsumedCount={}", record.getId(), 
                    record.getConsumedCount() + 1);
            return true;
        } else {
            log.error("消费授权失败: recordId={}", record.getId());
            return false;
        }
    }
    
    @Override
    public List<UserNotificationAuthorizationEntity> getUserAuthorizations(Long memberId) {
        log.debug("查询用户授权记录: memberId={}", memberId);
        return userNotificationAuthorizationMapper.selectByMemberId(memberId);
    }
    
    @Override
    public List<UserNotificationAuthorizationEntity> getUserAuthorizationsByTemplate(Long memberId, String templateId) {
        log.debug("查询用户模板授权记录: memberId={}, templateId={}", memberId, templateId);
        return userNotificationAuthorizationMapper.selectByMemberIdAndTemplateId(memberId, templateId);
    }
    
    @Override
    public List<UserNotificationAuthorizationEntity> getScenicAuthorizations(Long scenicId) {
        log.debug("查询景区授权记录: scenicId={}", scenicId);
        return userNotificationAuthorizationMapper.selectByScenicId(scenicId);
    }
    
    @Override
    public UserNotificationAuthorizationEntity getById(Long id) {
        log.debug("根据ID查询授权记录: id={}", id);
        return userNotificationAuthorizationMapper.selectById(id);
    }
    
    @Override
    public Map<String, UserNotificationAuthorizationEntity> batchCheckAuthorization(
            Long memberId, List<String> templateIds, Long scenicId) {
        log.debug("批量检查用户授权: memberId={}, templateIds={}, scenicId={}", memberId, templateIds, scenicId);

        Map<String, UserNotificationAuthorizationEntity> result = new HashMap<>();

        if (templateIds == null || templateIds.isEmpty()) {
            return result;
        }

        // 使用批量查询方法
        List<UserNotificationAuthorizationEntity> records =
                userNotificationAuthorizationMapper.selectBatchByTemplateIds(memberId, templateIds, scenicId);

        // 转换为Map
        Map<String, UserNotificationAuthorizationEntity> recordMap = records.stream()
                .collect(Collectors.toMap(
                        UserNotificationAuthorizationEntity::getTemplateId,
                        record -> record,
                        (existing, replacement) -> existing
                ));

        // 为每个模板ID填充结果
        for (String templateId : templateIds) {
            result.put(templateId, recordMap.get(templateId));
        }

        return result;
    }
    
    @Override
    public AuthorizationStats getAuthorizationStats(Long memberId) {
        log.debug("获取用户授权统计信息: memberId={}", memberId);
        
        List<UserNotificationAuthorizationEntity> records = getUserAuthorizations(memberId);
        
        AuthorizationStats stats = new AuthorizationStats();
        stats.setTotalTemplates(records.size());
        stats.setTotalAuthorizations(records.stream()
                .mapToInt(UserNotificationAuthorizationEntity::getAuthorizationCount)
                .sum());
        stats.setTotalConsumed(records.stream()
                .mapToInt(UserNotificationAuthorizationEntity::getConsumedCount)
                .sum());
        stats.setTotalRemaining(stats.getTotalAuthorizations() - stats.getTotalConsumed());
        stats.setQueryTime(new Date());
        
        return stats;
    }
}
