"""
ViralAcademy Models - Learning progress, achievements, challenges, growth plans.
"""

from datetime import datetime

from sqlalchemy import String, Integer, Float, DateTime, Text, JSON, Boolean
from sqlalchemy.orm import Mapped, mapped_column

from backend.database.connection import Base


class UserProgress(Base):
    """Track user learning progress and XP."""
    __tablename__ = "user_progress"

    id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    user_id: Mapped[str] = mapped_column(String(50), default="default", index=True)
    xp: Mapped[int] = mapped_column(Integer, default=0)
    level: Mapped[int] = mapped_column(Integer, default=1)
    streak_days: Mapped[int] = mapped_column(Integer, default=0)
    last_active: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
    completed_modules: Mapped[dict | None] = mapped_column(JSON, default=list)
    skill_scores: Mapped[dict | None] = mapped_column(JSON, default=dict)
    total_challenges_done: Mapped[int] = mapped_column(Integer, default=0)
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)

    def to_dict(self) -> dict:
        return {
            "id": self.id,
            "user_id": self.user_id,
            "xp": self.xp,
            "level": self.level,
            "streak_days": self.streak_days,
            "last_active": self.last_active.isoformat() if self.last_active else None,
            "completed_modules": self.completed_modules or [],
            "skill_scores": self.skill_scores or {},
            "total_challenges_done": self.total_challenges_done,
            "xp_to_next": self.level * 500,
            "xp_progress": round((self.xp % (self.level * 500)) / max(1, self.level * 500) * 100),
        }


class Achievement(Base):
    """Achievements/badges system."""
    __tablename__ = "achievements"

    id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    code: Mapped[str] = mapped_column(String(50), unique=True, index=True)
    name: Mapped[str] = mapped_column(String(200))
    description: Mapped[str] = mapped_column(Text, default="")
    icon: Mapped[str] = mapped_column(String(50), default="award")
    xp_reward: Mapped[int] = mapped_column(Integer, default=100)
    category: Mapped[str] = mapped_column(String(50), default="geral")
    rarity: Mapped[str] = mapped_column(String(20), default="comum")  # comum, raro, epico, lendario
    condition: Mapped[str] = mapped_column(Text, default="")
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)

    def to_dict(self) -> dict:
        return {
            "id": self.id,
            "code": self.code,
            "name": self.name,
            "description": self.description,
            "icon": self.icon,
            "xp_reward": self.xp_reward,
            "category": self.category,
            "rarity": self.rarity,
            "condition": self.condition,
        }


class UserAchievement(Base):
    """Tracks which achievements a user has earned."""
    __tablename__ = "user_achievements"

    id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    user_id: Mapped[str] = mapped_column(String(50), default="default", index=True)
    achievement_code: Mapped[str] = mapped_column(String(50), index=True)
    earned_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)

    def to_dict(self) -> dict:
        return {
            "user_id": self.user_id,
            "achievement_code": self.achievement_code,
            "earned_at": self.earned_at.isoformat() if self.earned_at else None,
        }


class Challenge(Base):
    """Daily/weekly challenges for gamification."""
    __tablename__ = "challenges"

    id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    title: Mapped[str] = mapped_column(String(300))
    description: Mapped[str] = mapped_column(Text, default="")
    challenge_type: Mapped[str] = mapped_column(String(20), default="daily")  # daily, weekly
    xp_reward: Mapped[int] = mapped_column(Integer, default=50)
    category: Mapped[str] = mapped_column(String(50), default="conteudo")
    is_completed: Mapped[bool] = mapped_column(Boolean, default=False)
    user_id: Mapped[str] = mapped_column(String(50), default="default", index=True)
    expires_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)

    def to_dict(self) -> dict:
        return {
            "id": self.id,
            "title": self.title,
            "description": self.description,
            "challenge_type": self.challenge_type,
            "xp_reward": self.xp_reward,
            "category": self.category,
            "is_completed": self.is_completed,
            "expires_at": self.expires_at.isoformat() if self.expires_at else None,
            "created_at": self.created_at.isoformat() if self.created_at else None,
        }


class GrowthPlan(Base):
    """AI-generated growth plans."""
    __tablename__ = "growth_plans"

    id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    user_id: Mapped[str] = mapped_column(String(50), default="default", index=True)
    title: Mapped[str] = mapped_column(String(300), default="Plano de Crescimento 90 Dias")
    plan_data: Mapped[dict | None] = mapped_column(JSON, default=dict)
    duration_days: Mapped[int] = mapped_column(Integer, default=90)
    progress_percent: Mapped[float] = mapped_column(Float, default=0.0)
    status: Mapped[str] = mapped_column(String(20), default="active")  # active, completed, paused
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
    updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

    def to_dict(self) -> dict:
        return {
            "id": self.id,
            "user_id": self.user_id,
            "title": self.title,
            "plan_data": self.plan_data or {},
            "duration_days": self.duration_days,
            "progress_percent": self.progress_percent,
            "status": self.status,
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "updated_at": self.updated_at.isoformat() if self.updated_at else None,
        }
