/**
 * 自然写互动课堂教学管理云平台软件 V1.0
 * 
 * 版权所有 (C) 2026
 * 软件全称：自然写互动课堂教学管理云平台软件
 * 版本号：V1.0
 * 
 * 本文件为云平台主启动类，负责 Spring Boot 应用初始化、
 * 微服务配置加载、健康检查端点注册及全局异常处理。
 */
package com.writech.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.http.HttpStatus;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 自然写互动课堂教学管理云平台 - 主启动类
 * 
 * 系统采用微服务架构，按领域拆分为用户服务、课堂服务、
 * 作业服务、设备服务、消息服务等多个独立微服务模块。
 * 通过 Nginx/Kong API Gateway 统一接入，使用 Kafka 
 * 进行异步消息传递，Redis 实现会话与缓存管理。
 */
@SpringBootApplication
@EnableDiscoveryClient
@EnableAsync
@EnableScheduling
public class WritechCloudApplication {

    /**
     * 应用主入口
     * 启动 Spring Boot 容器，加载所有微服务组件
     */
    public static void main(String[] args) {
        SpringApplication.run(WritechCloudApplication.class, args);
    }

    /**
     * 跨域配置
     * 允许前端应用和各终端 APP 跨域访问云平台 API
     */
    @Configuration
    public static class CorsConfig implements WebMvcConfigurer {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/api/**")
                    .allowedOriginPatterns("*")
                    .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                    .allowedHeaders("*")
                    .allowCredentials(true)
                    .maxAge(3600);
        }
    }

    /**
     * 全局异常处理器
     * 统一捕获并格式化所有未处理异常，返回标准 JSON 响应
     * 响应格式：{"code": 200, "msg": "success", "data": {...}}
     */
    @RestControllerAdvice
    public static class GlobalExceptionHandler {

        /**
         * 处理业务异常
         * 业务逻辑中抛出的自定义异常，返回对应的错误码和提示信息
         */
        @ExceptionHandler(BusinessException.class)
        public ResponseEntity<ApiResponse<?>> handleBusinessException(BusinessException ex) {
            ApiResponse<?> response = ApiResponse.error(ex.getCode(), ex.getMessage());
            return ResponseEntity.status(HttpStatus.OK).body(response);
        }

        /**
         * 处理参数校验异常
         * 请求参数不符合校验规则时返回详细的校验错误信息
         */
        @ExceptionHandler(IllegalArgumentException.class)
        public ResponseEntity<ApiResponse<?>> handleIllegalArgument(IllegalArgumentException ex) {
            ApiResponse<?> response = ApiResponse.error(400, "参数校验失败: " + ex.getMessage());
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
        }

        /**
         * 处理未知异常
         * 兜底处理所有未预见的系统异常，记录日志并返回统一错误响应
         */
        @ExceptionHandler(Exception.class)
        public ResponseEntity<ApiResponse<?>> handleException(Exception ex) {
            ApiResponse<?> response = ApiResponse.error(500, "系统内部错误，请稍后重试");
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }

    /**
     * 统一 API 响应包装类
     * 所有接口统一使用此格式返回数据
     * 格式：{"code": 200, "msg": "success", "data": {...}}
     */
    public static class ApiResponse<T> {
        private int code;
        private String msg;
        private T data;
        private LocalDateTime timestamp;

        public ApiResponse() {
            this.timestamp = LocalDateTime.now();
        }

        public ApiResponse(int code, String msg, T data) {
            this.code = code;
            this.msg = msg;
            this.data = data;
            this.timestamp = LocalDateTime.now();
        }

        /** 成功响应（带数据） */
        public static <T> ApiResponse<T> success(T data) {
            return new ApiResponse<>(200, "success", data);
        }

        /** 成功响应（无数据） */
        public static <T> ApiResponse<T> success() {
            return new ApiResponse<>(200, "success", null);
        }

        /** 错误响应 */
        public static <T> ApiResponse<T> error(int code, String msg) {
            return new ApiResponse<>(code, msg, null);
        }

        public int getCode() { return code; }
        public void setCode(int code) { this.code = code; }
        public String getMsg() { return msg; }
        public void setMsg(String msg) { this.msg = msg; }
        public T getData() { return data; }
        public void setData(T data) { this.data = data; }
        public LocalDateTime getTimestamp() { return timestamp; }
        public void setTimestamp(LocalDateTime timestamp) { this.timestamp = timestamp; }
    }

    /**
     * 自定义业务异常类
     * 用于在业务逻辑中抛出可预见的异常，包含错误码和消息
     */
    public static class BusinessException extends RuntimeException {
        private final int code;

        public BusinessException(int code, String message) {
            super(message);
            this.code = code;
        }

        public int getCode() { return code; }
    }
}
