from __future__ import annotations

from datetime import datetime as Datetime
from typing import TYPE_CHECKING, Final

import requests
from pydantic import BaseModel, PositiveInt, SkipValidation

from delta_barth.api.common import combine_route
from delta_barth.errors import STATUS_HANDLER
from delta_barth.types import DelBarApiError, Status

if TYPE_CHECKING:
    from delta_barth.api.common import Session


# ** sales data
class SalesPrognosisRequestP(BaseModel):
    FirmaId: SkipValidation[int | None]
    BuchungsDatum: SkipValidation[Datetime | None]


class SalesPrognosisResponseEntry(BaseModel):
    artikelId: PositiveInt
    firmaId: PositiveInt
    betrag: float  # negative values are filtered out later
    menge: float  # reasons for negative values unknown
    buchungsDatum: Datetime


class SalesPrognosisResponse(BaseModel):
    daten: tuple[SalesPrognosisResponseEntry, ...]


def get_sales_prognosis_data(
    session: Session,
    company_id: int | None = None,
    start_date: Datetime | None = None,
) -> tuple[SalesPrognosisResponse, Status]:
    session.assert_login()
    ROUTE: Final[str] = "verkauf/umsatzprognosedaten"
    URL: Final = combine_route(session.base_url, ROUTE)

    sales_prog_req = SalesPrognosisRequestP(
        FirmaId=company_id,
        BuchungsDatum=start_date,
    )
    resp = requests.get(
        URL,
        params=sales_prog_req.model_dump(mode="json", exclude_none=True),
        headers=session.headers,  # type: ignore[argumentType]
    )

    response: SalesPrognosisResponse
    status: Status
    if resp.status_code == 200:
        response = SalesPrognosisResponse(**resp.json())
        status = STATUS_HANDLER.SUCCESS
    else:
        response = SalesPrognosisResponse(daten=tuple())
        err = DelBarApiError(status_code=resp.status_code, **resp.json())
        status = STATUS_HANDLER.api_error(err)

    return response, status
