"""Domain model for a parsed web page.

Backed by both PostgreSQL (primary) and Doris (warehouse subset).
Keyed by a UUID ``id`` column — every parse creates a new unique row.
Upsert target is ``url`` (unique constraint in PG).
"""

from __future__ import annotations

from datetime import datetime

from repo_core.base.models import DomainModel


class WebParsedPage(DomainModel):
    """Strongly-typed representation of a parsed web page record.

    Dual-backend: PostgreSQL and Doris (identical column sets).
    Upserted by ``url`` — re-parsing the same URL replaces the existing row.

    System-managed timestamps (``created_at``, ``updated_at``) use
    ``datetime`` following repo_core convention.  Content timestamps
    (``published_time``, ``parsed_at``) are ISO 8601 strings from the
    parser output.

    Usage::

        page = WebParsedPage.from_db({
            "id": "550e8400-...",
            "url": "https://example.com",
            "seed_id": "seed-uuid",
            "title": "Example Page",
            "parsed_at": "2026-07-19T12:00:00+00:00",
            "created_at": datetime(2026, 7, 19, 12, 0, tzinfo=timezone.utc),
        })
        row = page.to_db()
    """

    # -- Identity -------------------------------------------------------
    id: str
    url: str
    seed_id: str
    raw_url_id: str | None = None  # DB id of the source raw HTML row (from web_html_raw)

    # -- Core parsed fields ---------------------------------------------
    title: str | None = None
    description: str | None = None
    author: str | None = None
    published_time: str | None = None  # ISO 8601 string
    main_image: str | None = None

    # -- Content --------------------------------------------------------
    content: str | None = None
    content_html: str | None = None

    # -- Classification -------------------------------------------------
    keywords: list[str] | None = None
    tags: list[str] | None = None
    category: str | None = None

    # -- Structured data ------------------------------------------------
    images: list[dict] | None = None
    tables: list[dict] | None = None
    links: list[dict] | None = None
    schema_data: list[dict] | None = None
    statistics: dict | None = None

    # -- Custom / extension data ----------------------------------------
    custom_content: dict | None = None

    # -- Metadata -------------------------------------------------------
    parsed_at: datetime | None = None
    diagnostics: dict | None = None

    # -- Versioning (append-only per URL, mirrors web_html_raw) ---------
    version: int = 1  # Monotonically increasing per URL

    # -- Timestamps -----------------------------------------------------
    created_at: datetime | None = None
    updated_at: datetime | None = None

    # -- Backend field filtering ----------------------------------------
    # PostgreSQL: all fields except warehouse-only flags
    _db_include: set[str] | None = {
        "id",
        "url",
        "seed_id",
        "raw_url_id",
        "title",
        "description",
        "author",
        "published_time",
        "main_image",
        "content",
        "content_html",
        "keywords",
        "tags",
        "category",
        "images",
        "tables",
        "links",
        "schema_data",
        "statistics",
        "custom_content",
        "parsed_at",
        "diagnostics",
        "version",
        "created_at",
        "updated_at",
    }

    # Doris: full parity with PostgreSQL — all fields included for analytics.
    _warehouse_include: set[str] | None = {
        "id",
        "url",
        "seed_id",
        "raw_url_id",
        "title",
        "description",
        "author",
        "published_time",
        "main_image",
        "content",
        "content_html",
        "keywords",
        "tags",
        "category",
        "images",
        "tables",
        "links",
        "schema_data",
        "statistics",
        "custom_content",
        "parsed_at",
        "diagnostics",
        "version",
        "created_at",
        "updated_at",
    }

    # Elasticsearch: not indexed
    _search_include: set[str] | None = set()

    _timestamps = {"created_at", "updated_at"}
