from typing import List, Optional
from sqlmodel import Field, Relationship, SQLModel
from datetime import datetime
from enum import Enum

# --- Join Tables ---
class Performance(SQLModel, table=True):
    """Link table between Show and Song (Many-to-Many with extra data)"""
    id: Optional[int] = Field(default=None, primary_key=True)
    slug: Optional[str] = Field(default=None, unique=True, index=True, description="songslug-YYYY-MM-DD")
    show_id: int = Field(foreign_key="show.id")
    song_id: int = Field(foreign_key="song.id")
    position: int = Field(description="Order in the setlist")
    set_name: Optional[str] = Field(default=None, description="e.g., Set 1, Encore")
    segue: bool = Field(default=False, description="Transition to next song >")
    notes: Optional[str] = Field(default=None)
    track_url: Optional[str] = Field(default=None, description="Deep link to track audio")
    youtube_link: Optional[str] = Field(default=None, description="YouTube video URL")
    bandcamp_link: Optional[str] = Field(default=None, description="Bandcamp track URL")
    nugs_link: Optional[str] = Field(default=None, description="Nugs.net track URL")
    
    nicknames: List["PerformanceNickname"] = Relationship(back_populates="performance")
    show: "Show" = Relationship(back_populates="performances")
    song: "Song" = Relationship()

class ShowArtist(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    show_id: int = Field(foreign_key="show.id")
    artist_id: int = Field(foreign_key="artist.id")
    notes: Optional[str] = Field(default=None, description="Role e.g. Guest")

class PerformanceArtist(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    performance_id: int = Field(foreign_key="performance.id")
    artist_id: int = Field(foreign_key="artist.id")
    notes: Optional[str] = Field(default=None, description="Role e.g. Guest")

class PerformanceNickname(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    performance_id: int = Field(foreign_key="performance.id")
    nickname: str = Field(index=True)
    description: Optional[str] = Field(default=None)
    status: str = Field(default="pending", index=True) # pending, approved, rejected
    suggested_by: int = Field(foreign_key="user.id")
    created_at: datetime = Field(default_factory=datetime.utcnow)
    
    performance: "Performance" = Relationship(back_populates="nicknames")
    user: "User" = Relationship()

class EntityTag(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    tag_id: int = Field(foreign_key="tag.id")
    entity_type: str = Field(index=True) # "show", "song", "venue"
    entity_id: int = Field(index=True)

# --- Core Entities ---

class VerticalScene(SQLModel, table=True):
    """Join table linking verticals to scenes (many-to-many)"""
    vertical_id: int = Field(foreign_key="vertical.id", primary_key=True)
    scene_id: int = Field(foreign_key="scene.id", primary_key=True)


class Scene(SQLModel, table=True):
    """Genre/scene categorization for bands (e.g., 'Jam', 'Bluegrass', 'Dead Family')"""
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str = Field(unique=True, index=True)
    slug: str = Field(unique=True, index=True)
    description: Optional[str] = Field(default=None)
    
    # Relationships
    verticals: List["Vertical"] = Relationship(back_populates="scenes", link_model=VerticalScene)


class Vertical(SQLModel, table=True):
    """Represents a Fandom Vertical (e.g., 'Phish', 'Goose', 'Star Wars')"""
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str = Field(index=True)
    slug: str = Field(unique=True, index=True)
    description: Optional[str] = Field(default=None)
    
    # Link to primary artist/band for this vertical
    primary_artist_id: Optional[int] = Field(default=None, foreign_key="artist.id")
    
    # Setlist.fm integration for universal import
    setlistfm_mbid: Optional[str] = Field(default=None, description="MusicBrainz ID for Setlist.fm")
    
    # Admin/status fields
    is_active: bool = Field(default=True, description="Show in band selector")
    is_featured: bool = Field(default=False, description="Highlight in discovery")
    
    # Branding
    logo_url: Optional[str] = Field(default=None, description="Band logo URL for UI")
    accent_color: Optional[str] = Field(default=None, description="Hex color for accents")
    
    # Rich profile fields
    formed_year: Optional[int] = Field(default=None, description="Year band was formed")
    origin_city: Optional[str] = Field(default=None, description="City of origin")
    origin_state: Optional[str] = Field(default=None, description="State/province")
    origin_country: Optional[str] = Field(default=None, description="Country")
    long_description: Optional[str] = Field(default=None, description="Full band biography")
    
    # Social/external links
    website_url: Optional[str] = Field(default=None)
    wikipedia_url: Optional[str] = Field(default=None)
    bandcamp_url: Optional[str] = Field(default=None)
    nugs_url: Optional[str] = Field(default=None)
    relisten_url: Optional[str] = Field(default=None)
    spotify_url: Optional[str] = Field(default=None)
    
    # Relationships
    shows: List["Show"] = Relationship(back_populates="vertical")
    songs: List["Song"] = Relationship(back_populates="vertical")
    scenes: List["Scene"] = Relationship(back_populates="verticals", link_model=VerticalScene)
    user_preferences: List["UserVerticalPreference"] = Relationship(back_populates="vertical")

class VenueCanon(SQLModel, table=True):
    """Canonical venue independent of band - enables cross-band venue linking (like SongCanon for songs)"""
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str = Field(index=True)
    slug: str = Field(unique=True, index=True)
    city: str
    state: Optional[str] = Field(default=None)
    country: str = Field(default="USA")
    latitude: Optional[float] = Field(default=None)
    longitude: Optional[float] = Field(default=None)
    capacity: Optional[int] = Field(default=None)
    website_url: Optional[str] = Field(default=None)
    notes: Optional[str] = Field(default=None)
    
    # All venue records that point to this canonical venue
    venues: List["Venue"] = Relationship(back_populates="canon")


class Venue(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str = Field(index=True)
    slug: Optional[str] = Field(default=None, unique=True, index=True)
    city: str
    state: Optional[str] = Field(default=None)
    country: str
    capacity: Optional[int] = Field(default=None)
    notes: Optional[str] = Field(default=None)
    
    # Link to canonical venue for cross-band deduplication
    canon_id: Optional[int] = Field(default=None, foreign_key="venuecanon.id")
    canon: Optional[VenueCanon] = Relationship(back_populates="venues")
    
    shows: List["Show"] = Relationship(back_populates="venue")


class Tour(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str = Field(index=True)
    slug: Optional[str] = Field(default=None, unique=True, index=True)
    start_date: Optional[datetime] = None
    end_date: Optional[datetime] = None
    notes: Optional[str] = Field(default=None)
    
    shows: List["Show"] = Relationship(back_populates="tour")


class Festival(SQLModel, table=True):
    """Multi-band festivals that span multiple shows/dates (Bonnaroo, Lockn, etc.)"""
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str = Field(index=True)
    slug: str = Field(unique=True, index=True)
    year: Optional[int] = Field(default=None, description="Festival year/edition")
    start_date: Optional[datetime] = None
    end_date: Optional[datetime] = None
    venue_id: Optional[int] = Field(default=None, foreign_key="venue.id")
    website_url: Optional[str] = Field(default=None)
    description: Optional[str] = Field(default=None)
    
    # Relationships
    shows: List["ShowFestival"] = Relationship(back_populates="festival")


class ShowFestival(SQLModel, table=True):
    """Link table for shows at festivals (many-to-many)"""
    id: Optional[int] = Field(default=None, primary_key=True)
    show_id: int = Field(foreign_key="show.id")
    festival_id: int = Field(foreign_key="festival.id")
    stage: Optional[str] = Field(default=None, description="Which stage (Main, Second, etc.)")
    set_time: Optional[str] = Field(default=None, description="Scheduled time slot")
    
    festival: Festival = Relationship(back_populates="shows")

class Artist(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str = Field(index=True)
    slug: str = Field(unique=True, index=True)
    bio: Optional[str] = Field(default=None)
    image_url: Optional[str] = Field(default=None)
    instrument: Optional[str] = Field(default=None)
    notes: Optional[str] = Field(default=None)
    
    songs: List["Song"] = Relationship(back_populates="artist")

class Musician(SQLModel, table=True):
    """Individual human musicians (for tracking sit-ins and band membership)"""
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str = Field(index=True)
    slug: str = Field(unique=True, index=True)
    bio: Optional[str] = Field(default=None)
    image_url: Optional[str] = Field(default=None)
    primary_instrument: Optional[str] = Field(default=None)
    notes: Optional[str] = Field(default=None)
    
    # Rich profile fields
    birth_year: Optional[int] = Field(default=None)
    origin_city: Optional[str] = Field(default=None)
    origin_state: Optional[str] = Field(default=None)
    origin_country: Optional[str] = Field(default=None)
    
    # Social links
    website_url: Optional[str] = Field(default=None)
    wikipedia_url: Optional[str] = Field(default=None)
    instagram_url: Optional[str] = Field(default=None)
    
    # Relationships
    memberships: List["BandMembership"] = Relationship(back_populates="musician")
    guest_appearances: List["PerformanceGuest"] = Relationship(back_populates="musician")

class BandMembership(SQLModel, table=True):
    """Link between Musician and Band/Artist with role and dates"""
    id: Optional[int] = Field(default=None, primary_key=True)
    musician_id: int = Field(foreign_key="musician.id")
    artist_id: int = Field(foreign_key="artist.id", description="The band/group")
    role: Optional[str] = Field(default=None, description="e.g., Keyboards, Rhythm Guitar")
    start_date: Optional[datetime] = Field(default=None)
    end_date: Optional[datetime] = Field(default=None, description="Null = current member")
    notes: Optional[str] = Field(default=None)
    
    musician: Musician = Relationship(back_populates="memberships")
    artist: Artist = Relationship()

class PerformanceGuest(SQLModel, table=True):
    """Link between Performance and Musician for sit-ins/guest appearances"""
    id: Optional[int] = Field(default=None, primary_key=True)
    performance_id: int = Field(foreign_key="performance.id")
    musician_id: int = Field(foreign_key="musician.id")
    instrument: Optional[str] = Field(default=None, description="What they played on this track")
    notes: Optional[str] = Field(default=None)
    
    musician: Musician = Relationship(back_populates="guest_appearances")


class Show(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    date: datetime = Field(index=True)
    slug: Optional[str] = Field(default=None, unique=True, index=True)
    vertical_id: int = Field(foreign_key="vertical.id")
    venue_id: Optional[int] = Field(default=None, foreign_key="venue.id")
    tour_id: Optional[int] = Field(default=None, foreign_key="tour.id")
    notes: Optional[str] = Field(default=None)
    
    # External Links
    bandcamp_link: Optional[str] = Field(default=None)
    nugs_link: Optional[str] = Field(default=None)
    youtube_link: Optional[str] = Field(default=None)
    relisten_link: Optional[str] = Field(default=None, description="Link to Relisten.net or archive.org")
    
    vertical: Vertical = Relationship(back_populates="shows")
    venue: Optional[Venue] = Relationship(back_populates="shows")
    tour: Optional[Tour] = Relationship(back_populates="shows")
    attendances: List["Attendance"] = Relationship(back_populates="show")
    performances: List["Performance"] = Relationship(back_populates="show")

class SongCanon(SQLModel, table=True):
    """Canonical 'master' song independent of band - enables cross-band song linking"""
    id: Optional[int] = Field(default=None, primary_key=True)
    title: str = Field(index=True)
    slug: str = Field(unique=True, index=True)
    original_artist: Optional[str] = Field(default=None, description="Original songwriter/band")
    original_artist_id: Optional[int] = Field(default=None, foreign_key="artist.id")
    notes: Optional[str] = Field(default=None)
    
    # All vertical-specific versions of this song
    versions: List["Song"] = Relationship(back_populates="canon")

class Song(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    title: str = Field(index=True)
    slug: Optional[str] = Field(default=None, unique=True, index=True)
    original_artist: Optional[str] = Field(default=None)
    vertical_id: int = Field(foreign_key="vertical.id")
    notes: Optional[str] = Field(default=None)
    youtube_link: Optional[str] = Field(default=None)
    
    # Link to canonical song for cross-band tracking
    canon_id: Optional[int] = Field(default=None, foreign_key="songcanon.id")
    canon: Optional[SongCanon] = Relationship(back_populates="versions")
    
    # Artist who wrote/performs this version
    artist_id: Optional[int] = Field(default=None, foreign_key="artist.id")
    artist: Optional["Artist"] = Relationship(back_populates="songs")
    
    vertical: "Vertical" = Relationship(back_populates="songs")

class Sequence(SQLModel, table=True):
    """Named groupings of consecutive songs, e.g. 'Autumn Crossing' = Travelers > Elmeg the Wise"""
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str = Field(index=True, description="Human-readable name like 'Autumn Crossing'")
    slug: str = Field(unique=True, index=True)
    description: Optional[str] = Field(default=None)
    notes: Optional[str] = Field(default=None)
    
    # Relationship to songs that make up this sequence
    songs: List["SequenceSong"] = Relationship(back_populates="sequence")

class SequenceSong(SQLModel, table=True):
    """Join table linking songs to sequences with ordering"""
    id: Optional[int] = Field(default=None, primary_key=True)
    sequence_id: int = Field(foreign_key="sequence.id")
    song_id: int = Field(foreign_key="song.id")
    position: int = Field(description="Order in sequence, 1-indexed")
    
    sequence: Sequence = Relationship(back_populates="songs")

class Tag(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str = Field(unique=True, index=True)
    slug: str = Field(unique=True, index=True)

class PreferenceTier(str, Enum):
    HEADLINER = "headliner"
    MAIN_STAGE = "main_stage"
    SUPPORTING = "supporting"

class UserVerticalPreference(SQLModel, table=True):
    """User preferences for which bands to display prominently vs. attribution-only"""
    id: Optional[int] = Field(default=None, primary_key=True)
    user_id: int = Field(foreign_key="user.id", index=True)
    vertical_id: int = Field(foreign_key="vertical.id", index=True)
    
    # Preferences
    display_mode: str = Field(default="standard") # compact, standard, expanded
    priority: int = Field(default=0) # 0-100 sorting
    tier: PreferenceTier = Field(default=PreferenceTier.MAIN_STAGE)
    notify_on_show: bool = Field(default=True)
    
    created_at: datetime = Field(default_factory=datetime.utcnow)
    
    user: "User" = Relationship(back_populates="vertical_preferences")
    vertical: "Vertical" = Relationship(back_populates="user_preferences")

class Attendance(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    user_id: int = Field(foreign_key="user.id")
    show_id: int = Field(foreign_key="show.id")
    notes: Optional[str] = Field(default=None)
    created_at: datetime = Field(default_factory=datetime.utcnow)
    
    user: "User" = Relationship(back_populates="attendances")
    show: "Show" = Relationship(back_populates="attendances")

class Comment(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    user_id: int = Field(foreign_key="user.id")
    content: str
    created_at: datetime = Field(default_factory=datetime.utcnow)
    
    # Polymorphic-ish associations (nullable FKs)
    show_id: Optional[int] = Field(default=None, foreign_key="show.id")
    venue_id: Optional[int] = Field(default=None, foreign_key="venue.id")
    song_id: Optional[int] = Field(default=None, foreign_key="song.id")
    parent_id: Optional[int] = Field(default=None, foreign_key="comment.id")
    
    user: "User" = Relationship(back_populates="comments")

class Rating(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    user_id: int = Field(foreign_key="user.id")
    score: float = Field(ge=1.0, le=10.0, description="Rating from 1.0 to 10.0")
    created_at: datetime = Field(default_factory=datetime.utcnow)
    
    show_id: Optional[int] = Field(default=None, foreign_key="show.id")
    song_id: Optional[int] = Field(default=None, foreign_key="song.id")
    performance_id: Optional[int] = Field(default=None, foreign_key="performance.id")
    venue_id: Optional[int] = Field(default=None, foreign_key="venue.id")
    tour_id: Optional[int] = Field(default=None, foreign_key="tour.id")
    
    user: "User" = Relationship(back_populates="ratings")

class NotificationType(str, Enum):
    SHOW_ALERT = "SHOW_ALERT"
    SIT_IN_ALERT = "SIT_IN_ALERT"
    CHASE_SONG_ALERT = "CHASE_SONG_ALERT"

class Notification(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    user_id: int = Field(foreign_key="user.id", index=True)
    type: NotificationType
    title: str
    message: str
    link: Optional[str] = None
    is_read: bool = Field(default=False)
    created_at: datetime = Field(default_factory=datetime.utcnow)

    user: "User" = Relationship(back_populates="notifications")

class User(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    email: str = Field(unique=True, index=True)
    hashed_password: str
    is_active: bool = Field(default=True)
    is_superuser: bool = Field(default=False)
    role: str = Field(default="user") # user, moderator, admin
    bio: Optional[str] = Field(default=None)
    avatar: Optional[str] = Field(default=None)
    avatar_bg_color: Optional[str] = Field(default="#3B82F6", description="Hex color for avatar background")
    avatar_text: Optional[str] = Field(default=None, description="1-3 character text overlay on avatar")
    
    # Privacy settings
    profile_public: bool = Field(default=True, description="Allow others to view profile")
    show_attendance_public: bool = Field(default=True, description="Show attended shows on profile")
    appear_in_leaderboards: bool = Field(default=True, description="Appear in community leaderboards")
    
    # Gamification
    xp: int = Field(default=0, description="Experience points")
    level: int = Field(default=1, description="User level based on XP")
    streak_days: int = Field(default=0, description="Consecutive days active")
    last_activity: Optional[datetime] = Field(default=None)
    
    # Social Identity
    bluesky_handle: Optional[str] = Field(default=None)
    mastodon_handle: Optional[str] = Field(default=None)
    instagram_handle: Optional[str] = Field(default=None)
    location: Optional[str] = Field(default=None, description="User's local scene/city")

    # Custom Titles & Flair (tracker forum style)
    custom_title: Optional[str] = Field(default=None, description="Custom title chosen by user")
    title_color: Optional[str] = Field(default=None, description="Hex color for username display")
    flair: Optional[str] = Field(default=None, description="Small text/emoji beside name")
    is_early_adopter: bool = Field(default=False, description="First 100 users get special perks")
    is_supporter: bool = Field(default=False, description="Donated/supported the platform")
    joined_at: datetime = Field(default_factory=datetime.utcnow)
    
    # Email verification
    email_verified: bool = Field(default=False)
    verification_token: Optional[str] = Field(default=None)
    verification_token_expires: Optional[datetime] = Field(default=None)
    
    # Password reset
    reset_token: Optional[str] = Field(default=None)
    reset_token_expires: Optional[datetime] = Field(default=None)
    
    # Multi-identity support: A user can have multiple Profiles
    profiles: List["Profile"] = Relationship(back_populates="user")
    comments: List["Comment"] = Relationship(back_populates="user")
    ratings: List["Rating"] = Relationship(back_populates="user")
    reviews: List["Review"] = Relationship(back_populates="user")
    attendances: List["Attendance"] = Relationship(back_populates="user")
    badges: List["UserBadge"] = Relationship(back_populates="user")
    preferences: Optional["UserPreferences"] = Relationship(back_populates="user", sa_relationship_kwargs={"uselist": False})
    reports: List["Report"] = Relationship(back_populates="user")
    notifications: List["Notification"] = Relationship(back_populates="user")
    playlists: List["UserPlaylist"] = Relationship(back_populates="user")
    vertical_preferences: List["UserVerticalPreference"] = Relationship(back_populates="user")


class UserPlaylist(SQLModel, table=True):
    """User-created curated collections of performances"""
    id: Optional[int] = Field(default=None, primary_key=True)
    user_id: int = Field(foreign_key="user.id")
    name: str = Field(index=True)
    slug: str = Field(index=True)
    description: Optional[str] = Field(default=None)
    is_public: bool = Field(default=True)
    created_at: datetime = Field(default_factory=datetime.utcnow)
    updated_at: datetime = Field(default_factory=datetime.utcnow)
    
    # Relationships
    user: "User" = Relationship(back_populates="playlists")
    performances: List["PlaylistPerformance"] = Relationship(back_populates="playlist")


class PlaylistPerformance(SQLModel, table=True):
    """Link table for performances in playlists with ordering"""
    id: Optional[int] = Field(default=None, primary_key=True)
    playlist_id: int = Field(foreign_key="userplaylist.id")
    performance_id: int = Field(foreign_key="performance.id")
    position: int = Field(description="Order in playlist, 1-indexed")
    added_at: datetime = Field(default_factory=datetime.utcnow)
    notes: Optional[str] = Field(default=None, description="User notes about this performance")
    
    playlist: UserPlaylist = Relationship(back_populates="performances")

class Report(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    user_id: int = Field(foreign_key="user.id")
    entity_type: str = Field(index=True) # comment, review, nickname
    entity_id: int = Field(index=True)
    reason: str
    details: str = Field(default="")
    status: str = Field(default="pending", index=True) # pending, resolved, dismissed
    created_at: datetime = Field(default_factory=datetime.utcnow)
    
    user: "User" = Relationship(back_populates="reports")

class Badge(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str = Field(unique=True, index=True)
    description: str
    icon: str = Field(description="Lucide icon name or image URL")
    slug: str = Field(unique=True, index=True)
    tier: str = Field(default="bronze", description="bronze, silver, gold, platinum, diamond")
    category: str = Field(default="general", description="attendance, ratings, social, milestones")
    xp_reward: int = Field(default=50, description="XP awarded when badge is earned")

class UserBadge(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    user_id: int = Field(foreign_key="user.id")
    badge_id: int = Field(foreign_key="badge.id")
    awarded_at: datetime = Field(default_factory=datetime.utcnow)
    
    user: "User" = Relationship(back_populates="badges")
    badge: "Badge" = Relationship()

class Review(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    user_id: int = Field(foreign_key="user.id")
    blurb: str = Field(description="One-liner/pullquote")
    content: str = Field(description="Full review text")
    score: float = Field(ge=1.0, le=10.0)
    show_id: Optional[int] = Field(default=None, foreign_key="show.id")
    venue_id: Optional[int] = Field(default=None, foreign_key="venue.id")
    song_id: Optional[int] = Field(default=None, foreign_key="song.id")
    performance_id: Optional[int] = Field(default=None, foreign_key="performance.id")
    tour_id: Optional[int] = Field(default=None, foreign_key="tour.id")
    year: Optional[int] = Field(default=None, description="For reviewing a specific year")
    created_at: datetime = Field(default_factory=datetime.utcnow)
    
    user: "User" = Relationship(back_populates="reviews")

class UserPreferences(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    user_id: int = Field(foreign_key="user.id", unique=True)
    wiki_mode: bool = Field(default=False, description="Disable social features")
    show_ratings: bool = Field(default=True)
    show_comments: bool = Field(default=True)
    
    # Theme preference (synced from frontend)
    theme: str = Field(default="system", description="light, dark, or system")
    
    # Email notification preferences
    email_on_reply: bool = Field(default=True, description="Email when someone replies to your review")
    email_on_chase: bool = Field(default=True, description="Email when your chase song is played")
    email_digest: bool = Field(default=False, description="Weekly digest email")
    
    user: "User" = Relationship(back_populates="preferences")



class Profile(SQLModel, table=True):
    """A user's identity within a specific context or global"""
    id: Optional[int] = Field(default=None, primary_key=True)
    user_id: int = Field(foreign_key="user.id")
    username: str = Field(index=True)
    display_name: Optional[str] = Field(default=None)
    
    user: User = Relationship(back_populates="profiles")

# --- Groups ---
class Group(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str = Field(index=True, unique=True)
    description: Optional[str] = None
    privacy: str = Field(default="public") # public, private, invite_only
    created_by: int = Field(foreign_key="user.id")
    created_at: datetime = Field(default_factory=datetime.utcnow)
    
    # Vertical scoping (optional - null means cross-band group)
    vertical_id: Optional[int] = Field(default=None, foreign_key="vertical.id", index=True)
    image_url: Optional[str] = Field(default=None, description="Group logo/image URL")
    
    members: List["GroupMember"] = Relationship(back_populates="group")
    posts: List["GroupPost"] = Relationship(back_populates="group")

class GroupMember(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    group_id: int = Field(foreign_key="group.id")
    user_id: int = Field(foreign_key="user.id")
    role: str = Field(default="member") # member, admin
    joined_at: datetime = Field(default_factory=datetime.utcnow)
    
    group: Group = Relationship(back_populates="members")
    user: User = Relationship()

class GroupPost(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    group_id: int = Field(foreign_key="group.id")
    user_id: int = Field(foreign_key="user.id")
    content: str
    created_at: datetime = Field(default_factory=datetime.utcnow)
    
    group: Group = Relationship(back_populates="posts")
    user: User = Relationship()


class Reaction(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    user_id: int = Field(foreign_key="user.id")
    entity_type: str = Field(index=True) # "review", "comment"
    entity_id: int = Field(index=True)
    emoji: str # "❤️", "🔥", etc.
    created_at: datetime = Field(default_factory=datetime.utcnow)
    
    user: User = Relationship()

class ChaseSong(SQLModel, table=True):
    """Songs a user wants to see live (hasn't seen performed yet or wants to see again)"""
    id: Optional[int] = Field(default=None, primary_key=True)
    user_id: int = Field(foreign_key="user.id", index=True)
    song_id: int = Field(foreign_key="song.id", index=True)
    priority: int = Field(default=1, description="1=high, 2=medium, 3=low")
    notes: Optional[str] = Field(default=None)
    created_at: datetime = Field(default_factory=datetime.utcnow)
    caught_at: Optional[datetime] = Field(default=None, description="When they finally saw it")
    caught_show_id: Optional[int] = Field(default=None, foreign_key="show.id")
    
    user: User = Relationship()
    song: "Song" = Relationship()

