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

import cn.novalon.gym.manage.common.dto.PageRequest;
import cn.novalon.gym.manage.common.util.RedisUtil;
import cn.novalon.gym.manage.groupcourse.domain.GroupCourse;
import cn.novalon.gym.manage.groupcourse.domain.GroupCourseDetail;
import cn.novalon.gym.manage.groupcourse.dto.GroupCourseQueryDto;
import cn.novalon.gym.manage.groupcourse.service.IGroupCourseService;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Validator;
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.util.HashMap;
import java.util.Map;

@Component
@Tag(name="团课管理",description = "团课相关操作")
public class GroupCourseHandler {
    private final IGroupCourseService groupCourseService;
    private final Validator validator;
    private final RedisUtil redisUtil;
    private final ObjectMapper objectMapper;
    
    public GroupCourseHandler(IGroupCourseService groupCourseService, 
                              Validator validator,
                              RedisUtil redisUtil,
                              ObjectMapper objectMapper){
        this.groupCourseService = groupCourseService;
        this.validator = validator;
        this.redisUtil = redisUtil;
        this.objectMapper = objectMapper;
    }

    @Operation(summary = "获取所有团课", description = "获取系统中所有团课列表")
    public Mono<ServerResponse> getAllGroupCourse(ServerRequest request){
        boolean includeDeleted = Boolean.valueOf(request.queryParam("includeDeleted").orElse("false"));
        return ServerResponse.ok()
                .body(groupCourseService.findAll(includeDeleted), GroupCourse.class);
    }

    @Operation(summary = "分页获取团课", description = "根据分页参数获取团课列表")
    public Mono<ServerResponse> getGroupCoursesByPage(ServerRequest request) {
        return request.bodyToMono(PageRequest.class)
                .flatMap(pageRequest -> {
                    boolean includeDeleted = request.queryParam("includeDeleted")
                            .map(Boolean::parseBoolean)
                            .orElse(false);
                    
                    if (pageRequest.getPage() < 0) {
                        pageRequest.setPage(0);
                    }
                    if (pageRequest.getSize() <= 0 || pageRequest.getSize() > 100) {
                        pageRequest.setSize(10);
                    }
                    if (pageRequest.getSort() == null || pageRequest.getSort().isEmpty()) {
                        pageRequest.setSort("id");
                    }
                    if (pageRequest.getOrder() == null || pageRequest.getOrder().isEmpty()) {
                        pageRequest.setOrder("asc");
                    }

                    return groupCourseService.findByPage(pageRequest, includeDeleted)
                            .flatMap(response -> ServerResponse.ok().bodyValue(response));
                });
    }

    @Operation(summary = "根据ID获取团课", description = "根据ID获取团课详情")
    public Mono<ServerResponse> getGroupCourseById(ServerRequest request){
        Long id = Long.valueOf(request.pathVariable("id"));
        return groupCourseService.findById(id)
                .flatMap(course -> ServerResponse.ok().bodyValue(course))
                .switchIfEmpty(ServerResponse.notFound().build());
    }

    @Operation(summary = "根据ID获取团课完整信息", description = "根据ID获取团课完整信息，包括团课基础信息、类型信息和标签信息")
    public Mono<ServerResponse> getGroupCourseDetailById(ServerRequest request){
        Long id = Long.valueOf(request.pathVariable("id"));
        return groupCourseService.findDetailById(id)
                .flatMap(detail -> ServerResponse.ok().bodyValue(detail))
                .switchIfEmpty(ServerResponse.notFound().build());
    }

    @Operation(summary = "创建团课", description = "创建新的团课")
    public Mono<ServerResponse> createGroupCourse(ServerRequest request) {
        return request.bodyToMono(GroupCourse.class)
                .flatMap(groupCourse -> {
                    if (groupCourse.getCourseName() == null || groupCourse.getCourseName().isEmpty()) {
                        Map<String, Object> error = new HashMap<>();
                        error.put("success", false);
                        error.put("message", "课程名称不能为空");
                        return ServerResponse.badRequest().bodyValue(error);
                    }
                    
                    return groupCourseService.create(groupCourse)
                            .flatMap(course -> {
                                Map<String, Object> response = new HashMap<>();
                                response.put("success", true);
                                response.put("message", "团课创建成功");
                                response.put("data", course);
                                return ServerResponse.ok().bodyValue(response);
                            })
                            .onErrorResume(error -> {
                                Map<String, Object> response = new HashMap<>();
                                response.put("success", false);
                                response.put("message", error.getMessage());
                                return ServerResponse.badRequest().bodyValue(response);
                            });
                });
    }

    @Operation(summary = "更新团课", description = "更新指定团课信息")
    public Mono<ServerResponse> updateGroupCourse(ServerRequest request) {
        Long id = Long.valueOf(request.pathVariable("id"));
        
        return request.bodyToMono(GroupCourse.class)
                .flatMap(groupCourse -> {
                    return groupCourseService.update(id, groupCourse)
                            .flatMap(course -> {
                                Map<String, Object> response = new HashMap<>();
                                response.put("success", true);
                                response.put("message", "团课更新成功");
                                response.put("data", course);
                                return ServerResponse.ok().bodyValue(response);
                            })
                            .onErrorResume(error -> {
                                Map<String, Object> response = new HashMap<>();
                                response.put("success", false);
                                response.put("message", error.getMessage());
                                return ServerResponse.badRequest().bodyValue(response);
                            });
                });
    }

    @Operation(summary = "取消团课", description = "取消指定团课（需提前24小时）")
    public Mono<ServerResponse> cancelGroupCourse(ServerRequest request) {
        Long id = Long.valueOf(request.pathVariable("id"));
        
        return groupCourseService.cancel(id)
                .flatMap(course -> {
                    Map<String, Object> response = new HashMap<>();
                    response.put("success", true);
                    response.put("message", "团课取消成功");
                    response.put("data", course);
                    return ServerResponse.ok().bodyValue(response);
                })
                .onErrorResume(error -> {
                    Map<String, Object> response = new HashMap<>();
                    response.put("success", false);
                    response.put("message", error.getMessage());
                    return ServerResponse.badRequest().bodyValue(response);
                });
    }

    @Operation(summary = "团课签到", description = "会员签到参加团课")
    public Mono<ServerResponse> signIn(ServerRequest request) {
        Long memberId = Long.valueOf(request.pathVariable("memberId"));
        
        return request.bodyToMono(Map.class)
                .flatMap(body -> {
                    if (body == null || body.isEmpty()) {
                        Map<String, Object> response = new HashMap<>();
                        response.put("success", false);
                        response.put("message", "请求体不能为空");
                        return ServerResponse.badRequest().bodyValue(response);
                    }
                    
                    Object courseIdObj = body.get("courseId");
                    if (courseIdObj == null) {
                        Map<String, Object> response = new HashMap<>();
                        response.put("success", false);
                        response.put("message", "courseId不能为空");
                        return ServerResponse.badRequest().bodyValue(response);
                    }
                    
                    Long courseId = ((Number) courseIdObj).longValue();
                    
                    return groupCourseService.signIn(courseId, memberId)
                            .flatMap(course -> {
                                Map<String, Object> response = new HashMap<>();
                                response.put("success", true);
                                response.put("message", "签到成功");
                                response.put("data", course);
                                return ServerResponse.ok().bodyValue(response);
                            })
                            .onErrorResume(error -> {
                                Map<String, Object> response = new HashMap<>();
                                response.put("success", false);
                                response.put("message", error.getMessage());
                                return ServerResponse.badRequest().bodyValue(response);
                            });
                });
    }

    @Operation(summary = "删除团课", description = "删除指定团课（软删除）")
    public Mono<ServerResponse> deleteGroupCourse(ServerRequest request) {
        Long id = Long.valueOf(request.pathVariable("id"));
        
        return groupCourseService.delete(id)
                .then(Mono.defer(() -> {
                    Map<String, Object> response = new HashMap<>();
                    response.put("success", true);
                    response.put("message", "团课删除成功");
                    return ServerResponse.ok().bodyValue(response);
                }))
                .onErrorResume(error -> {
                    Map<String, Object> response = new HashMap<>();
                    response.put("success", false);
                    response.put("message", error.getMessage());
                    return ServerResponse.badRequest().bodyValue(response);
                });
    }

    @Operation(summary = "多条件查询团课", description = "支持团课名称模糊查询、类型筛选、日期范围、时间段、价格排序、剩余名额排序等多条件组合查询")
    public Mono<ServerResponse> searchGroupCourses(ServerRequest request) {
        return request.bodyToMono(GroupCourseQueryDto.class)
                .flatMap(query -> {
                    return groupCourseService.searchGroupCourses(query)
                            .flatMap(response -> {
                                Map<String, Object> result = new HashMap<>();
                                result.put("success", true);
                                result.put("message", "查询成功");
                                result.put("data", response);
                                return ServerResponse.ok().bodyValue(result);
                            });
                })
                .onErrorResume(error -> {
                    Map<String, Object> errorResponse = new HashMap<>();
                    errorResponse.put("success", false);
                    errorResponse.put("message", error.getMessage());
                    return ServerResponse.badRequest().bodyValue(errorResponse);
                });
    }

    @Operation(summary = "测试-根据Key获取Redis缓存", description = "测试接口：根据传入的key值获取Redis中缓存的数据")
    public Mono<ServerResponse> getCacheByKey(ServerRequest request) {
        return request.bodyToMono(Map.class)
                .flatMap(body -> {
                    String key = (String) body.get("key");
                    
                    if (key == null || key.isEmpty()) {
                        Map<String, Object> error = new HashMap<>();
                        error.put("success", false);
                        error.put("message", "key参数不能为空");
                        return ServerResponse.badRequest().bodyValue(error);
                    }
                    
                    return redisUtil.get(key)
                            .map(cachedValue -> {
                                Map<String, Object> result = new HashMap<>();
                                if (cachedValue != null) {
                                    result.put("success", true);
                                    result.put("key", key);
                                    result.put("value", cachedValue);
                                    result.put("message", "缓存命中");
                                    
                                    try {
                                        if (cachedValue instanceof String) {
                                            Object jsonObject = objectMapper.readValue((String) cachedValue, Object.class);
                                            result.put("parsedValue", jsonObject);
                                            result.put("valueType", "JSON字符串");
                                        } else {
                                            result.put("valueType", cachedValue.getClass().getSimpleName());
                                        }
                                    } catch (Exception e) {
                                        result.put("parsedValue", null);
                                        result.put("valueType", "无法解析");
                                    }
                                } else {
                                    result.put("success", false);
                                    result.put("key", key);
                                    result.put("value", null);
                                    result.put("message", "缓存未命中");
                                }
                                
                                return result;
                            })
                            .flatMap(result -> ServerResponse.ok().bodyValue(result))
                            .onErrorResume(error -> {
                                Map<String, Object> errorResponse = new HashMap<>();
                                errorResponse.put("success", false);
                                errorResponse.put("message", "请求处理失败: " + error.getMessage());
                                return ServerResponse.status(500).bodyValue(errorResponse);
                            });
                });
    }
}
