package middleware

import (
	"fmt"
	"time"
	"verification-platform-backend/internal/database"
	"verification-platform-backend/internal/model"
	"verification-platform-backend/pkg/response"

	"github.com/gin-gonic/gin"
)

func CheckApiLimit() gin.HandlerFunc {
	return func(c *gin.Context) {
		userID, exists := c.Get("user_id")
		if !exists {
			response.Error(c, 401, "未授权")
			c.Abort()
			return
		}

		var user model.User
		if err := database.DB.Preload("CurrentPackage").First(&user, userID).Error; err != nil {
			response.Error(c, 500, "获取用户信息失败")
			c.Abort()
			return
		}

		if user.CurrentPackageID == nil {
			response.Error(c, 403, "您还没有购买套餐，请先购买套餐")
			c.Abort()
			return
		}

		var permission model.PackagePermission
		if err := database.DB.Where("package_id = ?", user.CurrentPackageID).First(&permission).Error; err != nil {
			response.Error(c, 500, "获取套餐权限失败")
			c.Abort()
			return
		}

		now := time.Now()
		if user.ApiCallsResetAt == nil || now.Sub(*user.ApiCallsResetAt) >= 24*time.Hour {
			user.ApiCallsUsed = 0
			user.ApiCallsResetAt = &now
			database.DB.Save(&user)
		}

		if user.ApiCallsUsed >= permission.MaxApiCalls {
			response.Error(c, 403, fmt.Sprintf("API调用次数已达上限（%d次/天），请升级套餐", permission.MaxApiCalls))
			c.Abort()
			return
		}

		c.Next()

		user.ApiCallsUsed++
		database.DB.Save(&user)
	}
}

func CheckStorageLimit(fileSize int64) gin.HandlerFunc {
	return func(c *gin.Context) {
		userID, exists := c.Get("user_id")
		if !exists {
			response.Error(c, 401, "未授权")
			c.Abort()
			return
		}

		var user model.User
		if err := database.DB.Preload("CurrentPackage").First(&user, userID).Error; err != nil {
			response.Error(c, 500, "获取用户信息失败")
			c.Abort()
			return
		}

		if user.CurrentPackageID == nil {
			response.Error(c, 403, "您还没有购买套餐，请先购买套餐")
			c.Abort()
			return
		}

		var permission model.PackagePermission
		if err := database.DB.Where("package_id = ?", user.CurrentPackageID).First(&permission).Error; err != nil {
			response.Error(c, 500, "获取套餐权限失败")
			c.Abort()
			return
		}

		maxStorageBytes := int64(permission.MaxStorage) * 1024 * 1024
		if user.StorageUsed+fileSize > maxStorageBytes {
			usedMB := float64(user.StorageUsed) / 1024 / 1024
			maxMB := float64(permission.MaxStorage)
			response.Error(c, 403, fmt.Sprintf("存储空间不足，已使用 %.2f MB / %.2f MB", usedMB, maxMB))
			c.Abort()
			return
		}

		c.Next()
	}
}

func RecordApiUsage() gin.HandlerFunc {
	return func(c *gin.Context) {
		startTime := time.Now()

		c.Next()

		userID, exists := c.Get("user_id")
		if !exists {
			return
		}

		appID, _ := c.Get("app_id")

		duration := time.Since(startTime)

		usage := model.ApiUsage{
			UserID:        userID.(uint),
			ApplicationID: appID.(uint),
			Endpoint:      c.Request.URL.Path,
			Method:        c.Request.Method,
			IPAddress:     c.ClientIP(),
			UserAgent:     c.Request.UserAgent(),
			ResponseTime:  int(duration.Milliseconds()),
			StatusCode:    c.Writer.Status(),
			Success:       c.Writer.Status() < 400,
			CreatedAt:     time.Now(),
		}

		if len(c.Errors) > 0 {
			usage.ErrorMessage = c.Errors.String()
		}

		database.DB.Create(&usage)
	}
}

func UpdateStorageUsed(userID uint, fileSize int64, action string) error {
	var user model.User
	if err := database.DB.First(&user, userID).Error; err != nil {
		return err
	}

	if action == "upload" {
		user.StorageUsed += fileSize
	} else if action == "delete" {
		user.StorageUsed -= fileSize
		if user.StorageUsed < 0 {
			user.StorageUsed = 0
		}
	}

	return database.DB.Save(&user).Error
}
