package handlers

import (
	"net/http"
	"time"

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

// WorkshopHandlers handles workshop session HTTP requests
type WorkshopHandlers struct {
	store *workshop.Store
}

// NewWorkshopHandlers creates new workshop handlers
func NewWorkshopHandlers(store *workshop.Store) *WorkshopHandlers {
	return &WorkshopHandlers{store: store}
}

// ============================================================================
// Session Management
// ============================================================================

// CreateSession creates a new workshop session
// POST /sdk/v1/workshops
func (h *WorkshopHandlers) CreateSession(c *gin.Context) {
	var req workshop.CreateSessionRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	tenantID := rbac.GetTenantID(c)
	userID := rbac.GetUserID(c)

	session := &workshop.Session{
		TenantID:       tenantID,
		Title:          req.Title,
		Description:    req.Description,
		SessionType:    req.SessionType,
		WizardSchema:   req.WizardSchema,
		Status:         workshop.SessionStatusDraft,
		CurrentStep:    1,
		TotalSteps:     10, // Default, will be updated when wizard is loaded
		ScheduledStart: req.ScheduledStart,
		ScheduledEnd:   req.ScheduledEnd,
		AssessmentID:   req.AssessmentID,
		RoadmapID:      req.RoadmapID,
		PortfolioID:    req.PortfolioID,
		Settings:       req.Settings,
		CreatedBy:      userID,
	}

	// Set default settings if not provided
	if !session.Settings.AllowBackNavigation {
		session.Settings.AllowBackNavigation = true
	}
	if !session.Settings.AllowNotes {
		session.Settings.AllowNotes = true
	}
	if !session.Settings.AutoSave {
		session.Settings.AutoSave = true
	}

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

	// Add creator as facilitator
	facilitator := &workshop.Participant{
		SessionID:  session.ID,
		UserID:     &userID,
		Name:       "Session Owner",
		Role:       workshop.ParticipantRoleFacilitator,
		CanEdit:    true,
		CanComment: true,
		CanApprove: true,
	}
	h.store.AddParticipant(c.Request.Context(), facilitator)

	c.JSON(http.StatusCreated, workshop.CreateSessionResponse{
		Session:  *session,
		JoinCode: session.JoinCode,
	})
}

// ListSessions lists workshop sessions
// GET /sdk/v1/workshops
func (h *WorkshopHandlers) ListSessions(c *gin.Context) {
	tenantID := rbac.GetTenantID(c)

	filters := &workshop.SessionFilters{
		Limit: 50,
	}

	if status := c.Query("status"); status != "" {
		filters.Status = workshop.SessionStatus(status)
	}
	if sessionType := c.Query("type"); sessionType != "" {
		filters.SessionType = sessionType
	}

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

	c.JSON(http.StatusOK, gin.H{
		"sessions": sessions,
		"total":    len(sessions),
	})
}

// GetSession retrieves a session with details
// GET /sdk/v1/workshops/:id
func (h *WorkshopHandlers) GetSession(c *gin.Context) {
	id, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid session ID"})
		return
	}

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

	// Get responses for current step
	stepNumber := summary.Session.CurrentStep
	responses, _ := h.store.GetResponses(c.Request.Context(), id, &stepNumber)

	// Get stats
	stats, _ := h.store.GetSessionStats(c.Request.Context(), id)

	c.JSON(http.StatusOK, gin.H{
		"session":       summary.Session,
		"participants":  summary.Participants,
		"step_progress": summary.StepProgress,
		"responses":     responses,
		"stats":         stats,
		"progress":      summary.OverallProgress,
	})
}

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

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

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

	session.Title = req.Title
	session.Description = req.Description
	session.ScheduledStart = req.ScheduledStart
	session.ScheduledEnd = req.ScheduledEnd
	session.Settings = req.Settings

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

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

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

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

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

// ============================================================================
// Session Status Control
// ============================================================================

// StartSession starts a workshop session
// POST /sdk/v1/workshops/:id/start
func (h *WorkshopHandlers) StartSession(c *gin.Context) {
	id, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid session ID"})
		return
	}

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

	if session.Status != workshop.SessionStatusDraft && session.Status != workshop.SessionStatusScheduled && session.Status != workshop.SessionStatusPaused {
		c.JSON(http.StatusBadRequest, gin.H{"error": "session cannot be started from current state"})
		return
	}

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

	// Initialize first step progress
	h.store.UpdateStepProgress(c.Request.Context(), id, 1, "in_progress", 0)

	session.Status = workshop.SessionStatusActive
	now := time.Now().UTC()
	session.ActualStart = &now

	c.JSON(http.StatusOK, gin.H{"session": session, "message": "session started"})
}

// PauseSession pauses a workshop session
// POST /sdk/v1/workshops/:id/pause
func (h *WorkshopHandlers) PauseSession(c *gin.Context) {
	id, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid session ID"})
		return
	}

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

	c.JSON(http.StatusOK, gin.H{"message": "session paused"})
}

// CompleteSession completes a workshop session
// POST /sdk/v1/workshops/:id/complete
func (h *WorkshopHandlers) CompleteSession(c *gin.Context) {
	id, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid session ID"})
		return
	}

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

	// Get final summary
	summary, _ := h.store.GetSessionSummary(c.Request.Context(), id)

	c.JSON(http.StatusOK, gin.H{
		"message": "session completed",
		"summary": summary,
	})
}
