package handlers

import (
	"context"
	"fmt"
	"net/http"
	"strings"
	"time"

	"github.com/gin-gonic/gin"

	"chat-switchboard/providers"
	"chat-switchboard/roles"
	"chat-switchboard/store"
)

// TitleHandler generates chat titles using the utility role.
type TitleHandler struct {
	stores   store.Stores
	resolver *roles.Resolver
}

// NewTitleHandler creates a title generation handler.
func NewTitleHandler(s store.Stores, r *roles.Resolver) *TitleHandler {
	return &TitleHandler{stores: s, resolver: r}
}

// GenerateTitle generates a title for a channel using the utility role.
// POST /channels/:id/generate-title
func (h *TitleHandler) GenerateTitle(c *gin.Context) {
	channelID := c.Param("id")
	userID := c.GetString("user_id")
	teamID := c.GetString("team_id")

	// Verify channel access
	owns, err := h.stores.Channels.UserOwns(c.Request.Context(), channelID, userID)
	if err != nil || !owns {
		c.JSON(http.StatusNotFound, gin.H{"error": "channel not found"})
		return
	}

	ch, err := h.stores.Channels.GetByID(c.Request.Context(), channelID)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "channel not found"})
		return
	}

	// Load first few messages
	msgs, err := h.stores.Messages.ListForChannel(c.Request.Context(), channelID, store.ListOptions{
		Limit: 4, Order: "asc",
	})
	if err != nil || len(msgs) == 0 {
		c.JSON(http.StatusOK, gin.H{"title": ch.Title}) // keep existing
		return
	}

	// Build a snippet from the first messages
	var snippet strings.Builder
	for _, m := range msgs {
		content := m.Content
		if len(content) > 200 {
			content = content[:200] + "…"
		}
		fmt.Fprintf(&snippet, "%s: %s\n", m.Role, content)
	}

	// Call utility role
	ctx, cancel := context.WithTimeout(c.Request.Context(), 15*time.Second)
	defer cancel()

	var tID *string
	if teamID != "" {
		tID = &teamID
	}

	result, err := h.resolver.Complete(ctx, roles.RoleUtility, userID, tID, []providers.Message{
		{
			Role:    "system",
			Content: "You are a title generator. Given a conversation snippet, produce a concise title of 6 words or fewer. Respond with ONLY the title, no quotes, no punctuation at the end, no explanation.",
		},
		{
			Role:    "user",
			Content: "Title this conversation:\n\n" + snippet.String(),
		},
	})
	if err != nil {
		// Fallback: truncate first user message
		c.JSON(http.StatusOK, gin.H{"title": ch.Title})
		return
	}

	title := strings.TrimSpace(result.Content)
	// Strip surrounding quotes if the model added them
	title = strings.Trim(title, "\"'`\u201c\u201d\u2018\u2019")
	if title == "" {
		c.JSON(http.StatusOK, gin.H{"title": ch.Title})
		return
	}
	// Cap at 100 chars
	if len(title) > 100 {
		title = title[:100]
	}

	// Update channel
	_ = h.stores.Channels.Update(c.Request.Context(), channelID, map[string]interface{}{
		"title": title,
	})

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