package handlers

import (
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"

	"github.com/Nanqipro/YunQue-Tech-Projects/ai_english_learning/serve/internal/common"
	"github.com/Nanqipro/YunQue-Tech-Projects/ai_english_learning/serve/internal/models"
	"github.com/Nanqipro/YunQue-Tech-Projects/ai_english_learning/serve/internal/services"
	"github.com/Nanqipro/YunQue-Tech-Projects/ai_english_learning/serve/internal/utils"
)

// TestHandler 测试处理器
type TestHandler struct {
	testService *services.TestService
}

// NewTestHandler 创建测试处理器实例
func NewTestHandler(testService *services.TestService) *TestHandler {
	return &TestHandler{
		testService: testService,
	}
}

// GetTestTemplates 获取测试模板列表
// @Summary 获取测试模板列表
// @Tags Test
// @Param type query string false "测试类型"
// @Param difficulty query string false "难度"
// @Param page query int false "页码"
// @Param page_size query int false "每页数量"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/templates [get]
func (h *TestHandler) GetTestTemplates(c *gin.Context) {
	typeStr := c.Query("type")
	difficultyStr := c.Query("difficulty")
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))

	var testType *models.TestType
	if typeStr != "" {
		t := models.TestType(typeStr)
		testType = &t
	}

	var difficulty *models.TestDifficulty
	if difficultyStr != "" {
		d := models.TestDifficulty(difficultyStr)
		difficulty = &d
	}

	templates, total, err := h.testService.GetTestTemplates(testType, difficulty, page, pageSize)
	if err != nil {
		common.ErrorResponse(c, http.StatusInternalServerError, "获取测试模板失败")
		return
	}

	common.SuccessResponse(c, gin.H{
		"templates": templates,
		"pagination": gin.H{
			"page":       page,
			"page_size":  pageSize,
			"total":      total,
			"total_page": (total + int64(pageSize) - 1) / int64(pageSize),
		},
	})
}

// GetTestTemplateByID 获取测试模板详情
// @Summary 获取测试模板详情
// @Tags Test
// @Param id path string true "模板ID"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/templates/{id} [get]
func (h *TestHandler) GetTestTemplateByID(c *gin.Context) {
	id := c.Param("id")

	template, err := h.testService.GetTestTemplateByID(id)
	if err != nil {
		common.ErrorResponse(c, http.StatusNotFound, "测试模板不存在")
		return
	}

	common.SuccessResponse(c, gin.H{"data": template})
}

// CreateTestSession 创建测试会话
// @Summary 创建测试会话
// @Tags Test
// @Param body body object true "请求体"
// @Success 201 {object} common.Response
// @Router /api/v1/tests/sessions [post]
func (h *TestHandler) CreateTestSession(c *gin.Context) {
	userID, exists := utils.GetUserIDFromContext(c)
	if !exists {
		common.BadRequestResponse(c, "请先登录")
		return
	}

	var req struct {
		TemplateID string `json:"template_id" binding:"required"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		common.BadRequestResponse(c, "请求参数错误")
		return
	}

	session, err := h.testService.CreateTestSession(req.TemplateID, utils.Int64ToString(userID))
	if err != nil {
		common.ErrorResponse(c, http.StatusInternalServerError, "创建测试会话失败: "+err.Error())
		return
	}

	common.SuccessResponseWithStatus(c, http.StatusCreated, gin.H{"data": session})
}

// GetTestSession 获取测试会话
// @Summary 获取测试会话
// @Tags Test
// @Param id path string true "会话ID"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/sessions/{id} [get]
func (h *TestHandler) GetTestSession(c *gin.Context) {
	sessionID := c.Param("id")

	session, err := h.testService.GetTestSession(sessionID)
	if err != nil {
		common.ErrorResponse(c, http.StatusNotFound, "测试会话不存在")
		return
	}

	// 验证用户权限
	userID, _ := utils.GetUserIDFromContext(c)
	if session.UserID != utils.Int64ToString(userID) {
		common.ErrorResponse(c, http.StatusForbidden, "无权访问此测试会话")
		return
	}

	common.SuccessResponse(c, gin.H{"data": session})
}

// StartTest 开始测试
// @Summary 开始测试
// @Tags Test
// @Param id path string true "会话ID"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/sessions/{id}/start [put]
func (h *TestHandler) StartTest(c *gin.Context) {
	sessionID := c.Param("id")

	// 验证用户权限
	session, err := h.testService.GetTestSession(sessionID)
	if err != nil {
		common.ErrorResponse(c, http.StatusNotFound, "测试会话不存在")
		return
	}

	userID, _ := utils.GetUserIDFromContext(c)
	if session.UserID != utils.Int64ToString(userID) {
		common.ErrorResponse(c, http.StatusForbidden, "无权操作此测试会话")
		return
	}

	updatedSession, err := h.testService.StartTest(sessionID)
	if err != nil {
		common.ErrorResponse(c, http.StatusBadRequest, err.Error())
		return
	}

	common.SuccessResponse(c, gin.H{"data": updatedSession})
}

// SubmitAnswer 提交答案
// @Summary 提交答案
// @Tags Test
// @Param id path string true "会话ID"
// @Param body body object true "请求体"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/sessions/{id}/answers [post]
func (h *TestHandler) SubmitAnswer(c *gin.Context) {
	sessionID := c.Param("id")

	var req struct {
		QuestionID string `json:"question_id" binding:"required"`
		Answer     string `json:"answer" binding:"required"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		common.BadRequestResponse(c, "请求参数错误")
		return
	}

	// 验证用户权限
	session, err := h.testService.GetTestSession(sessionID)
	if err != nil {
		common.ErrorResponse(c, http.StatusNotFound, "测试会话不存在")
		return
	}

	userID, _ := utils.GetUserIDFromContext(c)
	if session.UserID != utils.Int64ToString(userID) {
		common.ErrorResponse(c, http.StatusForbidden, "无权操作此测试会话")
		return
	}

	updatedSession, err := h.testService.SubmitAnswer(sessionID, req.QuestionID, req.Answer)
	if err != nil {
		common.ErrorResponse(c, http.StatusBadRequest, err.Error())
		return
	}

	common.SuccessResponse(c, gin.H{"data": updatedSession})
}

// PauseTest 暂停测试
// @Summary 暂停测试
// @Tags Test
// @Param id path string true "会话ID"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/sessions/{id}/pause [put]
func (h *TestHandler) PauseTest(c *gin.Context) {
	sessionID := c.Param("id")

	// 验证用户权限
	session, err := h.testService.GetTestSession(sessionID)
	if err != nil {
		common.ErrorResponse(c, http.StatusNotFound, "测试会话不存在")
		return
	}

	userID, _ := utils.GetUserIDFromContext(c)
	if session.UserID != utils.Int64ToString(userID) {
		common.ErrorResponse(c, http.StatusForbidden, "无权操作此测试会话")
		return
	}

	updatedSession, err := h.testService.PauseTest(sessionID)
	if err != nil {
		common.ErrorResponse(c, http.StatusBadRequest, err.Error())
		return
	}

	common.SuccessResponse(c, gin.H{"data": updatedSession})
}

// ResumeTest 恢复测试
// @Summary 恢复测试
// @Tags Test
// @Param id path string true "会话ID"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/sessions/{id}/resume [put]
func (h *TestHandler) ResumeTest(c *gin.Context) {
	sessionID := c.Param("id")

	// 验证用户权限
	session, err := h.testService.GetTestSession(sessionID)
	if err != nil {
		common.ErrorResponse(c, http.StatusNotFound, "测试会话不存在")
		return
	}

	userID, _ := utils.GetUserIDFromContext(c)
	if session.UserID != utils.Int64ToString(userID) {
		common.ErrorResponse(c, http.StatusForbidden, "无权操作此测试会话")
		return
	}

	updatedSession, err := h.testService.ResumeTest(sessionID)
	if err != nil {
		common.ErrorResponse(c, http.StatusBadRequest, err.Error())
		return
	}

	common.SuccessResponse(c, gin.H{"data": updatedSession})
}

// CompleteTest 完成测试
// @Summary 完成测试
// @Tags Test
// @Param id path string true "会话ID"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/sessions/{id}/complete [put]
func (h *TestHandler) CompleteTest(c *gin.Context) {
	sessionID := c.Param("id")

	// 验证用户权限
	session, err := h.testService.GetTestSession(sessionID)
	if err != nil {
		common.ErrorResponse(c, http.StatusNotFound, "测试会话不存在")
		return
	}

	userID, _ := utils.GetUserIDFromContext(c)
	if session.UserID != utils.Int64ToString(userID) {
		common.ErrorResponse(c, http.StatusForbidden, "无权操作此测试会话")
		return
	}

	result, err := h.testService.CompleteTest(sessionID)
	if err != nil {
		common.ErrorResponse(c, http.StatusBadRequest, err.Error())
		return
	}

	common.SuccessResponse(c, gin.H{"data": result})
}

// GetUserTestHistory 获取用户测试历史
// @Summary 获取用户测试历史
// @Tags Test
// @Param page query int false "页码"
// @Param page_size query int false "每页数量"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/sessions [get]
func (h *TestHandler) GetUserTestHistory(c *gin.Context) {
	userID, exists := utils.GetUserIDFromContext(c)
	if !exists {
		common.BadRequestResponse(c, "请先登录")
		return
	}

	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10"))

	results, total, err := h.testService.GetUserTestHistory(utils.Int64ToString(userID), page, pageSize)
	if err != nil {
		common.ErrorResponse(c, http.StatusInternalServerError, "获取测试历史失败")
		return
	}

	common.SuccessResponse(c, gin.H{
		"sessions": results,
		"pagination": gin.H{
			"page":       page,
			"page_size":  pageSize,
			"total":      total,
			"total_page": (total + int64(pageSize) - 1) / int64(pageSize),
		},
	})
}

// GetTestResultByID 获取测试结果详情
// @Summary 获取测试结果详情
// @Tags Test
// @Param id path string true "结果ID"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/results/{id} [get]
func (h *TestHandler) GetTestResultByID(c *gin.Context) {
	resultID := c.Param("id")

	result, err := h.testService.GetTestResultByID(resultID)
	if err != nil {
		common.ErrorResponse(c, http.StatusNotFound, "测试结果不存在")
		return
	}

	// 验证用户权限
	userID, _ := utils.GetUserIDFromContext(c)
	if result.UserID != utils.Int64ToString(userID) {
		common.ErrorResponse(c, http.StatusForbidden, "无权访问此测试结果")
		return
	}

	common.SuccessResponse(c, gin.H{"data": result})
}

// GetUserTestStats 获取用户测试统计
// @Summary 获取用户测试统计
// @Tags Test
// @Success 200 {object} common.Response
// @Router /api/v1/tests/stats [get]
func (h *TestHandler) GetUserTestStats(c *gin.Context) {
	userID, exists := utils.GetUserIDFromContext(c)
	if !exists {
		common.BadRequestResponse(c, "请先登录")
		return
	}

	stats, err := h.testService.GetUserTestStats(utils.Int64ToString(userID))
	if err != nil {
		common.ErrorResponse(c, http.StatusInternalServerError, "获取测试统计失败")
		return
	}

	common.SuccessResponse(c, stats)
}

// DeleteTestResult 删除测试结果
// @Summary 删除测试结果
// @Tags Test
// @Param id path string true "结果ID"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/results/{id} [delete]
func (h *TestHandler) DeleteTestResult(c *gin.Context) {
	resultID := c.Param("id")

	// 验证用户权限
	result, err := h.testService.GetTestResultByID(resultID)
	if err != nil {
		common.ErrorResponse(c, http.StatusNotFound, "测试结果不存在")
		return
	}

	userID, _ := utils.GetUserIDFromContext(c)
	if result.UserID != utils.Int64ToString(userID) {
		common.ErrorResponse(c, http.StatusForbidden, "无权删除此测试结果")
		return
	}

	if err := h.testService.DeleteTestResult(resultID); err != nil {
		common.ErrorResponse(c, http.StatusInternalServerError, "删除测试结果失败")
		return
	}

	common.SuccessResponse(c, gin.H{"message": "删除成功"})
}
