package models

import (
	"crypto/rand"
	"encoding/hex"

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

type WebSmsConfig struct {
	gorm.Model
	Username  string `json:"username" gorm:"column:username;size:255;not null"`
	ApiToken  string `json:"api_token" gorm:"column:api_token;type:text;not null"`
	Sender    string `json:"sender" gorm:"column:sender;size:30"`
	Notas     string `json:"notas" gorm:"column:notas;type:text"`
	Activo    bool   `json:"activo" gorm:"column:activo;default:true"`
	SecretKey string `json:"secret_key" gorm:"column:secret_key;size:64;uniqueIndex"`
}

func generateWebSmsSecret() string {
	b := make([]byte, 24)
	rand.Read(b)
	return "sms_" + hex.EncodeToString(b)
}

func (WebSmsConfig) TableName() string { return "websms_config" }

func GetWebSmsConfig() (*WebSmsConfig, error) {
	var item WebSmsConfig
	if err := app.Http.Database.DB.Where("activo = ?", true).Order("id DESC").First(&item).Error; err != nil {
		return nil, err
	}
	return &item, nil
}

func SaveWebSmsConfig(s WebSmsConfig) error {
	app.Http.Database.DB.Model(&WebSmsConfig{}).
		Where("activo = ?", true).
		Update("activo", false)
	s.Activo = true
	if s.ID > 0 {
		// preserve existing secret_key
		var existing WebSmsConfig
		app.Http.Database.DB.First(&existing, s.ID)
		if existing.SecretKey == "" {
			existing.SecretKey = generateWebSmsSecret()
		}
		return app.Http.Database.DB.Model(&s).Updates(map[string]interface{}{
			"username":   s.Username,
			"api_token":  s.ApiToken,
			"sender":     s.Sender,
			"notas":      s.Notas,
			"activo":     true,
			"secret_key": existing.SecretKey,
		}).Error
	}
	s.SecretKey = generateWebSmsSecret()
	return app.Http.Database.DB.Create(&s).Error
}

// ─── Log de SMS enviados ────────────────────────────────────────────────────

type WebSmsLog struct {
	gorm.Model
	Para    string `json:"para" gorm:"column:para;size:30;index"`
	Mensaje string `json:"mensaje" gorm:"column:mensaje;type:text"`
	Status  string `json:"status" gorm:"column:status;size:20"`
	MsgID   string `json:"msg_id" gorm:"column:msg_id;size:100"`
	Error   string `json:"error" gorm:"column:error;type:text"`
}

func (WebSmsLog) TableName() string { return "websms_log" }

func CreateWebSmsLog(entry *WebSmsLog) error {
	return app.Http.Database.DB.Create(entry).Error
}

func GetWebSmsLogs(limit int) ([]WebSmsLog, error) {
	var logs []WebSmsLog
	if err := app.Http.Database.DB.Order("id DESC").Limit(limit).Find(&logs).Error; err != nil {
		return nil, err
	}
	return logs, nil
}

// ─── Webhook ACK log ────────────────────────────────────────────────────────

type WebSmsWebhookLog struct {
	gorm.Model
	Tipo      string `json:"tipo" gorm:"column:tipo;size:20;index"` // delivery | click | incoming
	MsgID     string `json:"msg_id" gorm:"column:msg_id;size:100;index"`
	Para      string `json:"para" gorm:"column:para;size:30"`
	Status    string `json:"status" gorm:"column:status;size:30"`
	Raw       string `json:"raw" gorm:"column:raw;type:text"`
}

func (WebSmsWebhookLog) TableName() string { return "websms_webhook_log" }

func CreateWebSmsWebhookLog(entry *WebSmsWebhookLog) error {
	return app.Http.Database.DB.Create(entry).Error
}

func GetWebSmsWebhookLogs(limit int) ([]WebSmsWebhookLog, error) {
	var logs []WebSmsWebhookLog
	if err := app.Http.Database.DB.Order("id DESC").Limit(limit).Find(&logs).Error; err != nil {
		return nil, err
	}
	return logs, nil
}
