package com.example.demo.model;

import java.time.LocalDateTime;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Index;
import jakarta.persistence.Table;

/**
 * 用户错误日志实体
 * 用于记录和统计用户操作过程中产生的错误
 */
@Entity
@Table(name = "user_error_log", indexes = {
    @Index(name = "idx_username", columnList = "username"),
    @Index(name = "idx_error_type", columnList = "error_type"),
    @Index(name = "idx_created_at", columnList = "created_at"),
    @Index(name = "idx_error_source", columnList = "error_source")
})
public class UserErrorLog {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "username", length = 100)
    private String username; // 可能为空（未登录用户）

    @Enumerated(EnumType.STRING)
    @Column(name = "error_type", nullable = false, length = 50)
    private ErrorType errorType;

    @Column(name = "error_code", length = 50)
    private String errorCode;

    @Column(name = "error_message", columnDefinition = "TEXT")
    private String errorMessage;

    @Column(name = "error_source", nullable = false, length = 100)
    private String errorSource; // 错误来源（服务类名或接口路径）

    @Column(name = "task_id", length = 100)
    private String taskId; // 关联的任务ID（如果有）

    @Column(name = "task_type", length = 50)
    private String taskType; // 任务类型

    @Column(name = "request_path", length = 500)
    private String requestPath; // 请求路径

    @Column(name = "request_method", length = 10)
    private String requestMethod; // 请求方法 GET/POST等

    @Column(name = "request_params", columnDefinition = "TEXT")
    private String requestParams; // 请求参数（JSON格式，敏感信息需脱敏）

    @Column(name = "stack_trace", columnDefinition = "TEXT")
    private String stackTrace; // 堆栈跟踪（可选，用于调试）

    @Column(name = "ip_address", length = 50)
    private String ipAddress;

    @Column(name = "user_agent", length = 500)
    private String userAgent;

    @Column(name = "created_at", nullable = false)
    private LocalDateTime createdAt;

    /**
     * 错误类型枚举
     */
    public enum ErrorType {
        // 任务相关错误
        TASK_SUBMIT_ERROR("任务提交失败"),
        TASK_PROCESSING_ERROR("任务处理失败"),
        TASK_TIMEOUT("任务超时"),
        TASK_CANCELLED("任务取消"),
        
        // API相关错误
        API_CALL_ERROR("API调用失败"),
        API_RESPONSE_ERROR("API响应异常"),
        API_TIMEOUT("API超时"),
        
        // 支付相关错误
        PAYMENT_ERROR("支付失败"),
        PAYMENT_CALLBACK_ERROR("支付回调异常"),
        REFUND_ERROR("退款失败"),
        
        // 认证相关错误
        AUTH_ERROR("认证失败"),
        TOKEN_EXPIRED("Token过期"),
        PERMISSION_DENIED("权限不足"),
        
        // 数据相关错误
        DATA_VALIDATION_ERROR("数据验证失败"),
        DATA_NOT_FOUND("数据未找到"),
        DATA_CONFLICT("数据冲突"),
        
        // 文件相关错误
        FILE_UPLOAD_ERROR("文件上传失败"),
        FILE_DOWNLOAD_ERROR("文件下载失败"),
        FILE_PROCESS_ERROR("文件处理失败"),
        
        // 系统错误
        SYSTEM_ERROR("系统错误"),
        DATABASE_ERROR("数据库错误"),
        NETWORK_ERROR("网络错误"),
        
        // 其他
        UNKNOWN("未知错误");

        private final String description;

        ErrorType(String description) {
            this.description = description;
        }

        public String getDescription() {
            return description;
        }
    }

    // 构造函数
    public UserErrorLog() {
        this.createdAt = LocalDateTime.now();
    }

    public UserErrorLog(String username, ErrorType errorType, String errorMessage, String errorSource) {
        this();
        this.username = username;
        this.errorType = errorType;
        this.errorMessage = errorMessage;
        this.errorSource = errorSource;
    }

    // 静态工厂方法 - 快速创建任务错误日志
    public static UserErrorLog createTaskError(String username, String taskId, String taskType, 
                                                ErrorType errorType, String errorMessage) {
        UserErrorLog log = new UserErrorLog(username, errorType, errorMessage, "TaskService");
        log.setTaskId(taskId);
        log.setTaskType(taskType);
        return log;
    }

    // 静态工厂方法 - 快速创建API错误日志
    public static UserErrorLog createApiError(String username, String requestPath, 
                                               String errorMessage, String errorCode) {
        UserErrorLog log = new UserErrorLog(username, ErrorType.API_CALL_ERROR, errorMessage, "ApiService");
        log.setRequestPath(requestPath);
        log.setErrorCode(errorCode);
        return log;
    }

    // Getters and Setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public ErrorType getErrorType() {
        return errorType;
    }

    public void setErrorType(ErrorType errorType) {
        this.errorType = errorType;
    }

    public String getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(String errorCode) {
        this.errorCode = errorCode;
    }

    public String getErrorMessage() {
        return errorMessage;
    }

    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }

    public String getErrorSource() {
        return errorSource;
    }

    public void setErrorSource(String errorSource) {
        this.errorSource = errorSource;
    }

    public String getTaskId() {
        return taskId;
    }

    public void setTaskId(String taskId) {
        this.taskId = taskId;
    }

    public String getTaskType() {
        return taskType;
    }

    public void setTaskType(String taskType) {
        this.taskType = taskType;
    }

    public String getRequestPath() {
        return requestPath;
    }

    public void setRequestPath(String requestPath) {
        this.requestPath = requestPath;
    }

    public String getRequestMethod() {
        return requestMethod;
    }

    public void setRequestMethod(String requestMethod) {
        this.requestMethod = requestMethod;
    }

    public String getRequestParams() {
        return requestParams;
    }

    public void setRequestParams(String requestParams) {
        this.requestParams = requestParams;
    }

    public String getStackTrace() {
        return stackTrace;
    }

    public void setStackTrace(String stackTrace) {
        this.stackTrace = stackTrace;
    }

    public String getIpAddress() {
        return ipAddress;
    }

    public void setIpAddress(String ipAddress) {
        this.ipAddress = ipAddress;
    }

    public String getUserAgent() {
        return userAgent;
    }

    public void setUserAgent(String userAgent) {
        this.userAgent = userAgent;
    }

    public LocalDateTime getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(LocalDateTime createdAt) {
        this.createdAt = createdAt;
    }

    @Override
    public String toString() {
        return "UserErrorLog{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", errorType=" + errorType +
                ", errorCode='" + errorCode + '\'' +
                ", errorSource='" + errorSource + '\'' +
                ", createdAt=" + createdAt +
                '}';
    }
}
