package handlers

import (
	"net/http"
	"time"

	"github.com/breakpilot/consent-service/internal/services/jitsi"
	"github.com/gin-gonic/gin"
)

// ========================================
// Jitsi Video Conference Endpoints
// ========================================

// CreateMeetingRequest for creating Jitsi meetings
type CreateMeetingRequest struct {
	Type        string    `json:"type" binding:"required"` // "quick", "training", "parent_teacher", "class"
	Title       string    `json:"title,omitempty"`
	DisplayName string    `json:"display_name"`
	Email       string    `json:"email,omitempty"`
	Duration    int       `json:"duration,omitempty"` // minutes
	ClassName   string    `json:"class_name,omitempty"`
	ParentName  string    `json:"parent_name,omitempty"`
	StudentName string    `json:"student_name,omitempty"`
	Subject     string    `json:"subject,omitempty"`
	StartTime   time.Time `json:"start_time,omitempty"`
}

// CreateMeeting creates a new Jitsi meeting
func (h *CommunicationHandlers) CreateMeeting(c *gin.Context) {
	if h.jitsiService == nil {
		c.JSON(http.StatusServiceUnavailable, gin.H{"error": "Jitsi service not configured"})
		return
	}

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

	ctx := c.Request.Context()
	var link *jitsi.MeetingLink
	var err error

	switch req.Type {
	case "quick":
		link, err = h.jitsiService.CreateQuickMeeting(ctx, req.DisplayName)
	case "training":
		link, err = h.jitsiService.CreateTrainingSession(ctx, req.Title, req.DisplayName, req.Email, req.Duration)
	case "parent_teacher":
		link, err = h.jitsiService.CreateParentTeacherMeeting(ctx, req.DisplayName, req.ParentName, req.StudentName, req.StartTime)
	case "class":
		link, err = h.jitsiService.CreateClassMeeting(ctx, req.ClassName, req.DisplayName, req.Subject)
	default:
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid meeting type. Use: quick, training, parent_teacher, class"})
		return
	}

	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusCreated, gin.H{
		"room_name":     link.RoomName,
		"url":           link.URL,
		"join_url":      link.JoinURL,
		"moderator_url": link.ModeratorURL,
		"password":      link.Password,
		"expires_at":    link.ExpiresAt,
	})
}

// GetEmbedURLRequest for embedding Jitsi
type GetEmbedURLRequest struct {
	RoomName    string `json:"room_name" binding:"required"`
	DisplayName string `json:"display_name"`
	AudioMuted  bool   `json:"audio_muted"`
	VideoMuted  bool   `json:"video_muted"`
}

// GetEmbedURL returns an embeddable Jitsi URL
func (h *CommunicationHandlers) GetEmbedURL(c *gin.Context) {
	if h.jitsiService == nil {
		c.JSON(http.StatusServiceUnavailable, gin.H{"error": "Jitsi service not configured"})
		return
	}

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

	config := &jitsi.MeetingConfig{
		StartWithAudioMuted: req.AudioMuted,
		StartWithVideoMuted: req.VideoMuted,
		DisableDeepLinking:  true,
	}

	embedURL := h.jitsiService.BuildEmbedURL(req.RoomName, req.DisplayName, config)
	iframeCode := h.jitsiService.BuildIFrameCode(req.RoomName, 800, 600)

	c.JSON(http.StatusOK, gin.H{
		"embed_url":   embedURL,
		"iframe_code": iframeCode,
	})
}

// GetJitsiInfo returns Jitsi server information
func (h *CommunicationHandlers) GetJitsiInfo(c *gin.Context) {
	if h.jitsiService == nil {
		c.JSON(http.StatusServiceUnavailable, gin.H{"error": "Jitsi service not configured"})
		return
	}

	info := h.jitsiService.GetServerInfo()
	c.JSON(http.StatusOK, info)
}

// ========================================
// Admin Statistics Endpoints (for Admin Panel)
// ========================================

// CommunicationStats holds communication service statistics
type CommunicationStats struct {
	Matrix MatrixStats `json:"matrix"`
	Jitsi  JitsiStats  `json:"jitsi"`
}

// MatrixStats holds Matrix-specific statistics
type MatrixStats struct {
	Enabled    bool   `json:"enabled"`
	Healthy    bool   `json:"healthy"`
	ServerName string `json:"server_name"`
	// TODO: Add real stats from Matrix Synapse Admin API
	TotalUsers   int `json:"total_users"`
	TotalRooms   int `json:"total_rooms"`
	ActiveToday  int `json:"active_today"`
	MessagesToday int `json:"messages_today"`
}

// JitsiStats holds Jitsi-specific statistics
type JitsiStats struct {
	Enabled     bool   `json:"enabled"`
	Healthy     bool   `json:"healthy"`
	BaseURL     string `json:"base_url"`
	AuthEnabled bool   `json:"auth_enabled"`
	// TODO: Add real stats from Jitsi SRTP API or Jicofo
	ActiveMeetings    int `json:"active_meetings"`
	TotalParticipants int `json:"total_participants"`
	MeetingsToday     int `json:"meetings_today"`
	AvgDurationMin    int `json:"avg_duration_min"`
}

// GetAdminStats returns admin statistics for Matrix and Jitsi
func (h *CommunicationHandlers) GetAdminStats(c *gin.Context) {
	ctx := c.Request.Context()

	stats := CommunicationStats{}

	// Matrix Stats
	if h.matrixService != nil {
		matrixErr := h.matrixService.HealthCheck(ctx)
		stats.Matrix = MatrixStats{
			Enabled:      true,
			Healthy:      matrixErr == nil,
			ServerName:   h.matrixService.GetServerName(),
			// Placeholder stats - in production these would come from Synapse Admin API
			TotalUsers:    0,
			TotalRooms:    0,
			ActiveToday:   0,
			MessagesToday: 0,
		}
	} else {
		stats.Matrix = MatrixStats{Enabled: false}
	}

	// Jitsi Stats
	if h.jitsiService != nil {
		jitsiErr := h.jitsiService.HealthCheck(ctx)
		serverInfo := h.jitsiService.GetServerInfo()
		stats.Jitsi = JitsiStats{
			Enabled:           true,
			Healthy:           jitsiErr == nil,
			BaseURL:           serverInfo["base_url"],
			AuthEnabled:       serverInfo["auth_enabled"] == "true",
			// Placeholder stats - in production these would come from Jicofo/JVB stats
			ActiveMeetings:    0,
			TotalParticipants: 0,
			MeetingsToday:     0,
			AvgDurationMin:    0,
		}
	} else {
		stats.Jitsi = JitsiStats{Enabled: false}
	}

	c.JSON(http.StatusOK, stats)
}

// ========================================
// Helper Functions
// ========================================

func errToString(err error) string {
	if err == nil {
		return ""
	}
	return err.Error()
}

// RegisterRoutes registers all communication routes
func (h *CommunicationHandlers) RegisterRoutes(router *gin.RouterGroup, jwtSecret string, authMiddleware gin.HandlerFunc) {
	comm := router.Group("/communication")
	{
		// Public health check
		comm.GET("/status", h.GetCommunicationStatus)

		// Protected routes
		protected := comm.Group("")
		protected.Use(authMiddleware)
		{
			// Matrix
			protected.POST("/rooms", h.CreateRoom)
			protected.POST("/rooms/invite", h.InviteUser)
			protected.POST("/messages", h.SendMessage)
			protected.POST("/notifications", h.SendNotification)

			// Jitsi
			protected.POST("/meetings", h.CreateMeeting)
			protected.POST("/meetings/embed", h.GetEmbedURL)
			protected.GET("/jitsi/info", h.GetJitsiInfo)
		}

		// Admin routes (for Matrix user registration and stats)
		admin := comm.Group("/admin")
		admin.Use(authMiddleware)
		// TODO: Add AdminOnly middleware
		{
			admin.POST("/matrix/users", h.RegisterMatrixUser)
			admin.GET("/stats", h.GetAdminStats)
		}
	}
}
