"""Deribit Futures Historical Model."""
from datetime import datetime
from typing import Any, Optional, List, Dict

from capinvest_capdata.utils.data_path import history_url
from capinvest_capdata.utils.helpers import CAPDATA_INTERVALS, CapdataIntervals, post_by_token
from capinvest_core.provider.abstract.fetcher import Fetcher
from capinvest_core.provider.standard_models.equity_historical import EquityHistoricalQueryParams, EquityHistoricalData
from capinvest_core.provider.utils.descriptions import QUERY_DESCRIPTIONS
from capinvest_core.provider.utils.errors import EmptyDataError
from dateutil.relativedelta import relativedelta
from pydantic import Field

from capinvest_capdata.utils.helpers import get_capdata_token


# pylint: disable=unused-argument


class CapdataEtfHistoricalQueryParams(EquityHistoricalQueryParams):
    """
    Capdata etf historical Price Query.

    Source: https://www.caprisktech.com/#/documents/http-documentation
    """

    __alias_dict__ = {"start_date": "from", "end_date": "to"}
    __json_schema_extra__ = {
        "symbol": {"multiple_items_allowed": True},
        "interval": {"multiple_items_allowed": False,
                     "choices": CAPDATA_INTERVALS},
    }

    interval: CapdataIntervals = Field(
        default="d", description=QUERY_DESCRIPTIONS.get("interval", "")
    )


class CapdataEtfHistoricalData(EquityHistoricalData):
    """Capdata etf Historical Data."""


class CapdataEtfHistoricalFetcher(
    Fetcher[CapdataEtfHistoricalQueryParams, list[CapdataEtfHistoricalData]]
):
    """Deribit etf Historical Fetcher."""

    @staticmethod
    def transform_query(params: dict[str, Any]) -> CapdataEtfHistoricalQueryParams:
        """Transform the query."""
        transformed_params = params
        now = datetime.now().date()
        if params.get("start_date") is None:
            if params.get("interval") == "d" or params.get("interval") == "w":
                transformed_params["start_date"] = now - relativedelta(years=1)
            else:
                transformed_params["start_date"] = now - relativedelta(day=10)
        if params.get("end_date") is None:
            transformed_params["end_date"] = now
        return CapdataEtfHistoricalQueryParams(**transformed_params)

    @staticmethod
    async def aextract_data(
            query: CapdataEtfHistoricalQueryParams,
            credentials: Optional[dict[str, str]],
            **kwargs: Any,
    ) -> list:
        """Extract the raw data."""
        """Return the raw data from the CapData endpoint."""
        symbols = query.symbol.split(",")
        params = {
            "inst": symbols,
            "start": query.start_date.strftime("%Y-%m-%d %H:%M:%S"),
            "end": query.end_date.strftime("%Y-%m-%d %H:%M:%S"),
            "freq": query.interval,
            "fields": ["volume", "open", "close", "low", "high"]
        }
        results = post_by_token(history_url, params, credentials)
        if not results:
            raise EmptyDataError(
                f"{query.symbol} No data found"
            )
        return results

    @staticmethod
    def transform_data(
            query: CapdataEtfHistoricalQueryParams, data: List[Dict], **kwargs: Any
    ) -> list[CapdataEtfHistoricalData]:
        """Transform the data."""
        results: List[CapdataEtfHistoricalData] = []
        for d in sorted(
                data,
                key=lambda x: (
                        (x["date"], x["inst"])
                        if len(query.symbol.split(",")) > 1
                        else x["date"]
                ),
                reverse=False,
        ):
            results.append(CapdataEtfHistoricalData.model_validate(d))
        return results
