package cn.novalon.gym.manage.datacount.handler;

import cn.novalon.gym.manage.datacount.domain.*;
import cn.novalon.gym.manage.datacount.service.IDataStatisticsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 数据统计 Handler
 *
 * @author system
 * @date 2026-06-09
 */
@Component
@Tag(name = "数据统计", description = "数据统计相关操作")
public class DataStatisticsHandler {

    @Autowired
    private IDataStatisticsService dataStatisticsService;

    @Operation(summary = "获取综合统计数据", description = "获取会员、预约、签到综合统计数据")
    public Mono<ServerResponse> getStatisticsSummary(ServerRequest request) {
        StatisticsQuery query = buildQueryFromRequest(request);

        return dataStatisticsService.getStatisticsSummaryWithCache(query)
                .flatMap(summary -> ServerResponse.ok().bodyValue(summary))
                .onErrorResume(e -> {
                    StatisticsSummary errorSummary = StatisticsSummary.builder()
                            .statDate(LocalDateTime.now().toLocalDate().toString())
                            .generatedAt(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME))
                            .build();
                    return ServerResponse.ok().bodyValue(errorSummary);
                });
    }

    @Operation(summary = "获取会员统计数据", description = "获取会员统计数据")
    public Mono<ServerResponse> getMemberStatistics(ServerRequest request) {
        StatisticsQuery query = buildQueryFromRequest(request);

        return dataStatisticsService.getMemberStatistics(query)
                .flatMap(stats -> ServerResponse.ok().bodyValue(stats))
                .onErrorResume(e -> ServerResponse.ok().bodyValue(MemberStatistics.builder().statDate(query.getStartTime() != null ? query.getStartTime().toLocalDate().toString() : LocalDateTime.now().toLocalDate().toString()).build()));
    }

    @Operation(summary = "获取预约统计数据", description = "获取预约统计数据")
    public Mono<ServerResponse> getBookingStatistics(ServerRequest request) {
        StatisticsQuery query = buildQueryFromRequest(request);

        return dataStatisticsService.getBookingStatistics(query)
                .flatMap(stats -> ServerResponse.ok().bodyValue(stats))
                .onErrorResume(e -> ServerResponse.ok().bodyValue(BookingStatistics.builder().statDate(query.getStartTime() != null ? query.getStartTime().toLocalDate().toString() : LocalDateTime.now().toLocalDate().toString()).build()));
    }

    @Operation(summary = "获取签到统计数据", description = "获取签到统计数据")
    public Mono<ServerResponse> getSignInStatistics(ServerRequest request) {
        StatisticsQuery query = buildQueryFromRequest(request);

        return dataStatisticsService.getSignInStatistics(query)
                .flatMap(stats -> ServerResponse.ok().bodyValue(stats))
                .onErrorResume(e -> ServerResponse.ok().bodyValue(SignInStatistics.builder().statDate(query.getStartTime() != null ? query.getStartTime().toLocalDate().toString() : LocalDateTime.now().toLocalDate().toString()).build()));
    }

    @Operation(summary = "查询历史统计数据", description = "查询历史统计数据")
    public Mono<ServerResponse> queryHistoricalStatistics(ServerRequest request) {
        StatisticsQuery query = buildQueryFromRequest(request);

        return dataStatisticsService.queryHistoricalStatistics(query)
                .collectList()
                .flatMap(stats -> ServerResponse.ok().bodyValue(stats));
    }

    @Operation(summary = "导出统计数据", description = "导出统计数据为Excel文件")
    public Mono<ServerResponse> exportStatistics(ServerRequest request) {
        StatisticsQuery query = buildQueryFromRequest(request);

        return dataStatisticsService.exportStatistics(query)
                .flatMap(bytes -> {
                    String filename = "statistics_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + ".xlsx";
                    return ServerResponse.ok()
                            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"")
                            .contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
                            .bodyValue(bytes);
                })
                .onErrorResume(e -> ServerResponse.ok().bodyValue("导出失败: " + e.getMessage()));
    }

    private StatisticsQuery buildQueryFromRequest(ServerRequest request) {
        StatisticsQuery.StatisticsQueryBuilder builder = StatisticsQuery.builder();

        request.queryParam("statType").ifPresent(builder::statType);
        request.queryParam("periodType").ifPresent(builder::periodType);
        request.queryParam("startTime").ifPresent(startTimeStr -> {
            try {
                builder.startTime(LocalDateTime.parse(startTimeStr, DateTimeFormatter.ISO_LOCAL_DATE_TIME));
            } catch (Exception e) {
                try {
                    builder.startTime(LocalDateTime.parse(startTimeStr));
                } catch (Exception ignored) {
                }
            }
        });
        request.queryParam("endTime").ifPresent(endTimeStr -> {
            try {
                builder.endTime(LocalDateTime.parse(endTimeStr, DateTimeFormatter.ISO_LOCAL_DATE_TIME));
            } catch (Exception e) {
                try {
                    builder.endTime(LocalDateTime.parse(endTimeStr));
                } catch (Exception ignored) {
                }
            }
        });

        return builder.build();
    }
}
