package handlers

import (
	"net/http"
	"time"

	"github.com/breakpilot/school-service/internal/models"
	"github.com/gin-gonic/gin"
)

// Attendance Handlers

// CreateAttendance creates an attendance record
func (h *Handler) CreateAttendance(c *gin.Context) {
	var req models.CreateAttendanceRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		respondError(c, http.StatusBadRequest, "Invalid request: "+err.Error())
		return
	}

	attendance, err := h.gradebookService.CreateAttendance(c.Request.Context(), &req)
	if err != nil {
		respondError(c, http.StatusInternalServerError, "Failed to create attendance: "+err.Error())
		return
	}

	respondCreated(c, attendance)
}

// GetClassAttendance returns attendance for a class
func (h *Handler) GetClassAttendance(c *gin.Context) {
	classID := c.Param("classId")
	startDateStr := c.Query("start_date")
	endDateStr := c.Query("end_date")

	var startDate, endDate *time.Time
	if startDateStr != "" {
		t, err := time.Parse("2006-01-02", startDateStr)
		if err == nil {
			startDate = &t
		}
	}
	if endDateStr != "" {
		t, err := time.Parse("2006-01-02", endDateStr)
		if err == nil {
			endDate = &t
		}
	}

	attendance, err := h.gradebookService.GetClassAttendance(c.Request.Context(), classID, startDate, endDate)
	if err != nil {
		respondError(c, http.StatusInternalServerError, "Failed to get attendance: "+err.Error())
		return
	}

	respondSuccess(c, attendance)
}

// GetStudentAttendance returns attendance for a student
func (h *Handler) GetStudentAttendance(c *gin.Context) {
	studentID := c.Param("studentId")

	attendance, err := h.gradebookService.GetStudentAttendance(c.Request.Context(), studentID)
	if err != nil {
		respondError(c, http.StatusInternalServerError, "Failed to get attendance: "+err.Error())
		return
	}

	respondSuccess(c, attendance)
}

// DeleteAttendance deletes an attendance record
func (h *Handler) DeleteAttendance(c *gin.Context) {
	attendanceID := c.Param("id")

	if err := h.gradebookService.DeleteAttendance(c.Request.Context(), attendanceID); err != nil {
		respondError(c, http.StatusInternalServerError, "Failed to delete attendance: "+err.Error())
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Attendance deleted"})
}

// BulkCreateAttendance creates attendance for multiple students
func (h *Handler) BulkCreateAttendance(c *gin.Context) {
	classID := c.Param("classId")

	var req struct {
		Date    string `json:"date" binding:"required"`
		Records []struct {
			StudentID string                  `json:"student_id" binding:"required"`
			Status    models.AttendanceStatus `json:"status" binding:"required"`
			Periods   int                     `json:"periods"`
			Reason    string                  `json:"reason"`
		} `json:"records" binding:"required"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		respondError(c, http.StatusBadRequest, "Invalid request: "+err.Error())
		return
	}

	records := make([]struct {
		StudentID string
		Status    models.AttendanceStatus
		Periods   int
		Reason    string
	}, len(req.Records))

	for i, r := range req.Records {
		records[i] = struct {
			StudentID string
			Status    models.AttendanceStatus
			Periods   int
			Reason    string
		}{
			StudentID: r.StudentID,
			Status:    r.Status,
			Periods:   r.Periods,
			Reason:    r.Reason,
		}
	}

	if err := h.gradebookService.BulkCreateAttendance(c.Request.Context(), classID, req.Date, records); err != nil {
		respondError(c, http.StatusInternalServerError, "Failed to create attendance: "+err.Error())
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Attendance created"})
}

// Gradebook Entry Handlers

// CreateGradebookEntry creates a gradebook entry
func (h *Handler) CreateGradebookEntry(c *gin.Context) {
	var req models.CreateGradebookEntryRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		respondError(c, http.StatusBadRequest, "Invalid request: "+err.Error())
		return
	}

	entry, err := h.gradebookService.CreateGradebookEntry(c.Request.Context(), &req)
	if err != nil {
		respondError(c, http.StatusInternalServerError, "Failed to create entry: "+err.Error())
		return
	}

	respondCreated(c, entry)
}

// GetGradebookEntries returns entries for a class
func (h *Handler) GetGradebookEntries(c *gin.Context) {
	classID := c.Param("classId")
	entryTypeStr := c.Query("entry_type")
	startDateStr := c.Query("start_date")
	endDateStr := c.Query("end_date")

	var entryType *string
	if entryTypeStr != "" {
		entryType = &entryTypeStr
	}

	var startDate, endDate *time.Time
	if startDateStr != "" {
		t, err := time.Parse("2006-01-02", startDateStr)
		if err == nil {
			startDate = &t
		}
	}
	if endDateStr != "" {
		t, err := time.Parse("2006-01-02", endDateStr)
		if err == nil {
			endDate = &t
		}
	}

	entries, err := h.gradebookService.GetGradebookEntries(c.Request.Context(), classID, entryType, startDate, endDate)
	if err != nil {
		respondError(c, http.StatusInternalServerError, "Failed to get entries: "+err.Error())
		return
	}

	respondSuccess(c, entries)
}

// GetStudentEntries returns gradebook entries for a student
func (h *Handler) GetStudentEntries(c *gin.Context) {
	studentID := c.Param("studentId")

	entries, err := h.gradebookService.GetStudentEntries(c.Request.Context(), studentID)
	if err != nil {
		respondError(c, http.StatusInternalServerError, "Failed to get entries: "+err.Error())
		return
	}

	respondSuccess(c, entries)
}

// DeleteGradebookEntry deletes a gradebook entry
func (h *Handler) DeleteGradebookEntry(c *gin.Context) {
	entryID := c.Param("id")

	if err := h.gradebookService.DeleteGradebookEntry(c.Request.Context(), entryID); err != nil {
		respondError(c, http.StatusInternalServerError, "Failed to delete entry: "+err.Error())
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Entry deleted"})
}
