package guilds

import (
	"sync"
	"time"
)

// PointHistory represents a point modification entry in a member's history
type PointHistory struct {
	Date       time.Time `json:"date" db:"date"`
	ModifiedBy string    `json:"modified_by" db:"modified_by"`
	Comment    string    `json:"comment" db:"comment"`
	Points     float64   `json:"points" db:"points"`
	SaveNeeded bool      `json:"-" db:"-"`
}

// GuildMember represents a member of a guild
type GuildMember struct {
	mu                           sync.RWMutex
	CharacterID                  int32          `json:"character_id" db:"character_id"`
	AccountID                    int32          `json:"account_id" db:"account_id"`
	RecruiterID                  int32          `json:"recruiter_id" db:"recruiter_id"`
	Name                         string         `json:"name" db:"name"`
	GuildStatus                  int32          `json:"guild_status" db:"guild_status"`
	Points                       float64        `json:"points" db:"points"`
	AdventureClass               int8           `json:"adventure_class" db:"adventure_class"`
	AdventureLevel               int8           `json:"adventure_level" db:"adventure_level"`
	TradeskillClass              int8           `json:"tradeskill_class" db:"tradeskill_class"`
	TradeskillLevel              int8           `json:"tradeskill_level" db:"tradeskill_level"`
	Rank                         int8           `json:"rank" db:"rank"`
	MemberFlags                  int8           `json:"member_flags" db:"member_flags"`
	Zone                         string         `json:"zone" db:"zone"`
	JoinDate                     time.Time      `json:"join_date" db:"join_date"`
	LastLoginDate                time.Time      `json:"last_login_date" db:"last_login_date"`
	Note                         string         `json:"note" db:"note"`
	OfficerNote                  string         `json:"officer_note" db:"officer_note"`
	RecruiterDescription         string         `json:"recruiter_description" db:"recruiter_description"`
	RecruiterPictureData         []byte         `json:"recruiter_picture_data" db:"recruiter_picture_data"`
	RecruitingShowAdventureClass int8           `json:"recruiting_show_adventure_class" db:"recruiting_show_adventure_class"`
	PointHistory                 []PointHistory `json:"point_history" db:"-"`
}

// GuildEvent represents an event in the guild's history
type GuildEvent struct {
	EventID     int64     `json:"event_id" db:"event_id"`
	Date        time.Time `json:"date" db:"date"`
	Type        int32     `json:"type" db:"type"`
	Description string    `json:"description" db:"description"`
	Locked      int8      `json:"locked" db:"locked"`
	SaveNeeded  bool      `json:"-" db:"-"`
}

// GuildBankEvent represents an event in a guild bank's history
type GuildBankEvent struct {
	EventID     int64     `json:"event_id" db:"event_id"`
	Date        time.Time `json:"date" db:"date"`
	Type        int32     `json:"type" db:"type"`
	Description string    `json:"description" db:"description"`
}

// Bank represents a guild bank with its event history
type Bank struct {
	Name   string           `json:"name" db:"name"`
	Events []GuildBankEvent `json:"events" db:"-"`
}

// Guild represents a guild with all its properties and members
type Guild struct {
	mu                  sync.RWMutex
	id                  int32
	name                string
	level               int8
	formedDate          time.Time
	motd                string
	expCurrent          int64
	expToNextLevel      int64
	recruitingShortDesc string
	recruitingFullDesc  string
	recruitingMinLevel  int8
	recruitingPlayStyle int8
	members             map[int32]*GuildMember
	guildEvents         []GuildEvent
	permissions         map[int8]map[int8]int8 // rank -> permission -> value
	eventFilters        map[int8]map[int8]int8 // event_id -> category -> value
	recruitingFlags     map[int8]int8
	recruitingDescTags  map[int8]int8
	ranks               map[int8]string // rank -> name
	banks               [4]Bank

	// Save flags
	saveNeeded              bool
	memberSaveNeeded        bool
	eventsSaveNeeded        bool
	ranksSaveNeeded         bool
	eventFiltersSaveNeeded  bool
	pointsHistorySaveNeeded bool
	recruitingSaveNeeded    bool

	// Tracking
	nextEventID  int64
	lastModified time.Time
}

// GuildData represents guild data for database operations
type GuildData struct {
	ID                  int32     `json:"id" db:"id"`
	Name                string    `json:"name" db:"name"`
	Level               int8      `json:"level" db:"level"`
	FormedDate          time.Time `json:"formed_date" db:"formed_date"`
	MOTD                string    `json:"motd" db:"motd"`
	EXPCurrent          int64     `json:"exp_current" db:"exp_current"`
	EXPToNextLevel      int64     `json:"exp_to_next_level" db:"exp_to_next_level"`
	RecruitingShortDesc string    `json:"recruiting_short_desc" db:"recruiting_short_desc"`
	RecruitingFullDesc  string    `json:"recruiting_full_desc" db:"recruiting_full_desc"`
	RecruitingMinLevel  int8      `json:"recruiting_min_level" db:"recruiting_min_level"`
	RecruitingPlayStyle int8      `json:"recruiting_play_style" db:"recruiting_play_style"`
}

// GuildMemberData represents guild member data for database operations
type GuildMemberData struct {
	CharacterID                  int32     `json:"character_id" db:"character_id"`
	GuildID                      int32     `json:"guild_id" db:"guild_id"`
	AccountID                    int32     `json:"account_id" db:"account_id"`
	RecruiterID                  int32     `json:"recruiter_id" db:"recruiter_id"`
	Name                         string    `json:"name" db:"name"`
	GuildStatus                  int32     `json:"guild_status" db:"guild_status"`
	Points                       float64   `json:"points" db:"points"`
	AdventureClass               int8      `json:"adventure_class" db:"adventure_class"`
	AdventureLevel               int8      `json:"adventure_level" db:"adventure_level"`
	TradeskillClass              int8      `json:"tradeskill_class" db:"tradeskill_class"`
	TradeskillLevel              int8      `json:"tradeskill_level" db:"tradeskill_level"`
	Rank                         int8      `json:"rank" db:"rank"`
	MemberFlags                  int8      `json:"member_flags" db:"member_flags"`
	Zone                         string    `json:"zone" db:"zone"`
	JoinDate                     time.Time `json:"join_date" db:"join_date"`
	LastLoginDate                time.Time `json:"last_login_date" db:"last_login_date"`
	Note                         string    `json:"note" db:"note"`
	OfficerNote                  string    `json:"officer_note" db:"officer_note"`
	RecruiterDescription         string    `json:"recruiter_description" db:"recruiter_description"`
	RecruiterPictureData         []byte    `json:"recruiter_picture_data" db:"recruiter_picture_data"`
	RecruitingShowAdventureClass int8      `json:"recruiting_show_adventure_class" db:"recruiting_show_adventure_class"`
}

// GuildEventData represents guild event data for database operations
type GuildEventData struct {
	EventID     int64     `json:"event_id" db:"event_id"`
	GuildID     int32     `json:"guild_id" db:"guild_id"`
	Date        time.Time `json:"date" db:"date"`
	Type        int32     `json:"type" db:"type"`
	Description string    `json:"description" db:"description"`
	Locked      int8      `json:"locked" db:"locked"`
}

// GuildRankData represents guild rank data for database operations
type GuildRankData struct {
	GuildID int32  `json:"guild_id" db:"guild_id"`
	Rank    int8   `json:"rank" db:"rank"`
	Name    string `json:"name" db:"name"`
}

// GuildPermissionData represents guild permission data for database operations
type GuildPermissionData struct {
	GuildID    int32 `json:"guild_id" db:"guild_id"`
	Rank       int8  `json:"rank" db:"rank"`
	Permission int8  `json:"permission" db:"permission"`
	Value      int8  `json:"value" db:"value"`
}

// GuildEventFilterData represents guild event filter data for database operations
type GuildEventFilterData struct {
	GuildID  int32 `json:"guild_id" db:"guild_id"`
	EventID  int8  `json:"event_id" db:"event_id"`
	Category int8  `json:"category" db:"category"`
	Value    int8  `json:"value" db:"value"`
}

// GuildRecruitingData represents guild recruiting data for database operations
type GuildRecruitingData struct {
	GuildID int32 `json:"guild_id" db:"guild_id"`
	Flag    int8  `json:"flag" db:"flag"`
	Value   int8  `json:"value" db:"value"`
}

// PointHistoryData represents point history data for database operations
type PointHistoryData struct {
	CharacterID int32     `json:"character_id" db:"character_id"`
	Date        time.Time `json:"date" db:"date"`
	ModifiedBy  string    `json:"modified_by" db:"modified_by"`
	Comment     string    `json:"comment" db:"comment"`
	Points      float64   `json:"points" db:"points"`
}

// GuildList manages all guilds in the system
type GuildList struct {
	mu     sync.RWMutex
	guilds map[int32]*Guild
}

// GuildManager provides high-level guild management
type GuildManager struct {
	guildList     *GuildList
	database      GuildDatabase
	clientManager ClientManager
	playerManager PlayerManager
	eventHandler  GuildEventHandler
	logger        LogHandler
}

// GuildStatistics provides guild system usage statistics
type GuildStatistics struct {
	TotalGuilds       int     `json:"total_guilds"`
	TotalMembers      int     `json:"total_members"`
	ActiveGuilds      int     `json:"active_guilds"`
	AverageGuildSize  float64 `json:"average_guild_size"`
	TotalEvents       int     `json:"total_events"`
	TotalRecruiters   int     `json:"total_recruiters"`
	UniqueAccounts    int     `json:"unique_accounts"`
	HighestGuildLevel int8    `json:"highest_guild_level"`
}

// GuildInfo provides basic guild information
type GuildInfo struct {
	ID                  int32     `json:"id"`
	Name                string    `json:"name"`
	Level               int8      `json:"level"`
	FormedDate          time.Time `json:"formed_date"`
	MOTD                string    `json:"motd"`
	MemberCount         int       `json:"member_count"`
	OnlineMemberCount   int       `json:"online_member_count"`
	RecruiterCount      int       `json:"recruiter_count"`
	RecruitingShortDesc string    `json:"recruiting_short_desc"`
	RecruitingFullDesc  string    `json:"recruiting_full_desc"`
	RecruitingMinLevel  int8      `json:"recruiting_min_level"`
	RecruitingPlayStyle int8      `json:"recruiting_play_style"`
	IsRecruiting        bool      `json:"is_recruiting"`
}

// MemberInfo provides guild member information
type MemberInfo struct {
	CharacterID     int32     `json:"character_id"`
	Name            string    `json:"name"`
	Rank            int8      `json:"rank"`
	RankName        string    `json:"rank_name"`
	Points          float64   `json:"points"`
	AdventureClass  int8      `json:"adventure_class"`
	AdventureLevel  int8      `json:"adventure_level"`
	TradeskillClass int8      `json:"tradeskill_class"`
	TradeskillLevel int8      `json:"tradeskill_level"`
	Zone            string    `json:"zone"`
	JoinDate        time.Time `json:"join_date"`
	LastLoginDate   time.Time `json:"last_login_date"`
	IsOnline        bool      `json:"is_online"`
	IsRecruiter     bool      `json:"is_recruiter"`
	Note            string    `json:"note"`
	OfficerNote     string    `json:"officer_note"`
}

// GuildRoster represents the complete guild roster
type GuildRoster struct {
	GuildInfo GuildInfo    `json:"guild_info"`
	Members   []MemberInfo `json:"members"`
}

// GuildInvite represents a pending guild invitation
type GuildInvite struct {
	GuildID       int32     `json:"guild_id"`
	GuildName     string    `json:"guild_name"`
	CharacterID   int32     `json:"character_id"`
	CharacterName string    `json:"character_name"`
	InviterID     int32     `json:"inviter_id"`
	InviterName   string    `json:"inviter_name"`
	Rank          int8      `json:"rank"`
	InviteDate    time.Time `json:"invite_date"`
	ExpiresAt     time.Time `json:"expires_at"`
}

// GuildEventInfo provides formatted guild event information
type GuildEventInfo struct {
	EventID     int64     `json:"event_id"`
	Date        time.Time `json:"date"`
	Type        int32     `json:"type"`
	TypeName    string    `json:"type_name"`
	Description string    `json:"description"`
	Locked      bool      `json:"locked"`
}

// GuildSearchCriteria represents guild search parameters
type GuildSearchCriteria struct {
	NamePattern      string `json:"name_pattern"`
	MinLevel         int8   `json:"min_level"`
	MaxLevel         int8   `json:"max_level"`
	MinMembers       int    `json:"min_members"`
	MaxMembers       int    `json:"max_members"`
	RecruitingOnly   bool   `json:"recruiting_only"`
	PlayStyle        int8   `json:"play_style"`
	RequiredFlags    []int8 `json:"required_flags"`
	RequiredDescTags []int8 `json:"required_desc_tags"`
	ExcludedDescTags []int8 `json:"excluded_desc_tags"`
}

// RecruitingInfo provides detailed recruiting information
type RecruitingInfo struct {
	GuildID    int32           `json:"guild_id"`
	GuildName  string          `json:"guild_name"`
	ShortDesc  string          `json:"short_desc"`
	FullDesc   string          `json:"full_desc"`
	MinLevel   int8            `json:"min_level"`
	PlayStyle  int8            `json:"play_style"`
	Flags      map[int8]int8   `json:"flags"`
	DescTags   map[int8]int8   `json:"desc_tags"`
	Recruiters []RecruiterInfo `json:"recruiters"`
}

// RecruiterInfo provides recruiter information
type RecruiterInfo struct {
	CharacterID        int32  `json:"character_id"`
	Name               string `json:"name"`
	Description        string `json:"description"`
	PictureData        []byte `json:"picture_data"`
	ShowAdventureClass bool   `json:"show_adventure_class"`
	AdventureClass     int8   `json:"adventure_class"`
	IsOnline           bool   `json:"is_online"`
}
