package models

import (
	"time"
)

// Season represents the seasons table
type Season struct {
	ID           uint      `gorm:"primaryKey;autoIncrement" json:"id"`
	SeasonNumber int       `gorm:"not null;unique;index" json:"season_number"`
	SeasonName   string    `gorm:"size:100;not null" json:"season_name"`
	StartTime    time.Time `gorm:"not null" json:"start_time"`
	EndTime      time.Time `gorm:"not null" json:"end_time"`
	Status       string    `gorm:"size:20;default:'upcoming'" json:"status"` // upcoming, active, ended
	TotalRewards float64   `gorm:"type:decimal(30,2)" json:"total_rewards"`
	Multiplier   float64   `gorm:"type:decimal(10,4);default:1.0000" json:"multiplier"`
	Description  string    `gorm:"type:text" json:"description"`
	IsActive     bool      `gorm:"default:true" json:"is_active"`
	CreatedAt    time.Time `json:"created_at"`
	UpdatedAt    time.Time `json:"updated_at"`
}

func (Season) TableName() string {
	return "seasons"
}

// VIPTier represents the vip_tiers table
type VIPTier struct {
	ID           uint      `gorm:"primaryKey;autoIncrement" json:"id"`
	TierName     string    `gorm:"size:50;not null" json:"tier_name"`
	TierLevel    int       `gorm:"not null;unique;index" json:"tier_level"`
	MinPoints    int64     `gorm:"not null;index" json:"min_points"`
	MaxPoints    *int64    `json:"max_points"`
	Multiplier   float64   `gorm:"type:decimal(10,4);default:1.0000" json:"multiplier"`
	Perks        string    `gorm:"type:json" json:"perks"`
	Icon         string    `gorm:"size:255" json:"icon"`
	Color        string    `gorm:"size:50" json:"color"`
	DisplayOrder int       `gorm:"default:0" json:"display_order"`
	IsActive     bool      `gorm:"default:true" json:"is_active"`
	CreatedAt    time.Time `json:"created_at"`
	UpdatedAt    time.Time `json:"updated_at"`
}

func (VIPTier) TableName() string {
	return "vip_tiers"
}

// UserTeam represents the user_teams table
type UserTeam struct {
	WalletAddress     string     `gorm:"primaryKey;size:42" json:"wallet_address"`
	TeamTVLUSD        float64    `gorm:"type:decimal(30,2);default:0.00" json:"team_tvl_usd"`
	TeamTargetTVLUSD  float64    `gorm:"type:decimal(30,2);default:10000000.00" json:"team_target_tvl_usd"`
	TeamMembersCount  int        `gorm:"default:0" json:"team_members_count"`
	WhalesCount       int        `gorm:"default:0" json:"whales_count"`
	WhalesTarget      int        `gorm:"default:3" json:"whales_target"`
	TradersCount      int        `gorm:"default:0" json:"traders_count"`
	TradersTarget     int        `gorm:"default:3" json:"traders_target"`
	UsersCount        int        `gorm:"default:0" json:"users_count"`
	UsersTarget       int        `gorm:"default:3" json:"users_target"`
	LastCalculatedAt  *time.Time `json:"last_calculated_at"`
	CreatedAt         time.Time  `json:"created_at"`
	UpdatedAt         time.Time  `json:"updated_at"`
}

func (UserTeam) TableName() string {
	return "user_teams"
}

// UserPointsSummary represents the user_points_summary table
type UserPointsSummary struct {
	WalletAddress     string     `gorm:"primaryKey;size:42" json:"wallet_address"`
	TotalPoints       int64      `gorm:"default:0" json:"total_points"`
	HoldingPoints     int64      `gorm:"default:0" json:"holding_points"`
	LpPoints          int64      `gorm:"default:0" json:"lp_points"`
	LendingPoints     int64      `gorm:"default:0" json:"lending_points"`
	TradingPoints     int64      `gorm:"default:0" json:"trading_points"`
	InvitationPoints  int64      `gorm:"default:0" json:"invitation_points"`
	BonusPoints       int64      `gorm:"default:0" json:"bonus_points"`
	GlobalRank        *int       `json:"global_rank"`
	SeasonRank        *int       `json:"season_rank"`
	CurrentSeason     int        `gorm:"default:1" json:"current_season"`
	TotalTrades       int        `gorm:"default:0" json:"total_trades"`
	TotalHoldingDays  int        `gorm:"default:0" json:"total_holding_days"`
	TotalInvites      int        `gorm:"default:0" json:"total_invites"`
	LastCalculatedAt  *time.Time `json:"last_calculated_at"`
	UpdatedAt         time.Time  `json:"updated_at"`
}

func (UserPointsSummary) TableName() string {
	return "user_points_summary"
}

// UserPointsRecord represents the user_points_records table
type UserPointsRecord struct {
	ID                uint      `gorm:"primaryKey;autoIncrement" json:"id"`
	WalletAddress     string    `gorm:"size:42;not null;index" json:"wallet_address"`
	PointsChange      int       `gorm:"not null" json:"points_change"`
	PointsBefore      int       `gorm:"not null" json:"points_before"`
	PointsAfter       int       `gorm:"not null" json:"points_after"`
	SourceType        string    `gorm:"size:50;not null" json:"source_type"`
	MultiplierApplied float64   `gorm:"type:decimal(10,4);default:1.0000" json:"multiplier_applied"`
	SourceID          *uint     `json:"source_id"`
	RuleID       *uint     `json:"rule_id"`
	Description  string    `gorm:"type:text" json:"description"`
	Metadata     string    `gorm:"type:json" json:"metadata"`
	CreatedAt    time.Time `json:"created_at"`
}

func (UserPointsRecord) TableName() string {
	return "user_points_records"
}

// Invitation represents the invitations table
type Invitation struct {
	ID                   uint      `gorm:"primaryKey;autoIncrement" json:"id"`
	ReferrerWallet       string    `gorm:"size:42;not null;index" json:"referrer_wallet"`
	RefereeWallet        string    `gorm:"size:42;not null;unique;index" json:"referee_wallet"`
	InviteCode           string    `gorm:"size:20;not null" json:"invite_code"`
	BindSignature        string    `gorm:"type:text" json:"bind_signature"`
	BindHash             string    `gorm:"size:66" json:"bind_hash"`
	Status               string    `gorm:"size:50;default:'active'" json:"status"`
	ReferrerRewardPoints int       `gorm:"default:0" json:"referrer_reward_points"`
	RefereeRewardPoints  int       `gorm:"default:0" json:"referee_reward_points"`
	BoundAt              time.Time `gorm:"not null" json:"bound_at"`
	CreatedAt            time.Time `json:"created_at"`
}

func (Invitation) TableName() string {
	return "invitations"
}

// InviteCode represents the invite_codes table
type InviteCode struct {
	ID            uint       `gorm:"primaryKey;autoIncrement" json:"id"`
	WalletAddress string     `gorm:"size:42;not null;unique;index" json:"wallet_address"`
	Code          string     `gorm:"size:20;not null;unique;index" json:"code"`
	MaxUses       int        `gorm:"default:-1" json:"max_uses"` // -1 = unlimited
	UsedCount     int        `gorm:"default:0" json:"used_count"`
	ExpiresAt     NullTime   `json:"expires_at"`
	IsActive      bool       `gorm:"default:true" json:"is_active"`
	CreatedAt     time.Time  `json:"created_at"`
}

func (InviteCode) TableName() string {
	return "invite_codes"
}

// =====================
// Response DTOs
// =====================

// DashboardResponse is the response for GET /api/points/dashboard
type DashboardResponse struct {
	TotalPoints      int64          `json:"totalPoints"`
	GlobalRank       int            `json:"globalRank"`
	TopPercentage    string         `json:"topPercentage"`
	MemberTier       string         `json:"memberTier"`
	VIPLevel         int            `json:"vipLevel"`
	PointsToNextTier int64          `json:"pointsToNextTier"`
	NextTier         string         `json:"nextTier"`
	Season           SeasonInfo     `json:"season"`
}

// SeasonInfo contains season information
type SeasonInfo struct {
	SeasonNumber   int       `json:"seasonNumber"`
	SeasonName     string    `json:"seasonName"`
	IsLive         bool      `json:"isLive"`
	EndTime        time.Time `json:"endTime"`
	DaysRemaining  int       `json:"daysRemaining"`
	HoursRemaining int       `json:"hoursRemaining"`
}

// LeaderboardResponse is the response for GET /api/points/leaderboard
type LeaderboardResponse struct {
	TopUsers []LeaderboardUser `json:"topUsers"`
	MyRank   int               `json:"myRank"`
	MyPoints int64             `json:"myPoints"`
}

// LeaderboardUser represents a user in the leaderboard
type LeaderboardUser struct {
	Rank          int    `json:"rank"`
	WalletAddress string `json:"address"`
	Points        int64  `json:"points"`
}

// InviteCodeResponse is the response for GET /api/points/invite-code
type InviteCodeResponse struct {
	Code      string `json:"code"`
	UsedCount int    `json:"usedCount"`
	MaxUses   int    `json:"maxUses"`
}

// TeamTVLResponse is the response for GET /api/points/team
type TeamTVLResponse struct {
	CurrentTVL      string      `json:"currentTVL"`
	TargetTVL       string      `json:"targetTVL"`
	ProgressPercent float64     `json:"progressPercent"`
	TotalMembers    int         `json:"totalMembers"`
	Roles           []RoleCount `json:"roles"`
}

// RoleCount represents count for each role
type RoleCount struct {
	Icon    string `json:"icon"`
	Label   string `json:"label"`
	Current int    `json:"current"`
	Target  int    `json:"target"`
}

// ActivitiesResponse is the response for GET /api/points/activities
type ActivitiesResponse struct {
	Activities []ActivityRecord `json:"activities"`
	Pagination PaginationInfo   `json:"pagination"`
}

// ActivityRecord represents a single activity
type ActivityRecord struct {
	Type          string    `json:"type"`
	UserAddress   string    `json:"userAddress"`
	FriendAddress string    `json:"friendAddress,omitempty"`
	InviteCode    string    `json:"inviteCode,omitempty"`
	Points        int       `json:"points"`
	CreatedAt     time.Time `json:"createdAt"`
}

// PaginationInfo contains pagination metadata
type PaginationInfo struct {
	Page      int `json:"page"`
	PageSize  int `json:"pageSize"`
	Total     int `json:"total"`
	TotalPage int `json:"totalPage"`
}

// BindInviteRequest is the request body for POST /api/points/bind-invite
type BindInviteRequest struct {
	Code      string `json:"code" binding:"required"`
	Signature string `json:"signature" binding:"required"`
}

// HoldersSnapshot represents the holders_snapshots table
// 每小时快照：记录用户持有 YT/LP/Lending 代币的余额及积分计算结果
type HoldersSnapshot struct {
	ID                   uint      `gorm:"primaryKey;autoIncrement" json:"id"`
	WalletAddress        string    `gorm:"size:42;not null;index" json:"wallet_address"`
	TokenType            string    `gorm:"size:20;not null" json:"token_type"`
	TokenAddress         string    `gorm:"size:42;not null" json:"token_address"`
	ChainID              int       `gorm:"not null" json:"chain_id"`
	Balance              float64   `gorm:"type:decimal(30,18);not null" json:"balance"`
	BalanceUSD           float64   `gorm:"type:decimal(30,2)" json:"balance_usd"`
	HoldingDurationHours int       `json:"holding_duration_hours"`
	PointsMultiplier     float64   `gorm:"type:decimal(10,4);default:1.0000" json:"points_multiplier"`
	EarnedPoints         int       `json:"earned_points"`
	SnapshotTime         time.Time `gorm:"not null;index" json:"snapshot_time"`
	SeasonID             *uint     `gorm:"index" json:"season_id"`
	CreatedAt            time.Time `json:"created_at"`
}

func (HoldersSnapshot) TableName() string {
	return "holders_snapshots"
}
