package app

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

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

func SetupAccountRoutes(r *gin.RouterGroup) {
	r.GET("/account", handleAppGetAccount)
	r.POST("/heartbeat", handleAppHeartbeat)
}

func handleAppGetAccount(c *gin.Context) {
	appKey := c.Param("appKey")
	var app model.Application
	if err := database.DB.Where("app_key = ?", appKey).First(&app).Error; err != nil {
		response.Error(c, 404, "应用不存在")
		return
	}

	if service.GetApplicationDisabledStatus(app.ID) {
		response.Error(c, 403, "该应用已被禁用")
		return
	}

	var req struct {
		UserID uint `json:"user_id"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误")
		return
	}

	var user model.AppUser
	if err := database.DB.First(&user, req.UserID).Error; err != nil {
		response.Error(c, 404, "用户不存在")
		return
	}

	response.Success(c, gin.H{
		"user_id":  user.ID,
		"username": user.Username,
		"balance":  user.Balance,
		"status":   user.Status,
	})
}

func handleAppHeartbeat(c *gin.Context) {
	appKey := c.Param("appKey")
	var app model.Application
	if err := database.DB.Where("app_key = ?", appKey).First(&app).Error; err != nil {
		response.Error(c, 404, "应用不存在")
		return
	}

	if service.GetApplicationDisabledStatus(app.ID) {
		response.Error(c, 403, "该应用已被禁用")
		return
	}

	var req struct {
		UserID     uint   `json:"user_id"`
		DeviceID   string `json:"device_id"`
		InstanceID string `json:"instance_id"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误")
		return
	}

	var user model.AppUser
	if err := database.DB.First(&user, req.UserID).Error; err != nil {
		response.Error(c, 404, "用户不存在")
		return
	}

	if blocked, reason := checkRiskControl(c, app.ID, req.DeviceID, user.Username); blocked {
		log.Printf("[DEBUG] Heartbeat blocked by risk control: %s", reason)
		response.Error(c, 403, reason)
		return
	}

	now := time.Now()
	user.LastHeartbeatAt = &now

	if app.BillingType != "free" && app.DeductionMode == "auto" && app.DeductionAmount > 0 {
		shouldDeduct := false

		switch app.DeductionType {
		case "timer":
			if user.LastHeartbeatAt != nil {
				elapsed := now.Sub(*user.LastHeartbeatAt)
				var interval time.Duration
				switch app.DeductionUnit {
				case "minute":
					interval = time.Duration(app.DeductionInterval) * time.Minute
				case "hour":
					interval = time.Duration(app.DeductionInterval) * time.Hour
				case "day":
					interval = time.Duration(app.DeductionInterval) * 24 * time.Hour
				default:
					interval = time.Duration(app.DeductionInterval) * time.Minute
				}
				if elapsed >= interval {
					shouldDeduct = true
				}
			}
		case "login":
			shouldDeduct = true
		}

		if shouldDeduct {
			if user.Balance == -1 {
				log.Printf("[DEBUG] User %d is permanent member, skip deduction", user.ID)
			} else if app.BillingType == "subscription" {
				if user.ExpiryAt == nil || user.ExpiryAt.Before(now) {
					log.Printf("[DEBUG] User %d subscription expired, ExpiryAt=%v", user.ID, user.ExpiryAt)
					response.Error(c, 403, "订阅已过期")
					return
				}
				log.Printf("[DEBUG] User %d subscription valid, skip balance deduction", user.ID)
			} else {
				if user.Balance >= app.DeductionAmount {
					user.Balance -= app.DeductionAmount
					log.Printf("[DEBUG] Deducted %.2f from user %d, new balance: %.2f", app.DeductionAmount, user.ID, user.Balance)
				} else {
					log.Printf("[DEBUG] User %d has insufficient balance: %.2f < %.2f", user.ID, user.Balance, app.DeductionAmount)
					response.Error(c, 403, "余额不足")
					return
				}
			}
		}
	}

	if err := database.DB.Save(&user).Error; err != nil {
		response.Error(c, 500, "更新心跳失败")
		return
	}

	if req.DeviceID != "" {
		var device model.UserDevice
		err := database.DB.Where("user_id = ? AND application_id = ? AND device_id = ?", user.ID, app.ID, req.DeviceID).First(&device).Error

		if err != nil {
			device = model.UserDevice{
				UserID:        user.ID,
				ApplicationID: app.ID,
				DeviceID:      req.DeviceID,
				DeviceName:    req.DeviceID,
				Status:        "active",
			}
			if err := database.DB.Create(&device).Error; err != nil {
				log.Printf("[DEBUG] Failed to create device: %v", err)
			}
		}

		instanceID := req.InstanceID
		if instanceID == "" {
			instanceID = req.DeviceID
		}

		if device.ID > 0 {
			var session model.DeviceSession
			sessionErr := database.DB.Where("device_id = ? AND instance_id = ?", device.ID, instanceID).First(&session).Error

			if sessionErr != nil {
				session = model.DeviceSession{
					DeviceID:      device.ID,
					UserID:        user.ID,
					ApplicationID: app.ID,
					InstanceID:    instanceID,
					LastHeartbeat: &now,
				}
				if err := database.DB.Create(&session).Error; err != nil {
					log.Printf("[DEBUG] Failed to create session: %v", err)
				}
			} else {
				session.LastHeartbeat = &now
				if err := database.DB.Save(&session).Error; err != nil {
					log.Printf("[DEBUG] Failed to update session: %v", err)
				}
			}
		}
	}

	response.SuccessWithMessage(c, "心跳成功", gin.H{
		"message": "心跳成功",
		"balance": user.Balance,
	})
}
