from __future__ import annotations

from typing import Any

import pandas as pd
import structlog

from agrobr.datasets.base import BaseDataset, DatasetInfo, DatasetSource, _unpack_result
from agrobr.datasets.deterministic import get_snapshot
from agrobr.models import MetaInfo

logger = structlog.get_logger()


async def _fetch_antaq(
    produto: str,  # noqa: ARG001
    **kwargs: Any,
) -> tuple[pd.DataFrame, MetaInfo | None]:
    from agrobr import antaq

    result = await antaq.movimentacao(
        ano=kwargs["ano"],
        tipo_navegacao=kwargs.get("tipo_navegacao"),
        natureza_carga=kwargs.get("natureza_carga"),
        mercadoria=kwargs.get("mercadoria"),
        porto=kwargs.get("porto"),
        uf=kwargs.get("uf"),
        sentido=kwargs.get("sentido"),
        return_meta=True,
    )
    return _unpack_result(result)


MOVIMENTACAO_PORTUARIA_INFO = DatasetInfo(
    name="movimentacao_portuaria",
    description="Movimentação portuária de cargas — ANTAQ",
    sources=[
        DatasetSource(
            name="antaq",
            priority=1,
            fetch_fn=_fetch_antaq,
            description="ANTAQ — Agência Nacional de Transportes Aquaviários",
        ),
    ],
    products=[],
    contract_version="1.0",
    update_frequency="yearly",
    typical_latency="ano+6 meses",
    source_url="https://web3.antaq.gov.br/ea/sense/",
    source_institution="ANTAQ",
    unit="ton",
    license="livre",
)


class MovimentacaoPortuariaDataset(BaseDataset):
    info = MOVIMENTACAO_PORTUARIA_INFO

    def _validate_produto(self, produto: str) -> None:
        pass

    async def fetch(  # type: ignore[override]
        self,
        *,
        ano: int,
        mercadoria: str | None = None,
        porto: str | None = None,
        uf: str | None = None,
        sentido: str | None = None,
        tipo_navegacao: str | None = None,
        natureza_carga: str | None = None,
        return_meta: bool = False,
        **kwargs: Any,
    ) -> pd.DataFrame | tuple[pd.DataFrame, MetaInfo]:
        snapshot = get_snapshot()

        logger.info(
            "dataset_fetch",
            dataset="movimentacao_portuaria",
            ano=ano,
        )

        df, source_name, source_meta, attempted = await self._try_sources(
            "",
            ano=ano,
            mercadoria=mercadoria,
            porto=porto,
            uf=uf,
            sentido=sentido,
            tipo_navegacao=tipo_navegacao,
            natureza_carga=natureza_carga,
            **kwargs,
        )

        df = self._normalize(df)
        self._validate_contract(df)

        if return_meta:
            return df, self._build_meta(df, source_name, source_meta, attempted, snapshot)
        return df

    def _normalize(self, df: pd.DataFrame) -> pd.DataFrame:
        return df


_movimentacao_portuaria = MovimentacaoPortuariaDataset()

from agrobr.datasets.registry import register  # noqa: E402

register(_movimentacao_portuaria)


async def movimentacao_portuaria(
    *,
    ano: int,
    mercadoria: str | None = None,
    porto: str | None = None,
    uf: str | None = None,
    sentido: str | None = None,
    tipo_navegacao: str | None = None,
    natureza_carga: str | None = None,
    return_meta: bool = False,
    **kwargs: Any,
) -> pd.DataFrame | tuple[pd.DataFrame, MetaInfo]:
    return await _movimentacao_portuaria.fetch(
        ano=ano,
        mercadoria=mercadoria,
        porto=porto,
        uf=uf,
        sentido=sentido,
        tipo_navegacao=tipo_navegacao,
        natureza_carga=natureza_carga,
        return_meta=return_meta,
        **kwargs,
    )
