package models

import (
	"crypto/rand"
	"fmt"

	"github.com/sujit-baniya/fiber-boilerplate/app"
	"gorm.io/gorm"
)

// TelegramPortalToken almacena un código de verificación temporal para vincular
// el Telegram de un usuario del portal con el bot de notificaciones.
type TelegramPortalToken struct {
	gorm.Model
	PortalUserID uint   `json:"portal_user_id" gorm:"column:portal_user_id;uniqueIndex"`
	Token        string `json:"token"          gorm:"column:token;uniqueIndex;size:8"`
}

func (TelegramPortalToken) TableName() string { return "telegram_portal_tokens" }

// GenerateTelegramPortalToken genera (o renueva) el código de vinculación para el usuario.
// El código tiene 6 caracteres hexadecimales en mayúsculas (e.g. "A3F9B2").
func GenerateTelegramPortalToken(portalUserID uint) (*TelegramPortalToken, error) {
	// Eliminar tokens previos del mismo usuario (borrado físico para evitar conflicto con uniqueIndex)
	app.Http.Database.DB.Unscoped().Where("portal_user_id = ?", portalUserID).Delete(&TelegramPortalToken{})

	b := make([]byte, 3)
	if _, err := rand.Read(b); err != nil {
		return nil, fmt.Errorf("no se pudo generar token: %w", err)
	}
	token := fmt.Sprintf("%06X", b)

	t := &TelegramPortalToken{PortalUserID: portalUserID, Token: token}
	if err := app.Http.Database.DB.Create(t).Error; err != nil {
		return nil, err
	}
	return t, nil
}

// FindTelegramPortalToken busca un token de vinculación activo.
func FindTelegramPortalToken(token string) (*TelegramPortalToken, error) {
	var t TelegramPortalToken
	err := app.Http.Database.DB.Where("token = ?", token).First(&t).Error
	return &t, err
}

// DeleteTelegramPortalToken elimina el token de un usuario (tras vincular correctamente).
func DeleteTelegramPortalToken(portalUserID uint) {
	app.Http.Database.DB.Unscoped().Where("portal_user_id = ?", portalUserID).Delete(&TelegramPortalToken{})
}

// GetTelegramPortalTokenByUser devuelve el token vigente de un usuario del portal.
func GetTelegramPortalTokenByUser(portalUserID uint) (*TelegramPortalToken, error) {
	var t TelegramPortalToken
	err := app.Http.Database.DB.Where("portal_user_id = ?", portalUserID).First(&t).Error
	if err != nil {
		return nil, err
	}
	return &t, nil
}
