package controllers

import (
	"fmt"
	"net/http"
	"strconv"
	"time"

	"learnsteam/learsteam-quiz-api/internal/models"
	"learnsteam/learsteam-quiz-api/internal/services"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
)

type QuizController interface {
	List(*gin.Context)
	Find(*gin.Context)
	Create(*gin.Context)
	Update(*gin.Context)
}

type quizController struct {
	service services.QuizService
}

func NewQuizController(service services.QuizService) QuizController {
	return &quizController{
		service: service,
	}
}

// Quiz List
//
// @Summary 퀴즈 목록 가져오기
// @Description 퀴즈 목록을 가져옵니다.
// @Tags 	Quiz
//
// @Accept json
// @Produce json
//
// @Param program_id query string true "프로그램 ID"
// @Param q query string false "검색어"
// @Param page query int false "페이지"
// @Param limit query int false "페이지 사이즈"
//
// @Success 200 {object} models.QuizListResponse
// @Router /quiz  [get]
func (controller *quizController) List(c *gin.Context) {
	program_id := c.DefaultQuery("program_id", "")
	page, err := strconv.Atoi(c.DefaultQuery("page", "1"))
	if err != nil {
		fmt.Println("error : page")
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	limit, err := strconv.Atoi(c.DefaultQuery("limit", "10"))
	if err != nil {
		fmt.Println("error : limit")
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	result, err := controller.service.List(program_id, page, limit)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	totalNumber, err := controller.service.Total(program_id)
	if err != nil {
		fmt.Println("error : list")
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	totalPage := int64(totalNumber/int64(limit) + 1)

	c.JSON(http.StatusOK, gin.H{"data": result, "total": totalNumber, "page": page, "totalPage": totalPage, "pageSize": limit})
}

// Get Quiz
//
// @Summary 퀴즈 가져오기
// @Description ID로 퀴즈를 가져옵니다.
// @Tags 	Quiz
//
// @Accept json
// @Produce json
//
// @Param id path string true "퀴즈 ID"
//
// @Success 200 {object} models.QuizResponse
// @Router /quiz/{id} [get]
func (controller *quizController) Find(c *gin.Context) {
	id := c.Param("id")

	result, err := controller.service.Find(id)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, result)
}

// Create Quiz
//
// @Summary 퀴즈 생성
// @Description 퀴즈를 만듭니다.
// @Tags 	Quiz
//
// @Accept json
// @Produce json
//
// @Param program_id body string true "프로그램 ID"
// @Param sequence body int true "퀴즈 순서"
// @Param quiz_type body string true "퀴즈 타입 : choice, check, ox, input"
// @Param question body string true "퀴즈 문제"
// @Param choice body []string true "퀴즈 선택지 : ['선택1','선택2','선택3', '선택4']"
// @Param answer body []string true "퀴즈 정답 : [1,3]"
// @Param hint body string true "퀴즈 힌트"
// @Param comment body string true "퀴즈 해설"
//
// @Success 200 {object} models.QuizResponse
// @Router /quiz [post]
func (controller *quizController) Create(c *gin.Context) {
	var request models.QuizRequest
	if err := c.ShouldBindJSON(&request); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	quiz := &models.Quiz{
		ID:        uuid.NewString(),
		ProgramID: request.ProgramID,
		Sequence:  request.Sequence,
		QuizType:  request.QuizType,
		Question:  request.Question,
		Choice:    request.Choice,
		Answer:    request.Answer,
		Hint:      request.Hint,
		Comment:   request.Comment,
		UpdatedAt: time.Now(),
		CreatedAt: time.Now(),
	}

	result, err := controller.service.Create(quiz)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, result)
}

// Update Quiz
//
// @Summary 퀴즈 수정
// @Description 퀴즈를 수정합니다.
// @Tags 	Quiz
//
// @Accept json
// @Produce json
//
// @Param id path string true "퀴즈 ID"
// @Param program_id body string true "프로그램 ID"
// @Param sequence body int true "퀴즈 순서"
// @Param quiz_type body string true "퀴즈 타입 : choice, check, ox, input"
// @Param question body string true "퀴즈 문제"
// @Param choice body []string true "퀴즈 선택지 : ['선택1','선택2','선택3', '선택4']"
// @Param answer body []string true "퀴즈 정답 : [1,3]"
// @Param hint body string true "퀴즈 힌트"
// @Param comment body string true "퀴즈 해설"
//
// @Success 200 {object} models.QuizResponse
// @Router /quiz [put]
func (controller *quizController) Update(c *gin.Context) {
	id := c.Param("id")
	var request models.QuizRequest
	if err := c.ShouldBindJSON(&request); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	quiz, err := controller.service.Find(id)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	quiz.ProgramID = request.ProgramID
	quiz.Sequence = request.Sequence
	quiz.QuizType = request.QuizType
	quiz.Question = request.Question
	quiz.Choice = request.Choice
	quiz.Answer = request.Answer
	quiz.Hint = request.Hint
	quiz.Comment = request.Comment
	quiz.UpdatedAt = time.Now()

	result, err := controller.service.Update(quiz)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, result)
}
