package models

import (
	"strings"
	"time"
)

type UserRecord struct {
	Account                  string   `json:"account"`
	PasswordHash             string   `json:"passwordHash"`
	Username                 string   `json:"username"`
	Email                    string   `json:"email"`
	Level                    int      `json:"level"`
	SproutCoins              int      `json:"sproutCoins"`
	LastCheckInDate          string   `json:"lastCheckInDate,omitempty"`
	LastCheckInAt            string   `json:"lastCheckInAt,omitempty"`
	LastVisitDate            string   `json:"lastVisitDate,omitempty"`
	LastVisitAt              string   `json:"lastVisitAt,omitempty"`
	LastVisitIP              string   `json:"lastVisitIp,omitempty"`
	LastVisitDisplayLocation string   `json:"lastVisitDisplayLocation,omitempty"`
	CheckInTimes             []string `json:"checkInTimes,omitempty"`
	VisitTimes               []string `json:"visitTimes,omitempty"`
	SecondaryEmails          []string `json:"secondaryEmails,omitempty"`
	Phone                    string   `json:"phone,omitempty"`
	AvatarURL                string   `json:"avatarUrl,omitempty"`
	WebsiteURL               string   `json:"websiteUrl,omitempty"`
	Bio                      string   `json:"bio,omitempty"`
	CreatedAt                string   `json:"createdAt"`
	UpdatedAt                string   `json:"updatedAt"`
	Banned                   bool     `json:"banned"`
	BanReason                string   `json:"banReason,omitempty"`
	BannedAt                 string   `json:"bannedAt,omitempty"`
	TokenEpoch               int64    `json:"-"` // 递增使用户此前签发的 JWT 全局失效；不对外 JSON 序列化
	AuthClients              []AuthClientEntry `json:"authClients,omitempty"`
}

type UserPublic struct {
	Account                  string   `json:"account"`
	Username                 string   `json:"username"`
	Email                    string   `json:"email"`
	Level                    int      `json:"level"`
	SproutCoins              int      `json:"sproutCoins"`
	LastCheckInDate          string   `json:"lastCheckInDate,omitempty"`
	LastCheckInAt            string   `json:"lastCheckInAt,omitempty"`
	LastVisitDate            string   `json:"lastVisitDate,omitempty"`
	CheckInDays              int      `json:"checkInDays"`
	CheckInStreak            int      `json:"checkInStreak"`
	LastVisitAt              string   `json:"lastVisitAt,omitempty"`
	LastVisitIP              string   `json:"lastVisitIp,omitempty"`
	LastVisitDisplayLocation string   `json:"lastVisitDisplayLocation,omitempty"`
	VisitDays                int      `json:"visitDays"`
	VisitStreak              int      `json:"visitStreak"`
	SecondaryEmails          []string `json:"secondaryEmails,omitempty"`
	Phone                    string   `json:"phone,omitempty"`
	AvatarURL                string   `json:"avatarUrl,omitempty"`
	CustomAvatarURL          string   `json:"customAvatarUrl,omitempty"` // 用户自选头像链接；为空时 avatarUrl 可能为 QQ 邮箱推断头像
	WebsiteURL               string   `json:"websiteUrl,omitempty"`
	Bio                      string   `json:"bio,omitempty"`
	CreatedAt                string   `json:"createdAt"`
	UpdatedAt                string   `json:"updatedAt"`
	Banned                   bool     `json:"banned,omitempty"`
	BanReason                string   `json:"banReason,omitempty"`
	BannedAt                 string   `json:"bannedAt,omitempty"`
	AuthClients              []AuthClientEntry `json:"authClients,omitempty"`
}

func (u UserRecord) Public() UserPublic {
	checkInDays, checkInStreak, lastCheckInAt := ActivitySummary(u.CheckInTimes, u.LastCheckInDate)
	visitDays, visitStreak, lastVisitAt := ActivitySummary(u.VisitTimes, u.LastVisitDate)
	if strings.TrimSpace(u.LastCheckInAt) != "" {
		lastCheckInAt = u.LastCheckInAt
	}
	if strings.TrimSpace(u.LastVisitAt) != "" {
		lastVisitAt = u.LastVisitAt
	}
	return UserPublic{
		Account:         u.Account,
		Username:        u.Username,
		Email:           u.Email,
		Level:           u.Level,
		SproutCoins:     u.SproutCoins,
		LastCheckInDate: u.LastCheckInDate,
		LastCheckInAt:   lastCheckInAt,
		LastVisitDate:   u.LastVisitDate,
		CheckInDays:     checkInDays,
		CheckInStreak:   checkInStreak,
		LastVisitAt:     lastVisitAt,
		VisitDays:       visitDays,
		VisitStreak:     visitStreak,
		SecondaryEmails:   u.SecondaryEmails,
		Phone:             u.Phone,
		AvatarURL:         u.ResolvedAvatarURL(),
		CustomAvatarURL:   strings.TrimSpace(u.AvatarURL),
		WebsiteURL:        u.WebsiteURL,
		Bio:               u.Bio,
		CreatedAt:         u.CreatedAt,
		UpdatedAt:         u.UpdatedAt,
	}
}

// PublicProfile 在 Public 基础上附带最近访问 IP / 展示用地理位置，仅供「用户公开主页」接口使用。
func (u UserRecord) PublicProfile() UserPublic {
	p := u.Public()
	p.LastVisitIP = strings.TrimSpace(u.LastVisitIP)
	p.LastVisitDisplayLocation = strings.TrimSpace(u.LastVisitDisplayLocation)
	return p
}

// OwnerPublic 包含仅本人/管理员可见的字段（如最近访问 IP），勿用于公开资料接口。
func (u UserRecord) OwnerPublic() UserPublic {
	p := u.Public()
	p.LastVisitIP = strings.TrimSpace(u.LastVisitIP)
	p.LastVisitDisplayLocation = strings.TrimSpace(u.LastVisitDisplayLocation)
	p.Banned = u.Banned
	p.BanReason = strings.TrimSpace(u.BanReason)
	p.BannedAt = strings.TrimSpace(u.BannedAt)
	if len(u.AuthClients) > 0 {
		p.AuthClients = append([]AuthClientEntry(nil), u.AuthClients...)
	}
	return p
}

type UserShowcase struct {
	Account     string `json:"account"`
	Username    string `json:"username"`
	Level       int    `json:"level"`
	SproutCoins int    `json:"sproutCoins"`
	AvatarURL   string `json:"avatarUrl,omitempty"`
	WebsiteURL  string `json:"websiteUrl,omitempty"`
	Bio         string `json:"bio,omitempty"`
}

func (u UserRecord) Showcase() UserShowcase {
	return UserShowcase{
		Account:     u.Account,
		Username:    u.Username,
		Level:       u.Level,
		SproutCoins: u.SproutCoins,
		AvatarURL:   u.ResolvedAvatarURL(),
		WebsiteURL:  u.WebsiteURL,
		Bio:         u.Bio,
	}
}

// PublicUserListEntry 公开用户目录条目（含注册时间供排序与展示）。
type PublicUserListEntry struct {
	UserShowcase
	CreatedAt string `json:"createdAt"`
}

func (u UserRecord) PublicListEntry() PublicUserListEntry {
	return PublicUserListEntry{
		UserShowcase: u.Showcase(),
		CreatedAt:    u.CreatedAt,
	}
}

func NowISO() string {
	return time.Now().Format(time.RFC3339)
}
