package admin

import (
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/gothinkster/golang-gin-realworld-example-app/common"
	"github.com/gothinkster/golang-gin-realworld-example-app/models"
)

func ListUsers(c *gin.Context) {
	db := common.GetDB()
	p := ParsePagination(c)

	query := db.Model(&models.User{})
	if v := c.Query("wallet_address"); v != "" {
		query = query.Where("wallet_address LIKE ?", "%"+strings.ToLower(v)+"%")
	}
	if v := c.Query("member_tier"); v != "" {
		query = query.Where("member_tier = ?", v)
	}
	if v := c.Query("nickname"); v != "" {
		query = query.Where("nickname LIKE ?", "%"+v+"%")
	}

	var total int64
	query.Count(&total)

	var items []models.User
	if err := query.Order("created_at DESC").Offset(p.Offset()).Limit(p.PageSize).Find(&items).Error; err != nil {
		Fail(c, http.StatusInternalServerError, "Failed to fetch users")
		return
	}
	OKList(c, items, total)
}

func GetUser(c *gin.Context) {
	db := common.GetDB()
	wallet := strings.ToLower(c.Param("wallet"))
	var item models.User
	if err := db.Where("wallet_address = ?", wallet).First(&item).Error; err != nil {
		Fail(c, http.StatusNotFound, "User not found")
		return
	}
	OK(c, item)
}

// UpdateUser allows updating limited fields: nickname, member_tier, vip_level, total_points, global_rank
func UpdateUser(c *gin.Context) {
	db := common.GetDB()
	wallet := strings.ToLower(c.Param("wallet"))

	var existing models.User
	if err := db.Where("wallet_address = ?", wallet).First(&existing).Error; err != nil {
		Fail(c, http.StatusNotFound, "User not found")
		return
	}

	var payload struct {
		Nickname   string  `json:"nickname"`
		MemberTier string  `json:"member_tier"`
		VIPLevel   int     `json:"vip_level"`
		TotalPoints int64  `json:"total_points"`
		GlobalRank  *int   `json:"global_rank"`
	}
	if err := c.ShouldBindJSON(&payload); err != nil {
		Fail(c, http.StatusBadRequest, err.Error())
		return
	}

	updates := map[string]interface{}{}
	if payload.Nickname != "" {
		updates["nickname"] = payload.Nickname
	}
	if payload.MemberTier != "" {
		updates["member_tier"] = payload.MemberTier
	}
	if payload.VIPLevel > 0 {
		updates["vip_level"] = payload.VIPLevel
	}
	if payload.TotalPoints >= 0 {
		updates["total_points"] = payload.TotalPoints
	}
	if payload.GlobalRank != nil {
		updates["global_rank"] = payload.GlobalRank
	}

	if err := db.Model(&existing).Updates(updates).Error; err != nil {
		Fail(c, http.StatusInternalServerError, err.Error())
		return
	}

	// Reload updated user
	db.Where("wallet_address = ?", wallet).First(&existing)
	LogOp(c, "update", "user", "update_user", nil, updates)
	OK(c, existing)
}
