from dataclasses import dataclass, field
from datetime import datetime
from typing import Optional

from bs4 import BeautifulSoup
from requests.structures import CaseInsensitiveDict


@dataclass
class Entity:
    id: str
    name: str | None
    type: str
    alternate_name: str | None
    url: str | None
    description: str | None
    raw: dict
    date_published: datetime | None = None
    date_modified: datetime | None = None

@dataclass
class ResponseMeta:
    content_length: Optional[int]
    content_encoding: Optional[str]
    cache_control: Optional[str]
    last_modified: Optional[str]
    etag: Optional[str]
    server: Optional[str]


@dataclass
class UrlContext:
    url: str
    text: str | None = None
    status_code: int | None = None
    content_type: str | None = None
    position: str | None = None

@dataclass
class DomainContext:
    url: str
    ssl: bool = field(init=False, default=False)
    brand_name: str = field(init=False, default=None)
    brand_description: str = field(init=False, default=None)
    connections: list[str] = field(init=False, default=None)
    entities: list[Entity] = field(init=False, default=None)

@dataclass
class PageHeading:
    tag: str | None = None
    content: str | None = None

@dataclass
class PageMetaContext:
    name: str | None = None
    meta_type: str | None = None
    value: str | None = None

@dataclass
class PageContext:
    url: str
    soup: BeautifulSoup | None = None
    canonical_url: str | None = None
    nodes: list[dict] | None = None # all JSON-LD blocks parsed
    index_nodes: dict[str, dict] | None = None
    headers: CaseInsensitiveDict | None = None
    breadcrumbs: list | None = None
    # links: list[dict] | None = None
    meta_title: str | None = None
    is_title: bool = False
    meta_description: str | None = None
    is_description: bool = False
    is_index: bool = False
    is_follow: bool = False
    is_file: bool = False
    is_navigation: bool = False
    is_no_h1: bool = False
    is_domain: bool = False
    extera_h1: bool = False
    images_count: int = 0
    videos_count: int = 0
    audio_count: int = 0
    status_code: int = 0
    links: list[UrlContext] | None = None
    entities: list[Entity] = field(init=False, default=None)
    page_metas: list[PageMetaContext] = field(init=False, default=None)
    author: Entity | None = field(init=False, default=None)
    parent: dict | None = field(init=False, default=None)
    response_meta: ResponseMeta | None = field(init=False, default=None)
    headings : list[PageHeading] | None = field(init=False, default=None)
