package com.gameplatform.server.service.link;

import com.gameplatform.server.mapper.agent.LinkBatchMapper;
import com.gameplatform.server.mapper.agent.LinkTaskMapper;
import com.gameplatform.server.model.dto.link.LinkListItem;
import com.gameplatform.server.model.dto.link.LinkListRequest;
import com.gameplatform.server.model.dto.link.LinkListResponse;
import com.gameplatform.server.model.entity.agent.LinkBatch;
import com.gameplatform.server.model.entity.agent.LinkTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 链接列表查询服务
 */
@Service
public class LinkListService {
    private static final Logger log = LoggerFactory.getLogger(LinkListService.class);

    private final LinkTaskMapper linkTaskMapper;
    private final LinkBatchMapper linkBatchMapper;

    public LinkListService(LinkTaskMapper linkTaskMapper, LinkBatchMapper linkBatchMapper) {
        this.linkTaskMapper = linkTaskMapper;
        this.linkBatchMapper = linkBatchMapper;
    }

    /**
     * 分页查询链接列表
     */
    public Mono<LinkListResponse> getLinkList(Long agentId, LinkListRequest request) {
        return Mono.fromCallable(() -> {
            log.info("=== 开始查询链接列表 ===");
            log.info("代理ID: {}, 请求参数: {}", agentId, request);
            
            // 计算偏移量
            int offset = (request.getPage() - 1) * request.getPageSize();
            
            // 验证排序参数
            validateSortParams(request);
            
            // 查询链接任务列表
            List<LinkTask> linkTasks = linkTaskMapper.findLinkTasksWithConditions(
                agentId,
                request.getStatus(),
                request.getBatchId(),
                request.getIsExpired(),
                request.getSortBy(),
                request.getSortDir(),
                offset,
                request.getPageSize()
            );
            
            // 查询总数
            long total = linkTaskMapper.countLinkTasksWithConditions(
                agentId,
                request.getStatus(),
                request.getBatchId(),
                request.getIsExpired()
            );
            
            log.info("查询到 {} 条记录，总数: {}", linkTasks.size(), total);
            
            // 获取所有相关的批次信息
            Map<Long, LinkBatch> batchMap = getBatchMap(linkTasks);
            
            // 转换为DTO
            List<LinkListItem> items = linkTasks.stream()
                .map(task -> convertToListItem(task, batchMap.get(task.getBatchId())))
                .collect(Collectors.toList());
            
            // 构建响应
            LinkListResponse response = new LinkListResponse();
            response.setItems(items);
            response.setTotal(total);
            response.setPage(request.getPage());
            response.setPageSize(request.getPageSize());
            response.setTotalPages((int) Math.ceil((double) total / request.getPageSize()));
            response.setHasNext(request.getPage() * request.getPageSize() < total);
            response.setHasPrev(request.getPage() > 1);
            
            log.info("链接列表查询完成: 当前页={}, 每页大小={}, 总页数={}", 
                    response.getPage(), response.getPageSize(), response.getTotalPages());
            
            return response;
        });
    }

    /**
     * 验证排序参数
     */
    private void validateSortParams(LinkListRequest request) {
        String sortBy = request.getSortBy();
        if (sortBy != null && !List.of("createdAt", "updatedAt", "expireAt").contains(sortBy)) {
            request.setSortBy("createdAt");
            log.warn("无效的排序字段 '{}', 使用默认值 'createdAt'", sortBy);
        }
        
        String sortDir = request.getSortDir();
        if (sortDir != null && !List.of("ASC", "DESC").contains(sortDir.toUpperCase())) {
            request.setSortDir("DESC");
            log.warn("无效的排序方向 '{}', 使用默认值 'DESC'", sortDir);
        } else if (sortDir != null) {
            request.setSortDir(sortDir.toUpperCase());
        }
    }

    /**
     * 获取批次信息映射
     */
    private Map<Long, LinkBatch> getBatchMap(List<LinkTask> linkTasks) {
        if (linkTasks.isEmpty()) {
            return Map.of();
        }
        
        List<Long> batchIds = linkTasks.stream()
            .map(LinkTask::getBatchId)
            .distinct()
            .collect(Collectors.toList());
        
        try {
            List<LinkBatch> batches = linkBatchMapper.findByIds(batchIds);
            return batches.stream()
                .collect(Collectors.toMap(LinkBatch::getId, batch -> batch));
        } catch (Exception e) {
            log.error("获取批次信息失败: {}", e.getMessage(), e);
            return Map.of();
        }
    }

    /**
     * 转换为列表项DTO
     */
    private LinkListItem convertToListItem(LinkTask task, LinkBatch batch) {
        LinkListItem item = new LinkListItem();
        
        // 基本信息
        item.setCodeNo(task.getCodeNo());
        item.setBatchId(task.getBatchId());
        item.setStatus(task.getStatus());
        item.setStatusDesc(getStatusDesc(task.getStatus()));
        item.setExpireAt(task.getExpireAt());
        item.setRegion(task.getRegion());
        item.setMachineId(task.getMachineId());
        item.setLoginAt(task.getLoginAt());
        item.setCreatedAt(task.getCreatedAt());
        item.setUpdatedAt(task.getUpdatedAt());
        
        // 计算是否过期和剩余时间
        // expire_at字段只在状态为EXPIRED时才有值，表示过期时间戳
        LocalDateTime now = LocalDateTime.now();
        boolean isExpired = "EXPIRED".equals(task.getStatus());
        long remainingSeconds = 0L;
        
        // 根据不同状态计算剩余时间
        if (isExpired) {
            remainingSeconds = 0L;
        } else {
            // 非过期状态显示为永不过期
            remainingSeconds = Long.MAX_VALUE;
        }
        
        item.setIsExpired(isExpired);
        item.setRemainingSeconds(remainingSeconds);
        
        // 从批次信息中获取任务详情
        if (batch != null) {
            item.setQuantity(batch.getQuantity());
            item.setTimes(batch.getTimes());
            item.setTotalPoints(batch.getQuantity() * batch.getTimes());
        } else {
            // 如果批次信息不存在，设置默认值
            log.warn("批次信息不存在: batchId={}", task.getBatchId());
            item.setQuantity(0);
            item.setTimes(0);
            item.setTotalPoints(0);
        }
        
        return item;
    }

    /**
     * 获取状态描述
     */
    private String getStatusDesc(String status) {
        return switch (status) {
            case "NEW" -> "新建";
            case "USING" -> "使用中";
            case "LOGGED_IN" -> "已登录";
            case "COMPLETED" -> "已完成";
            case "REFUNDED" -> "已退款";
            case "EXPIRED" -> "已过期";
            default -> "未知状态";
        };
    }
}
