"""Domain model for codal.ir financial statements.

Phase 1: statement type discovery — URL + classification.
Phase 2: publisher discovery — company name + stock symbol.
"""

from __future__ import annotations

from datetime import datetime
from typing import Any

from repo_core.base.models import DomainModel


class CodalStatement(DomainModel):
    """A financial statement discovered on my.codal.ir.

    Each row represents one statement URL/version pair with its
    classification.  The same URL may appear in multiple versions.

    Phase 1 fields: identity + classification.
    Phase 2 fields: publisher link + publish metadata.
    Phase 3 fields: statement detail + fetch lifecycle.
    """

    # -- Identity -------------------------------------------------------
    id: str
    url: str
    version: int = 1
    statement_id: str | None = None

    # -- Classification (Phase 1) ---------------------------------------
    statement_type: str | None = None
    source_page_url: str | None = None
    anchor_text: str | None = None

    # -- Publisher link (Phase 2) --------------------------------------
    publisher_id: int | None = None
    publish_date: datetime | None = None
    code: str | None = None

    # -- Statement detail (Phase 3) ------------------------------------
    statement_title: str | None = None
    sent_datetime: str | None = None
    discovery_time: datetime | None = None
    fetch_datetime: datetime | None = None
    status: str | None = None
    tracking_number: str | None = None
    view_number: str | None = None
    alert: str | None = None
    details: dict[str, Any] | None = None
    raw_hash: str | None = None

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

    # -- Backend field filtering ----------------------------------------
    _db_include: set[str] | None = {
        "id", "url", "version", "statement_id", "statement_type", "source_page_url",
        "anchor_text", "publisher_id", "publish_date", "code",
        "statement_title", "sent_datetime", "discovery_time",
        "fetch_datetime", "status", "tracking_number",
        "view_number", "alert", "details", "raw_hash",
        "created_at", "updated_at",
    }
    _search_include: set[str] | None = set()
    _warehouse_include: set[str] | None = None
    _timestamps = {"created_at", "updated_at"}


class CodalPublisher(DomainModel):
    """A publisher (company) discovered on my.codal.ir.

    Keyed by ``(publisher_id, version)``.  ``publisher_id`` is the numeric
    ID from the URL path (``/fa/publisher/<publisher_id>``).  ``name`` is
    the company name extracted from the ``p.logo-name`` CSS selector.
    ``namad`` is the stock symbol extracted from ``small.symbol-name``.

    Multiple publishers may share the same ``namad`` (different share
    classes of the same company).  Each re-parse that produces different
    content creates a new version.
    """

    # -- Identity -------------------------------------------------------
    id: str
    publisher_id: int
    url: str
    version: int = 1

    # -- Extracted fields -----------------------------------------------
    name: str | None = None
    namad: str | None = None

    # -- Change detection -----------------------------------------------
    raw_hash: str | None = None

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

    # -- Backend field filtering ----------------------------------------
    _db_include: set[str] | None = {
        "id", "publisher_id", "url", "version",
        "name", "namad", "raw_hash",
        "created_at", "updated_at",
    }
    _search_include: set[str] | None = set()
    _warehouse_include: set[str] | None = None
    _timestamps = {"created_at", "updated_at"}


class CodalPublisherDetail(DomainModel):
    """Detailed company info extracted from the publisher profile page.

    Keyed by ``(publisher_id, version)``.  Each re-parse that produces
    different content creates a new version.

    All text fields are raw Persian values as displayed on codal.ir.
    """

    # -- Identity -------------------------------------------------------
    id: str
    publisher_id: int
    version: int = 1

    # -- Company info table ---------------------------------------------
    ceo: str | None = None
    cfo: str | None = None
    activity_field: str | None = None
    auditor: str | None = None
    alt_auditor: str | None = None
    company_type: str | None = None
    acceptance_type: str | None = None
    nature: str | None = None
    registered_capital: str | None = None
    unregistered_capital: str | None = None
    national_id: str | None = None
    isic: str | None = None
    isin: str | None = None
    fiscal_year_end: str | None = None
    seo_deposit_id: str | None = None

    # -- Stock / market info --------------------------------------------
    industry_group: str | None = None
    stock_status: str | None = None

    # -- Change detection -----------------------------------------------
    raw_hash: str | None = None

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

    # -- Backend field filtering ----------------------------------------
    _db_include: set[str] | None = {
        "id", "publisher_id", "version",
        "ceo", "cfo", "activity_field", "auditor", "alt_auditor",
        "company_type", "acceptance_type", "nature",
        "registered_capital", "unregistered_capital",
        "national_id", "isic", "isin", "fiscal_year_end", "seo_deposit_id",
        "industry_group", "stock_status", "raw_hash",
        "created_at", "updated_at",
    }
    _search_include: set[str] | None = set()
    _warehouse_include: set[str] | None = None
    _timestamps = {"created_at", "updated_at"}


class CodalPublisherContact(DomainModel):
    """Contact information extracted from ``/fa/publisher/<id>/contact``.

    Keyed by ``(publisher_id, version)``.  Each re-parse that produces
    different content creates a new version.
    """

    id: str
    publisher_id: int
    version: int = 1

    factory_address: str | None = None
    factory_phone: str | None = None
    factory_fax: str | None = None
    stock_affairs_address: str | None = None
    stock_affairs_phone: str | None = None
    stock_affairs_fax: str | None = None
    central_office_address: str | None = None
    central_office_phone: str | None = None
    central_office_fax: str | None = None
    email: str | None = None
    website: str | None = None
    phone: str | None = None
    fax: str | None = None

    # -- Change detection -----------------------------------------------
    raw_hash: str | None = None

    created_at: datetime | None = None
    updated_at: datetime | None = None

    _db_include: set[str] | None = {
        "id", "publisher_id", "version",
        "factory_address", "factory_phone", "factory_fax",
        "stock_affairs_address", "stock_affairs_phone", "stock_affairs_fax",
        "central_office_address", "central_office_phone", "central_office_fax",
        "email", "website", "phone", "fax", "raw_hash",
        "created_at", "updated_at",
    }
    _search_include: set[str] | None = set()
    _warehouse_include: set[str] | None = None
    _timestamps = {"created_at", "updated_at"}


class CodalPublisherBoardMember(DomainModel):
    """Board member extracted from ``/fa/publisher/<id>/board``.

    Multiple rows per publisher per version.  Each re-parse that produces
    different content creates a new version.
    """

    id: str
    publisher_id: int
    version: int = 1
    name: str | None = None
    position: str | None = None
    is_employee: bool = False
    is_legal_representative: bool = False

    # -- Change detection -----------------------------------------------
    raw_hash: str | None = None

    created_at: datetime | None = None
    updated_at: datetime | None = None

    _db_include: set[str] | None = {
        "id", "publisher_id", "version", "name", "position",
        "is_employee", "is_legal_representative", "raw_hash",
        "created_at", "updated_at",
    }
    _search_include: set[str] | None = set()
    _warehouse_include: set[str] | None = None
    _timestamps = {"created_at", "updated_at"}


class CodalPublisherCapitalEvent(DomainModel):
    """Capital increase event from ``/fa/publisher/<id>/capital_increase``.

    Multiple rows per publisher per version.  Each re-parse that produces
    different content creates a new version.
    """

    id: str
    publisher_id: int
    version: int = 1
    event_date: str | None = None
    stage: str | None = None
    description: str | None = None
    amount: str | None = None
    percentage: str | None = None

    # -- Change detection -----------------------------------------------
    raw_hash: str | None = None

    created_at: datetime | None = None
    updated_at: datetime | None = None

    _db_include: set[str] | None = {
        "id", "publisher_id", "version", "event_date", "stage",
        "description", "amount", "percentage", "raw_hash",
        "created_at", "updated_at",
    }
    _search_include: set[str] | None = set()
    _warehouse_include: set[str] | None = None
    _timestamps = {"created_at", "updated_at"}


class CodalPublisherSimilar(DomainModel):
    """A similar publisher (same industry) from ``/fa/publisher/<id>/similar_publisher/``.

    Multiple rows per source publisher per version.  Each re-parse that
    produces different content creates a new version.
    """

    id: str
    publisher_id: int
    version: int = 1
    similar_publisher_id: int
    similar_name: str | None = None
    similar_url: str | None = None

    # -- Change detection -----------------------------------------------
    raw_hash: str | None = None

    created_at: datetime | None = None
    updated_at: datetime | None = None

    _db_include: set[str] | None = {
        "id", "publisher_id", "version", "similar_publisher_id",
        "similar_name", "similar_url", "raw_hash",
        "created_at", "updated_at",
    }
    _search_include: set[str] | None = set()
    _warehouse_include: set[str] | None = None
    _timestamps = {"created_at", "updated_at"}


class CodalPublisherMessage(DomainModel):
    """Supervisor message from ``/fa/publisher/<id>/message``.

    Each message has a title (h3) with date/time and a body (p).
    Multiple rows per publisher per version — last 20 messages per page.
    Each re-parse that produces different content creates a new version.
    """

    id: str
    publisher_id: int
    version: int = 1
    title: str | None = None
    message_date: str | None = None
    message_time: str | None = None
    description: str | None = None

    # -- Change detection -----------------------------------------------
    raw_hash: str | None = None

    created_at: datetime | None = None
    updated_at: datetime | None = None

    _db_include: set[str] | None = {
        "id", "publisher_id", "version", "title", "message_date",
        "message_time", "description", "raw_hash",
        "created_at", "updated_at",
    }
    _search_include: set[str] | None = set()
    _warehouse_include: set[str] | None = None
    _timestamps = {"created_at", "updated_at"}

