package handlers

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// DetectionService 检测服务
type DetectionService struct {
	DB *gorm.DB
}

// StartDetectionRequest 发起检测请求
type StartDetectionRequest struct {
	ClassID      uint   `json:"class_id" binding:"required"`
	TeacherID    uint   `json:"teacher_id" binding:"required"`
	StudentCount int    `json:"student_count" binding:"required"`
	DetectionType string `json:"detection_type" binding:"required,oneof=vision fatigue training"` // vision, fatigue, training
	StartTime    *time.Time `json:"start_time"`
}

// StartDetectionResponse 发起检测响应
type StartDetectionResponse struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Data    struct {
		TaskID    string    `json:"task_id"`
		TaskNo    string    `json:"task_no"`
		StartTime time.Time `json:"start_time"`
	} `json:"data"`
}

// SubmitDetectionRequest 提交检测结果请求
type SubmitDetectionRequest struct {
	StudentID      uint      `json:"student_id" binding:"required"`
	DetectionID    string    `json:"detection_id" binding:"required"`
	Vision         VisionData `json:"vision"`
	EyeMovement    EyeMovementData `json:"eye_movement"`
	Response       ResponseData `json:"response"`
	Timestamp      int64     `json:"timestamp"`
	DeviceID       *uint     `json:"device_id"`
}

// SubmitDetectionResponse 提交检测结果响应
type SubmitDetectionResponse struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Data    struct {
		ID string `json:"id"`
	} `json:"data"`
}

// GetDetectionReportRequest 获取检测报告请求
type GetDetectionReportRequest struct {
	DetectionID string `json:"detection_id" uri:"detection_id"`
	StudentID   uint   `json:"student_id" uri:"student_id"`
}

// GetDetectionReportResponse 获取检测报告响应
type GetDetectionReportResponse struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Data    DetectionReport `json:"data"`
}

// GetDetectionHistoryRequest 获取检测历史请求
type GetDetectionHistoryRequest struct {
	StudentID uint      `form:"student_id"`
	ClassID   uint      `form:"class_id"`
	StartDate time.Time `form:"start_date"`
	EndDate   time.Time `form:"end_date"`
	Page      int       `form:"page,default=1"`
	PageSize  int       `form:"page_size,default=20"`
}

// GetDetectionHistoryResponse 获取检测历史响应
type GetDetectionHistoryResponse struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Data    struct {
		Items []DetectionHistory `json:"items"`
		Total int                `json:"total"`
		Page  int                `json:"page"`
	} `json:"data"`
}

// GetClassStatsRequest 获取班级统计请求
type GetClassStatsRequest struct {
	ClassID   uint      `form:"class_id" uri:"class_id" binding:"required"`
	StartDate time.Time `form:"start_date"`
	EndDate   time.Time `form:"end_date"`
}

// GetClassStatsResponse 获取班级统计响应
type GetClassStatsResponse struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Data    ClassStats `json:"data"`
}

// ClassStats 班级统计数据
type ClassStats struct {
	ClassID           uint             `json:"class_id"`
	ClassName         string           `json:"class_name"`
	TotalStudents     int              `json:"total_students"`
	TestedStudents    int              `json:"tested_students"`
	AvgVisionLeft     float64          `json:"avg_vision_left"`
	AvgVisionRight    float64          `json:"avg_vision_right"`
	VisionDeclineCount int             `json:"vision_decline_count"`
	AvgFatigueScore   float64          `json:"avg_fatigue_score"`
	AlertCount        int              `json:"alert_count"`
	AlertDistribution map[string]int   `json:"alert_distribution"`
	CreatedAt         time.Time        `json:"created_at"`
}

// VisionData 视力数据
type VisionData struct {
	VisionLeft  float64 `json:"vision_left"`
	VisionRight float64 `json:"vision_right"`
	Confidence  string  `json:"confidence"` // high, medium, low
}

// EyeMovementData 眼动数据
type EyeMovementData struct {
	LeftEye   PupilData `json:"left_eye"`
	RightEye  PupilData `json:"right_eye"`
	GazePoint GazePoint `json:"gaze_point"`
	Timestamp int64     `json:"timestamp"`
}

// PupilData 瞳孔数据
type PupilData struct {
	X          float64 `json:"x"`
	Y          float64 `json:"y"`
	Radius     float64 `json:"radius"`
	Confidence float64 `json:"confidence"`
}

// GazePoint 注视点
type GazePoint struct {
	X          float64 `json:"x"`
	Y          float64 `json:"y"`
	Confidence float64 `json:"confidence"`
}

// ResponseData 响应数据
type ResponseData struct {
	Accuracy     float64 `json:"accuracy"`      // 准确率
	ResponseType float64 `json:"response_time"` // 响应时间
	Errors       int     `json:"errors"`        // 错误次数
}

// DetectionReport 检测报告
type DetectionReport struct {
	ID             uint            `json:"id"`
	StudentID      uint            `json:"student_id"`
	Student        interface{}     `json:"student"`
	DetectionID    uint            `json:"detection_id"`
	Detection      interface{}     `json:"detection"`
	Vision         VisionData      `json:"vision"`
	EyeMovement    EyeMovementData `json:"eye_movement"`
	Response       ResponseData    `json:"response"`
	FatigueScore   float64         `json:"fatigue_score"`
	AlertLevel     string          `json:"alert_level"` // normal, warning, alert
	AIAnalysis     interface{}     `json:"ai_analysis"` // AI分析结果
	CreatedAt      time.Time       `json:"created_at"`
}

// DetectionHistory 检测历史
type DetectionHistory struct {
	ID             uint      `json:"id"`
	StudentID      uint      `json:"student_id"`
	Student        interface{} `json:"student"`
	ClassID        uint      `json:"class_id"`
	Class          interface{} `json:"class"`
	Vision         VisionData `json:"vision"`
	FatigueScore   float64   `json:"fatigue_score"`
	AlertLevel     string    `json:"alert_level"`
	DetectionTime  time.Time `json:"detection_time"`
	CreatedAt      time.Time `json:"created_at"`
}

// NewDetectionService 创建检测服务
func NewDetectionService(db *gorm.DB) *DetectionService {
	return &DetectionService{DB: db}
}

// StartDetection 发起检测
func (s *DetectionService) StartDetection(c *gin.Context) {
	var req StartDetectionRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "参数错误: " + err.Error(),
		})
		return
	}

	// 创建检测任务
	task := map[string]interface{}{
		"task_no":        generateTaskNo(), // 生成任务编号
		"class_id":       req.ClassID,
		"teacher_id":     req.TeacherID,
		"student_count":  req.StudentCount,
		"detection_type": req.DetectionType,
		"start_time":     req.StartTime,
		"status":         0, // 0:进行中
	}

	result := s.DB.Table("detection_tasks").Create(task)
	if result.Error != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "发起检测失败: " + result.Error.Error(),
		})
		return
	}

	// 返回响应
	resp := StartDetectionResponse{
		Code:    0,
		Message: "检测任务已创建",
	}
	resp.Data.TaskID = "task_" + string(rune(result.RowsAffected)) // 简化处理
	resp.Data.TaskNo = task["task_no"].(string)
	resp.Data.StartTime = time.Now()

	c.JSON(http.StatusOK, resp)
}

// SubmitDetection 提交检测结果
func (s *DetectionService) SubmitDetection(c *gin.Context) {
	var req SubmitDetectionRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "参数错误: " + err.Error(),
		})
		return
	}

	// 创建检测记录
	detection := map[string]interface{}{
		"task_id":        req.DetectionID, // 这里应该是task_id而不是detection_id
		"student_id":     req.StudentID,
		"detection_time": time.Now(),
		"vision_left":    req.Vision.VisionLeft,
		"vision_right":   req.Vision.VisionRight,
		"fatigue_score":  req.Response.Accuracy, // 使用响应准确率作为疲劳分数示例
		"device_id":      req.DeviceID,
		"status":         1,
	}

	result := s.DB.Table("detections").Create(detection)
	if result.Error != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "提交检测结果失败: " + result.Error.Error(),
		})
		return
	}

	resp := SubmitDetectionResponse{
		Code:    0,
		Message: "检测结果提交成功",
	}
	resp.Data.ID = "detection_" + string(rune(result.RowsAffected))

	c.JSON(http.StatusOK, resp)
}

// GetDetectionReport 获取检测报告
func (s *DetectionService) GetDetectionReport(c *gin.Context) {
	var req GetDetectionReportRequest
	if err := c.ShouldBindUri(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "参数错误: " + err.Error(),
		})
		return
	}

	// 查询检测报告
	var report DetectionReport
	result := s.DB.Table("detection_reports").Where("detection_id = ? AND student_id = ?", req.DetectionID, req.StudentID).First(&report)
	if result.Error != nil {
		if result.Error == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, gin.H{
				"code":    404,
				"message": "检测报告不存在",
			})
			return
		}
		
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "查询检测报告失败: " + result.Error.Error(),
		})
		return
	}

	resp := GetDetectionReportResponse{
		Code:    0,
		Message: "获取成功",
		Data:    report,
	}

	c.JSON(http.StatusOK, resp)
}

// GetDetectionHistory 获取检测历史
func (s *DetectionService) GetDetectionHistory(c *gin.Context) {
	var req GetDetectionHistoryRequest
	if err := c.ShouldBindQuery(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "参数错误: " + err.Error(),
		})
		return
	}

	// 构建查询条件
	query := s.DB.Table("detection_history")
	
	if req.StudentID != 0 {
		query = query.Where("student_id = ?", req.StudentID)
	}
	if req.ClassID != 0 {
		query = query.Where("class_id = ?", req.ClassID)
	}
	if !req.StartDate.IsZero() {
		query = query.Where("detection_time >= ?", req.StartDate)
	}
	if !req.EndDate.IsZero() {
		query = query.Where("detection_time <= ?", req.EndDate)
	}

	// 查询总数
	var total int64
	query.Count(&total)

	// 查询数据
	var histories []DetectionHistory
	query.Offset((req.Page - 1) * req.PageSize).Limit(req.PageSize).Find(&histories)

	resp := GetDetectionHistoryResponse{
		Code:    0,
		Message: "获取成功",
	}
	resp.Data.Items = histories
	resp.Data.Total = int(total)
	resp.Data.Page = req.Page

	c.JSON(http.StatusOK, resp)
}

// GetClassStats 获取班级统计
func (s *DetectionService) GetClassStats(c *gin.Context) {
	var req GetClassStatsRequest
	if err := c.ShouldBindUri(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "参数错误: " + err.Error(),
		})
		return
	}

	// 获取班级信息
	var classInfo struct {
		ID   uint   `json:"id"`
		Name string `json:"name"`
	}
	s.DB.Table("classes").Select("id, name").Where("id = ?", req.ClassID).First(&classInfo)

	// 计算统计信息
	var stats ClassStats
	stats.ClassID = req.ClassID
	stats.ClassName = classInfo.Name

	// 统计学生总数
	var totalStudents int64
	s.DB.Table("students").Where("class_id = ?", req.ClassID).Count(&totalStudents)
	stats.TotalStudents = int(totalStudents)

	// 统计参与检测的学生数
	var testedStudents int64
	s.DB.Table("detections").
		Joins("JOIN detection_tasks ON detections.task_id = detection_tasks.id").
		Where("detection_tasks.class_id = ?", req.ClassID).
		Distinct("student_id").Count(&testedStudents)
	stats.TestedStudents = int(testedStudents)

	// 计算平均视力
	var resultAvg struct {
		AvgLeft  float64 `json:"avg_left"`
		AvgRight float64 `json:"avg_right"`
	}
	s.DB.Table("detections").
		Joins("JOIN detection_tasks ON detections.task_id = detection_tasks.id").
		Where("detection_tasks.class_id = ?", req.ClassID).
		Select("AVG(vision_left) as avg_left, AVG(vision_right) as avg_right").
		Scan(&resultAvg)
	
	stats.AvgVisionLeft = resultAvg.AvgLeft
	stats.AvgVisionRight = resultAvg.AvgRight

	// 统计预警数量
	var alertCount int64
	s.DB.Table("alerts").
		Joins("JOIN students ON alerts.student_id = students.id").
		Where("students.class_id = ?", req.ClassID).
		Count(&alertCount)
	stats.AlertCount = int(alertCount)

	// 预警分布
	alertDist := make(map[string]int)
	alertDist["green"] = 0  // 示例数据
	alertDist["yellow"] = 0
	alertDist["orange"] = 0
	alertDist["red"] = 0
	stats.AlertDistribution = alertDist

	stats.CreatedAt = time.Now()

	resp := GetClassStatsResponse{
		Code:    0,
		Message: "获取成功",
		Data:    stats,
	}

	c.JSON(http.StatusOK, resp)
}

// generateTaskNo 生成任务编号 - 使用更安全的随机ID
func generateTaskNo() string {
	// 生成随机ID
	b := make([]byte, 8)
	_, err := rand.Read(b)
	if err != nil {
		// 如果随机数生成失败，使用时间戳+简单随机数作为备用
		return fmt.Sprintf("task_%d_%x", time.Now().UnixNano(), b[:4])
	}
	
	randomID := hex.EncodeToString(b)
	return fmt.Sprintf("task_%s_%s", time.Now().Format("20060102_150405"), randomID[:8])
}