from __future__ import annotations

from pathlib import Path
from typing import Any, Protocol, runtime_checkable
from pydantic import BaseModel, Field


class SxdAttachmentInfo(BaseModel):
    """Metadata for an official document attachment (PDF, Excel, Docx, etc.)."""

    filename: str
    download_url: str
    file_type: str = "unknown"  # "pdf", "xlsx", "xls", "doc", etc.
    size_bytes: int = 0


class SxdAnnouncement(BaseModel):
    """Metadata for a published construction material price announcement from Department of Construction."""

    title: str
    announcement_number: str = ""  # e.g. "622/TB-SXD", "558/TB-SXD"
    publish_date: str = ""  # e.g. "09/09/2026", "07/08/2026"
    period: str = ""  # e.g. "2026-08", "2026-07"
    source_url: str
    province: str = "HAI_PHONG"
    attachments: list[SxdAttachmentInfo] = Field(default_factory=list)


@runtime_checkable
class ISxdCrawlerPort(Protocol):
    """Domain Port Interface for crawling official Department of Construction (SXD) price announcements."""

    async def crawl_latest_announcements(
        self,
        base_url: str = "https://soxaydung.haiphong.gov.vn/thong-bao-chi-so-gia",
        max_items: int = 5,
    ) -> list[SxdAnnouncement]:
        """Crawl the latest price and index announcements from the SXD portal."""
        ...

    async def download_announcement_files(
        self,
        announcement: SxdAnnouncement,
        destination_dir: Path,
    ) -> dict[str, Path]:
        """Download all attachments for an announcement and save them to destination_dir.

        Returns a dictionary mapping file type or identifier to the saved local Path.
        """
        ...
