package handlers

import (
	"fmt"
	"log"
	"net/http"

	"github.com/gin-gonic/gin"

	"chat-switchboard/models"
	"chat-switchboard/store"
)

// ── Workflow Entry Handler ──────────────────
// Handles the visitor-facing workflow start flow.
// Landing page rendering is in pages/pages.go (RenderWorkflowLanding).

type WorkflowEntryHandler struct {
	stores store.Stores
}

func NewWorkflowEntryHandler(stores store.Stores) *WorkflowEntryHandler {
	return &WorkflowEntryHandler{stores: stores}
}

// StartVisitor creates an anonymous session + workflow instance for a visitor.
// POST /api/v1/workflow-entry/:scope/:slug
func (h *WorkflowEntryHandler) StartVisitor(c *gin.Context) {
	ctx := c.Request.Context()
	scope := c.Param("scope")
	slug := c.Param("slug")

	var teamID *string
	if scope != "global" {
		teamID = &scope
	}

	wf, err := h.stores.Workflows.GetBySlug(ctx, teamID, slug)
	if err != nil || wf == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "workflow not found"})
		return
	}
	if !wf.IsActive {
		c.JSON(http.StatusBadRequest, gin.H{"error": "workflow not active"})
		return
	}
	if wf.EntryMode != "public_link" {
		c.JSON(http.StatusForbidden, gin.H{"error": "workflow requires authentication"})
		return
	}

	ver, err := h.stores.Workflows.GetLatestVersion(ctx, wf.ID)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "workflow has no published version"})
		return
	}

	stages, err := h.stores.Workflows.ListStages(ctx, wf.ID)
	if err != nil || len(stages) == 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "workflow has no stages"})
		return
	}

	// Create the workflow channel (owned by workflow creator)
	ch := &models.Channel{
		UserID:      wf.CreatedBy,
		Title:       wf.Name,
		Description: wf.Description,
		Type:        "workflow",
		TeamID:      wf.TeamID,
	}
	if err := h.stores.Channels.Create(ctx, ch); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to create channel"})
		return
	}

	// Set workflow columns
	err = h.stores.Channels.SetWorkflowInstance(ctx, ch.ID, wf.ID, ver.VersionNumber, []byte("{}"), "active")
	if err != nil {
		log.Printf("Failed to set workflow columns: %v", err)
	}
	// Enable anonymous access + auto AI mode for visitor entry
	_ = h.stores.Channels.Update(ctx, ch.ID, map[string]interface{}{
		"allow_anonymous": true,
		"ai_mode":         "auto",
	})

	// Create anonymous session
	sessionToken := store.NewID()
	visitorCount, _ := h.stores.Sessions.CountForChannel(ctx, ch.ID)
	displayName := "Visitor"
	if visitorCount > 0 {
		displayName = fmt.Sprintf("Visitor %d", visitorCount+1)
	}
	sess := &models.SessionParticipant{
		SessionToken: sessionToken,
		ChannelID:    ch.ID,
		DisplayName:  displayName,
	}
	if err := h.stores.Sessions.Create(ctx, sess); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to create session"})
		return
	}

	// Add session as channel participant
	_ = h.stores.Channels.AddParticipant(ctx, &models.ChannelParticipant{
		ChannelID:       ch.ID,
		ParticipantType: "session",
		ParticipantID:   sess.ID,
		Role:            "visitor",
	})

	// Bind stage 0 persona
	if stages[0].PersonaID != nil {
		_ = h.stores.Channels.AddParticipant(ctx, &models.ChannelParticipant{
			ChannelID:       ch.ID,
			ParticipantType: "persona",
			ParticipantID:   *stages[0].PersonaID,
			Role:            "member",
		})
	}

	// Set session cookie (30 day expiry, matching v0.24.3)
	c.SetCookie("sb_session", sessionToken, 30*24*60*60, "/", "", false, true)

	// Redirect to workflow page — visitor lands on existing /w/:channelId
	stageMode := stages[0].StageMode
	if stageMode == "" {
		stageMode = "chat_only"
	}
	c.JSON(http.StatusCreated, gin.H{
		"channel_id":  ch.ID,
		"session_id":  sess.ID,
		"redirect_to": "/w/" + ch.ID,
		"stage_mode":  stageMode,
	})
}
