package models

import (
	"encoding/json"
	"time"

	"gorm.io/gorm"
)

// User represents a user in the system
type User struct {
	gorm.Model
	Email     string     `gorm:"uniqueIndex;not null" json:"email"`
	Password  string     `gorm:"not null" json:"-"`
	FirstName string     `json:"first_name"`
	LastName  string     `json:"last_name"`
	Role      string     `gorm:"default:editor" json:"role"` // admin, editor
	IsActive  bool       `gorm:"default:true"`
	LastLogin *time.Time `json:"last_login,omitempty"`
}

// Article represents a blog article
type Article struct {
  	gorm.Model
  	Title       string     `gorm:"not null" json:"title"`
  	Content     string     `gorm:"type:text;not null" json:"content"`
  	AuthorID    *uint      `gorm:"index" json:"author_id,omitempty"`
  	Author      *User      `gorm:"foreignKey:AuthorID" json:"author,omitempty"`
  	CategoryID  *uint      `gorm:"index" json:"category_id,omitempty"`
  	Category    *Category  `gorm:"foreignKey:CategoryID" json:"category,omitempty"`
  	ImageURL    string     `json:"image_url"`
  	Published   bool       `gorm:"default:false" json:"published"`
  	PublishedAt *time.Time `json:"published_at,omitempty"`
  	Slug        string     `gorm:"uniqueIndex" json:"slug"`
  	Excerpt     string     `gorm:"type:text" json:"excerpt"`
  	Featured    bool       `gorm:"default:false;index" json:"featured"`
  	// Fields for SEO and social previews
  	SEOTitle       string `json:"seo_title"`
  	SEODescription string `gorm:"type:text" json:"seo_description"`
  	// OG image for social sharing (optional)
  	OGImageURL string `json:"og_image_url"`
  	// Optional: link to external content or embedded media
  	ExternalLink string `json:"external_link"`
  	ViewCount   int `gorm:"default:0;index" json:"view_count"`
  	ReadTime    int `gorm:"default:0" json:"read_time"`    // estimated reading time in minutes
  	UniqueViews int `gorm:"default:0" json:"unique_views"` // Unique visitors (tracked by IP/session)
  	// Store the category name directly to simplify queries (denormalized)
  	CategoryName string `json:"category_name"`
  	Attachments string `gorm:"type:text" json:"attachments"` // JSON array: ["url1", "url2", ...]
  	// Gallery association (optional)
  	GalleryAlbumID   string `json:"gallery_album_id"`
  	GalleryAlbumURL  string `json:"gallery_album_url"`
  	// Stored as JSON string or comma-separated list; frontend normalizes
	GalleryPhotoIDs  string `gorm:"type:text" json:"gallery_photo_ids"`
	// YouTube video association (optional)
	YouTubeVideoID        string `json:"youtube_video_id"`
	YouTubeVideoTitle     string `gorm:"type:text" json:"youtube_video_title"`
	YouTubeVideoURL       string `json:"youtube_video_url"`
	YouTubeVideoThumbnail string `json:"youtube_video_thumbnail"`
	// Match link (loaded separately, not stored in this table)
	// Removed omitempty to always include in JSON (even if null)
	MatchLink *ArticleMatchLink `gorm:"-" json:"match_link"`
}

// ArticleTeamLink represents a link from an article to a team identified by an external FACR ID
type ArticleTeamLink struct {
	gorm.Model
	ArticleID      uint    `gorm:"not null;index" json:"article_id"`
	Article        Article `gorm:"foreignKey:ArticleID" json:"-"`
	ExternalTeamID string  `gorm:"not null;index" json:"external_team_id"`
	TeamName       string  `json:"team_name"`
}

func (ArticleTeamLink) TableName() string { return "article_team_links" }

// ArticleMatchLink represents a link from an article to a match identified by an external FACR match ID
type ArticleMatchLink struct {
    gorm.Model
    ArticleID       uint    `gorm:"not null;index" json:"article_id"`
    Article         Article `gorm:"foreignKey:ArticleID" json:"-"`
    ExternalMatchID string  `gorm:"not null;index" json:"external_match_id"`
    Title           string  `json:"title"`
}

func (ArticleMatchLink) TableName() string { return "article_match_links" }

// Team represents a football team
type Team struct {
    gorm.Model
    Name        string `gorm:"not null"`
    ShortName   string
    Description string
    LogoURL     string `json:"logo_url"`
    IsActive    bool `gorm:"default:true"`
}

// Player represents a football player
type Player struct {
    gorm.Model
    FirstName    string    `gorm:"not null" json:"first_name"`
    LastName     string    `gorm:"not null" json:"last_name"`
    DateOfBirth  time.Time `json:"date_of_birth"`
    Position     string    `json:"position"`
    JerseyNumber int       `json:"jersey_number"`
    TeamID       uint      `json:"team_id"`
    Team         Team      `gorm:"foreignKey:TeamID" json:"team"`
    Nationality  string    `json:"nationality"`
    Height       int       `json:"height"` // in cm
    Weight       int       `json:"weight"` // in kg
    ImageURL     string    `json:"image_url"`
    IsActive     bool      `gorm:"default:true" json:"is_active"`
    Email        string    `json:"email"`
    Phone        string    `json:"phone"`
}

// Sponsor represents a sponsor
type Sponsor struct {
	gorm.Model
	Name         string `gorm:"not null" json:"name"`
	LogoURL      string `json:"logo_url"`
	WebsiteURL   string `json:"website_url"`
	Description  string `json:"description"`
	IsActive     bool   `gorm:"default:true" json:"is_active"`
	Tier         string `gorm:"default:'standard'" json:"tier"` // general (hlavní), standard
	DisplayOrder int    `gorm:"default:0" json:"display_order"` // For custom ordering
	// Banner-specific metadata (optional)
	Placement string `json:"placement"` // e.g., homepage_top, homepage_sidebar
	Width     int    `json:"width"`
	Height    int    `json:"height"`
}

type Settings struct {
	gorm.Model
	// Frontpage layout and style variants (e.g., "classic", "grid"; "light", "dark")
	FrontpageLayout string `json:"frontpage_layout"`
	FrontpageStyle  string `json:"frontpage_style"`
	// Sponsors module display preferences
	SponsorsLayout string `json:"sponsors_layout"` // grid | slider | scroller | pyramid
	SponsorsTheme  string `json:"sponsors_theme"`  // light | dark
	// FACR club selection
	ClubID      string `json:"club_id"`   // UUID from fotbal.cz
	ClubType    string `json:"club_type"` // football|futsal
	ClubName    string `json:"club_name"`
	ClubLogoURL string `json:"club_logo_url"`
	ClubURL     string `json:"club_url"`

	// Theme customization: colors & fonts
	PrimaryColor    string `json:"primary_color"` // e.g. #0033aa
	SecondaryColor  string `json:"secondary_color"`
	AccentColor     string `json:"accent_color"`
	BackgroundColor string `json:"background_color"`
	TextColor       string `json:"text_color"`
	FontHeading     string `json:"font_heading"` // e.g. "Poppins, sans-serif"
	FontBody        string `json:"font_body"`

	// Custom assets: raw overrides stored as TEXT
	CustomCSS          string `gorm:"type:text" json:"custom_css"`
	CustomJS           string `gorm:"type:text" json:"custom_js"`
	CustomHTMLHome     string `gorm:"type:text" json:"custom_html_home"`
	CustomHTMLBlogList string `gorm:"type:text" json:"custom_html_blog_list"`
	CustomHTMLBlogPost string `gorm:"type:text" json:"custom_html_blog_post"`

	// Custom pages & navigation
	AboutHTML      string          `gorm:"type:text" json:"about_html"`
	ShowAboutInNav bool            `gorm:"default:true" json:"show_about_in_nav"`
	CustomNavJSON  string          `gorm:"type:text" json:"-"`
	CustomNav      []CustomNavLink `gorm:"-" json:"custom_nav,omitempty"`

	// SMTP configuration (optional, overrides environment when present)
	SMTPHost       string `json:"smtp_host"`
	SMTPPort       int    `json:"smtp_port"`
	SMTPUser       string `json:"smtp_user"`
	SMTPPassword   string `json:"smtp_password"`
	SMTPFrom       string `json:"smtp_from"`
	SMTPFromName   string `json:"smtp_from_name"`
	SMTPEncryption string `json:"smtp_encryption"` // tls|ssl|none
	SMTPAuth       bool   `json:"smtp_auth"`
	SMTPSkipVerify bool   `json:"smtp_skip_verify"`

	// SEO defaults (site-wide)
	SiteTitle         string `json:"site_title"`
	SiteDescription   string `json:"site_description"`
	MetaKeywords      string `json:"meta_keywords"` // comma-separated
	DefaultOGImageURL string `json:"default_og_image_url"`
	TwitterHandle     string `json:"twitter_handle"`                   // e.g. @club
	CanonicalBaseURL  string `json:"canonical_base_url"`               // e.g. https://www.club.cz
	AdditionalMeta    string `gorm:"type:text" json:"additional_meta"` // raw extra meta
	EnableIndexing    bool   `json:"enable_indexing"`                  // robots allow/disallow

	// Social profiles
	FacebookURL  string `json:"facebook_url"`
	InstagramURL string `json:"instagram_url"`
	YoutubeURL   string `json:"youtube_url"`

	// Generic gallery link (preferred over legacy specific providers)
	GalleryURL   string `json:"gallery_url"`
	GalleryLabel string `json:"gallery_label"`

	// Videos module configuration
	VideosModuleEnabled bool   `json:"videos_module_enabled"`
	VideosStyle         string `json:"videos_style"`  // slider | grid3 | grid
	VideosSource        string `json:"videos_source"` // auto | manual
	VideosLimit         int    `json:"videos_limit"`  // number of items on homepage

	// Manual videos storage (JSON strings)
	VideosJSON      string `gorm:"type:text" json:"-"`
	VideosItemsJSON string `gorm:"type:text" json:"-"`

	// Merch module configuration
	MerchModuleEnabled bool   `json:"merch_module_enabled"`
	MerchStyle         string `json:"merch_style"`  // grid | slider (future)
	MerchSource        string `json:"merch_source"` // manual | auto (future)
	MerchLimit         int    `json:"merch_limit"`
	// Manual merch storage
	MerchItemsJSON string `gorm:"type:text" json:"-"`

	// Newsletter automation toggle (persisted)
	NewsletterEnabled bool `json:"newsletter_enabled"`
	// Newsletter defaults
	DefaultDigestType         string `json:"default_digest_type"`         // blogs|events|matches|scores|weekly
	DefaultDigestCompetitions string `json:"default_digest_competitions"` // comma-separated codes

	// Newsletter scheduling (admin-configurable)
	// Enable/disable specific automated digests
	EnableWeekly         bool `json:"enable_weekly"`
	EnableMatchReminders bool `json:"enable_match_reminders"`
	EnableResults        bool `json:"enable_results"`
	// Weekly schedule
	NewsletterWeeklyDay  string `json:"newsletter_weekly_day"`  // sun|mon|tue|wed|thu|fri|sat
	NewsletterWeeklyHour int    `json:"newsletter_weekly_hour"` // 0-23 local time
	// Match reminder lead time (hours before kickoff)
	NewsletterReminderLeadHours int `json:"newsletter_reminder_lead_hours"` // default 48
	// Quiet hours for results (local time, inclusive start, exclusive end)
	NewsletterQuietStart int `json:"newsletter_quiet_start"` // 0-23
	NewsletterQuietEnd   int `json:"newsletter_quiet_end"`   // 0-23

	// Contact/Location information for map
	ContactAddress    string  `json:"contact_address"`
	ContactCity       string  `json:"contact_city"`
	ContactZip        string  `json:"contact_zip"`
	ContactCountry    string  `json:"contact_country"`
	ContactPhone      string  `json:"contact_phone"`
	ContactEmail      string  `json:"contact_email"`
	LocationLatitude  float64 `json:"location_latitude"`
	LocationLongitude float64 `json:"location_longitude"`
	MapZoomLevel      int     `gorm:"default:15" json:"map_zoom_level"`
	MapStyle          string  `json:"map_style"` // OpenStreetMap style URL or preset: default, dark, satellite
	ShowMapOnHomepage bool    `json:"show_map_on_homepage"`

	// Homepage matches display configuration
	FinishedMatchDisplayDays int `gorm:"default:2" json:"finished_match_display_days"` // Number of days to show finished matches with scores on homepage
}

// TableName specifies table name for Settings model
func (Settings) TableName() string { return "settings" }

// CustomNavLink represents an item in the main navigation managed via settings
type CustomNavLink struct {
	Label    string `json:"label"`
	URL      string `json:"url"`
	External bool   `json:"external"`
}

// LoadCustomNav hydrates the in-memory CustomNav slice from the persisted JSON string.
func (s *Settings) LoadCustomNav() {
	if s.CustomNavJSON == "" {
		s.CustomNav = nil
		return
	}
	var items []CustomNavLink
	if err := json.Unmarshal([]byte(s.CustomNavJSON), &items); err != nil {
		s.CustomNav = nil
		return
	}
	s.CustomNav = items
}

// SetCustomNav stores the provided navigation links and updates the serialized JSON column.
func (s *Settings) SetCustomNav(items []CustomNavLink) error {
	s.CustomNav = items
	if len(items) == 0 {
		s.CustomNavJSON = ""
		return nil
	}
	b, err := json.Marshal(items)
	if err != nil {
		return err
	}
	s.CustomNavJSON = string(b)
	return nil
}

// Club represents the main club/team configuration
type Club struct {
	gorm.Model
	Name         string `gorm:"not null" json:"name"`
	PrimaryColor string `gorm:"default:'#1a365d'" json:"primary_color"`
	SportType    string `gorm:"not null" json:"sport_type"`
	LogoPath     string `json:"logo_path"`
}

// TableName specifies the table name for the User model
func (User) TableName() string {
	return "users"
}

// TableName specifies the table name for the Article model
func (Article) TableName() string {
	return "articles"
}

// TableName specifies the table name for the Team model
func (Team) TableName() string {
	return "teams"
}

// TableName specifies the table name for the Player model
func (Player) TableName() string {
	return "players"
}

// TableName specifies the table name for the Sponsor model
func (Sponsor) TableName() string {
	return "sponsors"
}

// TableName specifies the table name for the Club model
func (Club) TableName() string {
	return "clubs"
}

// ContactCategory represents a category for organizing contacts (e.g., "Management", "Coaches", "Office")
type ContactCategory struct {
	ID          uint           `gorm:"primarykey" json:"id"`
	CreatedAt   time.Time      `json:"created_at"`
	UpdatedAt   time.Time      `json:"updated_at"`
	DeletedAt   gorm.DeletedAt `gorm:"index" json:"deleted_at,omitempty"`
	Name         string        `gorm:"not null;uniqueIndex" json:"name"`
	Description  string        `json:"description"`
	DisplayOrder int           `gorm:"default:0" json:"display_order"`
	IsActive     bool          `gorm:"default:true" json:"is_active"`
}

// TableName specifies the table name for the ContactCategory model
func (ContactCategory) TableName() string {
	return "contact_categories"
}

// Contact represents a contact person (e.g., coach, manager, office staff)
type Contact struct {
	ID          uint             `gorm:"primarykey" json:"id"`
	CreatedAt   time.Time        `json:"created_at"`
	UpdatedAt   time.Time        `json:"updated_at"`
	DeletedAt   gorm.DeletedAt   `gorm:"index" json:"deleted_at,omitempty"`
	CategoryID  *uint            `gorm:"index" json:"category_id,omitempty"`
	Category    *ContactCategory `gorm:"foreignKey:CategoryID" json:"category,omitempty"`
	Name        string           `gorm:"not null" json:"name"`
	Position    string           `json:"position"` // e.g., "Head Coach", "President"
	Email       string           `json:"email"`
	Phone       string           `json:"phone"`
	ImageURL    string           `json:"image_url"`
	Description string           `gorm:"type:text" json:"description"`
	DisplayOrder int             `gorm:"default:0" json:"display_order"`
	IsActive    bool             `gorm:"default:true" json:"is_active"`
}

// TableName specifies the table name for the Contact model
func (Contact) TableName() string {
	return "contacts"
}
