package flow

import (
	"context"
	"errors"
	"fmt"
	"log/slog"
	"strings"
	"time"

	"github.com/memohai/memoh/internal/auth"
	"github.com/memohai/memoh/internal/conversation"
	"github.com/memohai/memoh/internal/db"
	"github.com/memohai/memoh/internal/db/sqlc"
)

const emailTriggerTokenTTL = 10 * time.Minute

// EmailChatGateway implements email.ChatTriggerer by delegating to the Resolver.
type EmailChatGateway struct {
	resolver  *Resolver
	queries   *sqlc.Queries
	jwtSecret string
	logger    *slog.Logger
}

func NewEmailChatGateway(resolver *Resolver, queries *sqlc.Queries, jwtSecret string, logger *slog.Logger) *EmailChatGateway {
	return &EmailChatGateway{
		resolver:  resolver,
		queries:   queries,
		jwtSecret: jwtSecret,
		logger:    logger,
	}
}

func (g *EmailChatGateway) TriggerBotChat(ctx context.Context, botID, content string) error {
	if g == nil || g.resolver == nil {
		return errors.New("chat resolver not configured")
	}

	ownerUserID, err := g.resolveBotOwner(ctx, botID)
	if err != nil {
		return fmt.Errorf("resolve bot owner: %w", err)
	}

	token, err := g.generateToken(ownerUserID)
	if err != nil {
		return fmt.Errorf("generate trigger token: %w", err)
	}

	_, err = g.resolver.Chat(ctx, conversation.ChatRequest{
		BotID:          botID,
		ChatID:         botID,
		Query:          content,
		UserID:         ownerUserID,
		Token:          token,
		CurrentChannel: "email",
	})
	if err != nil {
		return fmt.Errorf("trigger chat: %w", err)
	}

	g.logger.Info("email trigger chat completed",
		slog.String("bot_id", botID))
	return nil
}

func (g *EmailChatGateway) resolveBotOwner(ctx context.Context, botID string) (string, error) {
	pgBotID, err := db.ParseUUID(botID)
	if err != nil {
		return "", err
	}
	bot, err := g.queries.GetBotByID(ctx, pgBotID)
	if err != nil {
		return "", fmt.Errorf("get bot: %w", err)
	}
	ownerID := bot.OwnerUserID.String()
	if ownerID == "" {
		return "", errors.New("bot owner not found")
	}
	return ownerID, nil
}

func (g *EmailChatGateway) generateToken(userID string) (string, error) {
	if strings.TrimSpace(g.jwtSecret) == "" {
		return "", errors.New("jwt secret not configured")
	}
	signed, _, err := auth.GenerateToken(userID, g.jwtSecret, emailTriggerTokenTTL)
	if err != nil {
		return "", err
	}
	return "Bearer " + signed, nil
}
