//
// utils.go
// Copyright (C) 2025 veypi <i@veypi.com>
//
// Distributed under terms of the MIT license.
//

package sms

import (
	"fmt"
	"time"

	"github.com/veypi/vbase/cfg"
	"github.com/veypi/vbase/models"
	"gorm.io/gorm"
)

// checkDailyLimit 检查每日发送次数限制
func CheckDailyLimit(phone, region string) error {
	today := time.Now().Truncate(24 * time.Hour)
	tomorrow := today.Add(24 * time.Hour)

	var count int64
	err := cfg.DB().Model(&models.SMSCode{}).
		Where("phone = ? AND region = ? AND created_at >= ? AND created_at < ?",
			phone, region, today, tomorrow).
		Count(&count).Error

	if err != nil {
		return fmt.Errorf("failed to check daily limit: %w", err)
	}

	if count >= int64(cfg.Config.SMS.Global.MaxDailyCount) {
		return fmt.Errorf("daily sms limit exceeded")
	}

	return nil
}

// checkSendInterval 检查发送间隔
func CheckSendInterval(phone, region, purpose string) error {
	var lastCode models.SMSCode
	err := cfg.DB().Where("phone = ? AND region = ? AND purpose = ?", phone, region, purpose).
		Order("created_at DESC").
		First(&lastCode).Error

	if err != nil && err != gorm.ErrRecordNotFound {
		return fmt.Errorf("failed to check send interval: %w", err)
	}

	if err == nil {
		timeSinceLastSend := time.Since(lastCode.CreatedAt)
		if timeSinceLastSend < cfg.Config.SMS.Global.SendInterval {
			remaining := cfg.Config.SMS.Global.SendInterval - timeSinceLastSend
			return fmt.Errorf("please wait %d seconds before sending again", int(remaining.Seconds()))
		}
	}

	return nil
}

// logSMS 记录短信发送日志
func LogSMS(phone, region, provider, messageID string, err error) {
	log := &models.SMSLog{
		Phone:     phone,
		Region:    region,
		Provider:  provider,
		MessageID: messageID,
		Status:    "ok",
	}
	if err != nil {
		log.Status = "failed"
		log.Error = err.Error()
	}
	cfg.DB().Create(log)
}

// CleanupExpiredCodes 清理过期的验证码
func CleanupExpiredCodes() error {
	result := cfg.DB().Model(&models.SMSCode{}).
		Where("status = ? AND expires_at < ?", models.CodeStatusPending, time.Now()).
		Update("status", models.CodeStatusExpired)

	if result.Error != nil {
		return fmt.Errorf("failed to cleanup expired codes: %w", result.Error)
	}

	return nil
}
