from __future__ import annotations

import enum
import typing as t
from dataclasses import dataclass, field

import pandas as pd
from pydantic import BaseModel, ConfigDict, SkipValidation

# ** Pipeline state management
StatusDescription: t.TypeAlias = tuple[str, int, str]


class IError(t.Protocol):
    code: int
    description: str
    message: str


class Status(BaseModel):
    code: SkipValidation[int]
    description: SkipValidation[str]
    message: SkipValidation[str] = ""
    api_server_error: SkipValidation[DelBarApiError | None] = None


@dataclass(slots=True)
class DataPipeStates:
    SUCCESS: Status
    TOO_FEW_POINTS: Status
    BAD_QUALITY: Status


@dataclass(slots=True)
class PipeResult:
    status: Status
    data: pd.DataFrame | None


# ** API
class ApiCredentials(BaseModel):
    model_config: ConfigDict = ConfigDict(str_strip_whitespace=True)

    user_name: str
    password: str
    database: str
    mandant: str


class DelBarApiError(BaseModel):
    status_code: int
    message: str = ""
    code: str | None = None
    hints: str | None = None
    type: str | None = None
    title: str | None = None
    errors: dict | None = None
    traceId: str | None = None


class HttpRequestTypes(enum.StrEnum):
    GET = enum.auto()
    POST = enum.auto()
    PUT = enum.auto()
    DELETE = enum.auto()


HttpContentHeaders = t.TypedDict(
    "HttpContentHeaders",
    {
        "Content-type": str,
        "Accept": str,
        "DelecoToken": t.NotRequired[str],
    },
)


# ** forecasts
@dataclass(slots=True)
class CustomerDataSalesForecast:
    order: list[int] = field(default_factory=list)
    date: list[pd.Timestamp] = field(default_factory=list)
    sales: list[float] = field(default_factory=list)
