"""Dividend calendar Oracle service methods."""

from __future__ import annotations

import datetime as dt
from typing import Sequence

from libs.oracle_client.client import OracleClient
from libs.oracle_client.models import (
    DividendCalendarEntry,
    DividendHistoryResponse,
    DividendIngestResponse,
    DividendUpcomingResponse,
)


def _date_param(value: dt.date | str | None) -> str | None:
    if value is None:
        return None
    if isinstance(value, dt.date):
        return value.isoformat()
    return str(value)


class DividendService:
    def __init__(self, client: OracleClient) -> None:
        self._client = client

    async def get_upcoming(
        self,
        *,
        as_of_date: dt.date | str | None = None,
        from_ex_date: dt.date | str | None = None,
        to_ex_date: dt.date | str | None = None,
        symbols: Sequence[str] | None = None,
        limit: int = 500,
        force_refresh: bool = False,
    ) -> DividendUpcomingResponse:
        params: dict[str, object] = {
            "limit": int(limit),
            "force_refresh": bool(force_refresh),
        }
        as_of = _date_param(as_of_date)
        from_ex = _date_param(from_ex_date)
        to_ex = _date_param(to_ex_date)
        if as_of:
            params["as_of_date"] = as_of
        if from_ex:
            params["from_ex_date"] = from_ex
        if to_ex:
            params["to_ex_date"] = to_ex
        if symbols:
            params["symbols"] = [str(symbol).strip().upper() for symbol in symbols if str(symbol).strip()]
        data = await self._client.get("/api/v1/dividends/upcoming", params=params)
        entries = [DividendCalendarEntry.model_validate(item) for item in data.get("dividends", [])]
        return DividendUpcomingResponse(
            dividends=entries,
            total_count=int(data.get("total_count", len(entries))),
            metadata=dict(data.get("metadata") or {}),
        )

    async def get_history(
        self,
        symbol: str,
        *,
        limit: int = 1000,
        force_refresh: bool = False,
    ) -> DividendHistoryResponse:
        data = await self._client.get(
            f"/api/v1/dividends/history/{symbol}",
            params={"limit": int(limit), "force_refresh": bool(force_refresh)},
        )
        entries = [DividendCalendarEntry.model_validate(item) for item in data.get("dividends", [])]
        annual_yield_estimate = data.get("annual_yield_estimate")
        return DividendHistoryResponse(
            symbol=data.get("symbol", symbol),
            dividends=entries,
            total_count=int(data.get("total_count", len(entries))),
            annual_yield_estimate=float(annual_yield_estimate) if annual_yield_estimate is not None else None,
            metadata=dict(data.get("metadata") or {}),
        )

    async def ingest(
        self,
        symbols: Sequence[str],
        *,
        force_refresh: bool = False,
    ) -> DividendIngestResponse:
        payload = {
            "symbols": [str(symbol).strip().upper() for symbol in symbols if str(symbol).strip()],
            "force_refresh": bool(force_refresh),
        }
        data = await self._client.post("/api/v1/dividends/admin/ingest", json=payload)
        return DividendIngestResponse.model_validate(data)
