package handlers

import (
	"net/http"
	"strconv"

	"github.com/breakpilot/ai-compliance-sdk/internal/rbac"
	"github.com/breakpilot/ai-compliance-sdk/internal/training"
	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
)

// ============================================================================
// Module Endpoints
// ============================================================================

// ListModules returns all training modules for the tenant
// GET /sdk/v1/training/modules
func (h *TrainingHandlers) ListModules(c *gin.Context) {
	tenantID := rbac.GetTenantID(c)

	filters := &training.ModuleFilters{
		Limit:  50,
		Offset: 0,
	}

	if v := c.Query("regulation_area"); v != "" {
		filters.RegulationArea = training.RegulationArea(v)
	}
	if v := c.Query("frequency_type"); v != "" {
		filters.FrequencyType = training.FrequencyType(v)
	}
	if v := c.Query("search"); v != "" {
		filters.Search = v
	}
	if v := c.Query("limit"); v != "" {
		if n, err := strconv.Atoi(v); err == nil {
			filters.Limit = n
		}
	}
	if v := c.Query("offset"); v != "" {
		if n, err := strconv.Atoi(v); err == nil {
			filters.Offset = n
		}
	}

	modules, total, err := h.store.ListModules(c.Request.Context(), tenantID, filters)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, training.ModuleListResponse{
		Modules: modules,
		Total:   total,
	})
}

// GetModule returns a single training module with content and quiz
// GET /sdk/v1/training/modules/:id
func (h *TrainingHandlers) GetModule(c *gin.Context) {
	id, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid module ID"})
		return
	}

	module, err := h.store.GetModule(c.Request.Context(), id)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	if module == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "module not found"})
		return
	}

	// Include content and quiz questions
	content, _ := h.store.GetPublishedContent(c.Request.Context(), id)
	questions, _ := h.store.ListQuizQuestions(c.Request.Context(), id)

	c.JSON(http.StatusOK, gin.H{
		"module":    module,
		"content":   content,
		"questions": questions,
	})
}

// CreateModule creates a new training module
// POST /sdk/v1/training/modules
func (h *TrainingHandlers) CreateModule(c *gin.Context) {
	tenantID := rbac.GetTenantID(c)

	var req training.CreateModuleRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	module := &training.TrainingModule{
		TenantID:        tenantID,
		ModuleCode:      req.ModuleCode,
		Title:           req.Title,
		Description:     req.Description,
		RegulationArea:  req.RegulationArea,
		NIS2Relevant:    req.NIS2Relevant,
		ISOControls:     req.ISOControls,
		FrequencyType:   req.FrequencyType,
		ValidityDays:    req.ValidityDays,
		RiskWeight:      req.RiskWeight,
		ContentType:     req.ContentType,
		DurationMinutes: req.DurationMinutes,
		PassThreshold:   req.PassThreshold,
	}

	if module.ValidityDays == 0 {
		module.ValidityDays = 365
	}
	if module.RiskWeight == 0 {
		module.RiskWeight = 2.0
	}
	if module.ContentType == "" {
		module.ContentType = "text"
	}
	if module.PassThreshold == 0 {
		module.PassThreshold = 70
	}
	if module.ISOControls == nil {
		module.ISOControls = []string{}
	}

	if err := h.store.CreateModule(c.Request.Context(), module); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusCreated, module)
}

// UpdateModule updates a training module
// PUT /sdk/v1/training/modules/:id
func (h *TrainingHandlers) UpdateModule(c *gin.Context) {
	id, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid module ID"})
		return
	}

	module, err := h.store.GetModule(c.Request.Context(), id)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	if module == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "module not found"})
		return
	}

	var req training.UpdateModuleRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if req.Title != nil {
		module.Title = *req.Title
	}
	if req.Description != nil {
		module.Description = *req.Description
	}
	if req.NIS2Relevant != nil {
		module.NIS2Relevant = *req.NIS2Relevant
	}
	if req.ISOControls != nil {
		module.ISOControls = req.ISOControls
	}
	if req.ValidityDays != nil {
		module.ValidityDays = *req.ValidityDays
	}
	if req.RiskWeight != nil {
		module.RiskWeight = *req.RiskWeight
	}
	if req.DurationMinutes != nil {
		module.DurationMinutes = *req.DurationMinutes
	}
	if req.PassThreshold != nil {
		module.PassThreshold = *req.PassThreshold
	}
	if req.IsActive != nil {
		module.IsActive = *req.IsActive
	}

	if err := h.store.UpdateModule(c.Request.Context(), module); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, module)
}

// DeleteModule deletes a training module
// DELETE /sdk/v1/training/modules/:id
func (h *TrainingHandlers) DeleteModule(c *gin.Context) {
	id, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid module ID"})
		return
	}

	module, err := h.store.GetModule(c.Request.Context(), id)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	if module == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "module not found"})
		return
	}

	if err := h.store.DeleteModule(c.Request.Context(), id); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

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