// Package user /v1/me 聚合、设备登记、应用更新检查。
package user

import (
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"

	"dudu/server/internal/auth"
	"dudu/server/internal/quota"
	"dudu/server/internal/store"
	"dudu/server/pkg/protocol"
)

type Handlers struct {
	DB    *gorm.DB
	Quota *quota.Manager
	// AppVersions 启动时由 config 解析好的平台→版本信息（17G）；nil/空表示未配置。
	AppVersions map[string]protocol.AppLatestResponse
}

// Me GET /v1/me（需登录）：余额/试用/账户态聚合 + 设备心跳登记。
func (h *Handlers) Me(c *gin.Context) {
	uid := auth.UserID(c)
	var u store.User
	if err := h.DB.First(&u, "id = ?", uid).Error; err != nil {
		c.JSON(http.StatusUnauthorized, protocol.NewAPIError(protocol.ErrUnauthorized))
		return
	}
	snap, err := h.Quota.Get(c, uid)
	if err != nil {
		c.JSON(http.StatusInternalServerError, protocol.NewAPIError(protocol.ErrInternal))
		return
	}
	h.touchDevice(c, uid)

	state := protocol.AccountOK
	switch {
	case snap.BalanceSeconds > 0:
		state = protocol.AccountOK
	case snap.TrialUsedToday < protocol.TrialDailySeconds:
		state = protocol.AccountTrial
	default:
		state = protocol.AccountQuota
	}
	c.JSON(http.StatusOK, protocol.MeResponse{
		UserID:          uid,
		NicknameMasked:  auth.MaskNickname(u.Nickname),
		BalanceSeconds:  snap.BalanceSeconds,
		TrialDailyLimit: protocol.TrialDailySeconds,
		TrialUsedToday:  snap.TrialUsedToday,
		AccountState:    state,
	})
}

// touchDevice 设备登记/心跳（X-Device-ID / X-Platform / X-App-Version 头）。
func (h *Handlers) touchDevice(c *gin.Context, uid string) {
	did := c.GetHeader("X-Device-ID")
	if did == "" {
		return
	}
	dev := store.Device{
		ID: did, UserID: uid,
		Platform: c.GetHeader("X-Platform"), AppVersion: c.GetHeader("X-App-Version"),
		LastSeen: time.Now(),
	}
	_ = h.DB.Clauses(clause.OnConflict{
		Columns:   []clause.Column{{Name: "id"}},
		DoUpdates: clause.AssignmentColumns([]string{"user_id", "platform", "app_version", "last_seen"}),
	}).Create(&dev).Error
}

// AppLatest GET /v1/app/latest?platform=mac|win|android|ios 🔓
// 版本信息来自启动时 config 解析好的 APP_LATEST_JSON（17G，{"mac":{"version":...,"url":...},...}），
// MVP 不建表；未配置/未知平台返回 204。
func (h *Handlers) AppLatest(c *gin.Context) {
	if v, ok := h.AppVersions[c.Query("platform")]; ok {
		c.JSON(http.StatusOK, v)
		return
	}
	c.Status(http.StatusNoContent)
}
