package controllers

import (
	"fmt"

	"github.com/gofiber/fiber/v2"
	"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
	"github.com/sujit-baniya/fiber-boilerplate/pkg/services"
)

// staffUserID extrae el ID del usuario interno autenticado desde c.Locals("user").
func staffUserID(c *fiber.Ctx) (uint, bool) {
	user, ok := c.Locals("user").(map[string]interface{})
	if !ok || user == nil {
		return 0, false
	}
	switch v := user["ID"].(type) {
	case uint:
		return v, true
	case int:
		return uint(v), true
	case float64:
		return uint(v), true
	}
	return 0, false
}

// TelegramStaffStatus indica si el usuario interno autenticado ya vinculó su Telegram.
// GET /app/profile/telegram-status
func TelegramStaffStatus(c *fiber.Ctx) error {
	userID, ok := staffUserID(c)
	if !ok {
		return c.Status(401).JSON(fiber.Map{"error": "No autenticado"})
	}
	u, err := models.FindUserByID(userID)
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": err.Error()})
	}
	return c.JSON(fiber.Map{"linked": u.TelegramChatID != "", "chat_id": u.TelegramChatID})
}

// TelegramStaffInit genera un código de vinculación temporal para el usuario interno.
// POST /app/profile/telegram-init
func TelegramStaffInit(c *fiber.Ctx) error {
	userID, ok := staffUserID(c)
	if !ok {
		return c.Status(401).JSON(fiber.Map{"error": "No autenticado"})
	}
	token, err := models.GenerateTelegramStaffToken(userID)
	if err != nil {
		return c.Status(500).JSON(fiber.Map{"error": "No se pudo generar el código"})
	}

	configs, _ := models.GetAllTelegramConfigs()
	botToken := ""
	for _, cfg := range configs {
		if cfg.Activo && cfg.BotToken != "" {
			botToken = cfg.BotToken
			break
		}
	}
	botUsername := services.GetBotUsername(botToken)

	return c.JSON(fiber.Map{
		"token":        token.Token,
		"bot_username": botUsername,
		"bot_link":     "https://t.me/" + botUsername,
	})
}

// TelegramStaffValidar busca en getUpdates de los bots activos el mensaje con el
// token del usuario y, si lo encuentra, vincula su chat_id.
// POST /app/profile/telegram-validar
func TelegramStaffValidar(c *fiber.Ctx) error {
	userID, ok := staffUserID(c)
	if !ok {
		return c.Status(401).JSON(fiber.Map{"error": "No autenticado"})
	}

	tkn, err := models.GetTelegramStaffTokenByUser(userID)
	if err != nil || tkn == nil {
		return c.Status(400).JSON(fiber.Map{"error": "No tienes un código activo. Genera uno primero."})
	}

	configs, _ := models.GetAllTelegramConfigs()
	for _, cfg := range configs {
		if !cfg.Activo || cfg.BotToken == "" {
			continue
		}
		chatID, found := searchTokenInUpdates(cfg.BotToken, tkn.Token)
		if !found {
			continue
		}
		chatIDStr := fmt.Sprintf("%d", chatID)
		if err := models.UpdateUserTelegramChatID(userID, chatIDStr); err != nil {
			return c.Status(500).JSON(fiber.Map{"error": "No se pudo vincular. Intenta de nuevo."})
		}
		models.DeleteTelegramStaffToken(userID)
		svc := &services.TelegramService{BotToken: cfg.BotToken}
		_ = svc.SendMessage(chatID, "✅ Tu Telegram quedó vinculado a tu usuario de U-Site.\n\nRecibirás aquí las tareas que te asignen y otras notificaciones personales.")
		return c.JSON(fiber.Map{"ok": true, "chat_id": chatIDStr})
	}

	return c.Status(404).JSON(fiber.Map{"error": "Todavía no encontramos tu mensaje. Envía el código al bot y vuelve a intentar."})
}
