"""Source — a platform-specific URL owned by an Artist (e.g., a Patreon URL).

Multiple sources per artist support creators with cross-platform presence.
"""

from datetime import datetime

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

from .base import Base


class Source(Base):
    __tablename__ = "source"

    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    artist_id: Mapped[int] = mapped_column(
        ForeignKey("artist.id", ondelete="CASCADE"), nullable=False, index=True
    )
    platform: Mapped[str] = mapped_column(String(64), nullable=False)
    url: Mapped[str] = mapped_column(Text, nullable=False)
    enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)

    config_overrides: Mapped[dict | None] = mapped_column(JSON, nullable=True)

    last_checked_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
    last_error: Mapped[str | None] = mapped_column(Text, nullable=True)
    # alembic 0032: last ErrorType category (auth_error, rate_limited,
    # not_found, ...). Lets FailingSourcesCard surface the taxonomy as
    # a colored chip so operators can bulk-triage by error class. Set
    # by _update_source_health alongside last_error; cleared on 'ok'.
    error_type: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
    check_interval_override: Mapped[int | None] = mapped_column(Integer, nullable=True)
    consecutive_failures: Mapped[int] = mapped_column(Integer, nullable=False, default=0)

    # alembic 0031: sticky deep-scan budget. When > 0, the next N download
    # runs use gallery-dl's full-walk config (skip: True + 1800s timeout);
    # when 0, runs use tick mode (skip: "exit:20" + 870s, exits early once
    # 20 contiguous archived items are seen). Auto-decrements per run, with
    # an auto-reset to 0 on clean exit + zero downloads (queue drained).
    backfill_runs_remaining: Mapped[int] = mapped_column(
        Integer, nullable=False, default=0, server_default="0",
    )

    artist = relationship("Artist", back_populates="sources")
