from datetime import datetime
from typing import Optional

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

from .database import Base


class Registration(Base):
    """A yatra participant registration. Mirrors the frontend `Registration` type."""

    __tablename__ = "registrations"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    registration_id: Mapped[str] = mapped_column(String(32), unique=True, index=True)

    name: Mapped[str] = mapped_column(String(120))
    email: Mapped[str] = mapped_column(String(180), index=True)
    phone: Mapped[str] = mapped_column(String(20))
    age: Mapped[int] = mapped_column(Integer)
    city: Mapped[str] = mapped_column(String(120))
    blood_group: Mapped[str] = mapped_column(String(8))
    experience: Mapped[str] = mapped_column(String(40))
    weekly_km: Mapped[int] = mapped_column(Integer)
    leg_choice: Mapped[str] = mapped_column(String(16))
    needs_rental: Mapped[bool] = mapped_column(Boolean, default=False)
    tshirt_size: Mapped[str] = mapped_column(String(4))
    emergency_contact_name: Mapped[str] = mapped_column(String(120))
    emergency_contact_phone: Mapped[str] = mapped_column(String(20))
    medical_fitness_confirmed: Mapped[bool] = mapped_column(Boolean, default=False)

    registered_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now()
    )


class ContactMessage(Base):
    """A "Contact Us" form submission."""

    __tablename__ = "contact_messages"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    name: Mapped[str] = mapped_column(String(120))
    email: Mapped[str] = mapped_column(String(180), index=True)
    phone: Mapped[str] = mapped_column(String(20))
    message: Mapped[Optional[str]] = mapped_column(Text, nullable=True)

    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now()
    )


class SponsorshipRequest(Base):
    """A sponsorship / partnership request submission."""

    __tablename__ = "sponsorship_requests"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    company: Mapped[str] = mapped_column(String(180))
    contact_name: Mapped[str] = mapped_column(String(120))
    tier: Mapped[str] = mapped_column(String(120))
    email: Mapped[Optional[str]] = mapped_column(String(180), index=True, nullable=True)
    phone: Mapped[Optional[str]] = mapped_column(String(20), nullable=True)
    message: Mapped[Optional[str]] = mapped_column(Text, nullable=True)

    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now()
    )


class AdminUser(Base):
    """A back-office admin account. Role gates access to submission data."""

    __tablename__ = "admin_users"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    email: Mapped[str] = mapped_column(String(180), unique=True, index=True)
    name: Mapped[str] = mapped_column(String(120))
    hashed_password: Mapped[str] = mapped_column(String(255))
    role: Mapped[str] = mapped_column(String(20), default="viewer")
    is_active: Mapped[bool] = mapped_column(Boolean, default=True)

    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now()
    )


class MediaAsset(Base):
    """A gallery image hosted on Cloudinary. Metadata mirrors the upload response."""

    __tablename__ = "media_assets"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    # Cloudinary public_id — the handle used to build delivery URLs and to delete.
    public_id: Mapped[str] = mapped_column(String(255), unique=True, index=True)
    secure_url: Mapped[str] = mapped_column(String(512))

    title: Mapped[Optional[str]] = mapped_column(String(200), nullable=True)
    category: Mapped[str] = mapped_column(String(80), default="gallery", index=True)

    format: Mapped[Optional[str]] = mapped_column(String(16), nullable=True)
    width: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
    height: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
    bytes: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)

    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now()
    )
