"""
Schemas API FastAPI pour Phase 3.
"""

from datetime import datetime
from typing import Optional

from pydantic import BaseModel, Field


class HealthStatus(BaseModel):
    db: bool
    redis: bool


class ProductOut(BaseModel):
    id: int
    source: str
    reference: str
    url: str
    title: Optional[str] = None
    category: Optional[str] = None
    description: Optional[str] = None
    currency: Optional[str] = None
    msrp: Optional[float] = None
    first_seen_at: datetime
    last_updated_at: datetime
    latest_price: Optional[float] = None
    latest_shipping_cost: Optional[float] = None
    latest_stock_status: Optional[str] = None
    latest_fetched_at: Optional[datetime] = None
    images: list[str] = []
    specs: dict[str, str] = {}
    discount_amount: Optional[float] = None
    discount_percent: Optional[float] = None


class ProductCreate(BaseModel):
    source: str
    reference: str
    url: str
    title: Optional[str] = None
    category: Optional[str] = None
    description: Optional[str] = None
    currency: Optional[str] = None
    msrp: Optional[float] = None


class ProductUpdate(BaseModel):
    url: Optional[str] = None
    title: Optional[str] = None
    category: Optional[str] = None
    description: Optional[str] = None
    currency: Optional[str] = None
    msrp: Optional[float] = None


class PriceHistoryOut(BaseModel):
    id: int
    product_id: int
    price: Optional[float] = None
    shipping_cost: Optional[float] = None
    stock_status: Optional[str] = None
    fetch_method: str
    fetch_status: str
    fetched_at: datetime


class PriceHistoryCreate(BaseModel):
    product_id: int
    price: Optional[float] = None
    shipping_cost: Optional[float] = None
    stock_status: Optional[str] = None
    fetch_method: str
    fetch_status: str
    fetched_at: datetime


class PriceHistoryUpdate(BaseModel):
    price: Optional[float] = None
    shipping_cost: Optional[float] = None
    stock_status: Optional[str] = None
    fetch_method: Optional[str] = None
    fetch_status: Optional[str] = None
    fetched_at: Optional[datetime] = None


class ScrapingLogOut(BaseModel):
    id: int
    product_id: Optional[int] = None
    url: str
    source: str
    reference: Optional[str] = None
    fetch_method: str
    fetch_status: str
    fetched_at: datetime
    duration_ms: Optional[int] = None
    html_size_bytes: Optional[int] = None
    errors: Optional[list[str]] = None
    notes: Optional[list[str]] = None


class WebhookOut(BaseModel):
    id: int
    event: str
    url: str
    enabled: bool
    secret: Optional[str] = None
    created_at: datetime


class WebhookCreate(BaseModel):
    event: str
    url: str
    enabled: bool = True
    secret: Optional[str] = None


class WebhookUpdate(BaseModel):
    event: Optional[str] = None
    url: Optional[str] = None
    enabled: Optional[bool] = None
    secret: Optional[str] = None


class WebhookTestResponse(BaseModel):
    status: str


class ScrapingLogCreate(BaseModel):
    product_id: Optional[int] = None
    url: str
    source: str
    reference: Optional[str] = None
    fetch_method: str
    fetch_status: str
    fetched_at: datetime
    duration_ms: Optional[int] = None
    html_size_bytes: Optional[int] = None
    errors: Optional[list[str]] = None
    notes: Optional[list[str]] = None


class ScrapingLogUpdate(BaseModel):
    product_id: Optional[int] = None
    url: Optional[str] = None
    source: Optional[str] = None
    reference: Optional[str] = None
    fetch_method: Optional[str] = None
    fetch_status: Optional[str] = None
    fetched_at: Optional[datetime] = None
    duration_ms: Optional[int] = None
    html_size_bytes: Optional[int] = None
    errors: Optional[list[str]] = None
    notes: Optional[list[str]] = None


class EnqueueRequest(BaseModel):
    url: str = Field(..., description="URL du produit")
    use_playwright: Optional[bool] = None
    save_db: bool = True


class EnqueueResponse(BaseModel):
    job_id: str


class ScheduleRequest(BaseModel):
    url: str = Field(..., description="URL du produit")
    interval_hours: int = Field(default=24, ge=1)
    use_playwright: Optional[bool] = None
    save_db: bool = True


class ScheduleResponse(BaseModel):
    job_id: str
    next_run: datetime


class ScrapePreviewRequest(BaseModel):
    url: str
    use_playwright: Optional[bool] = None


class ScrapePreviewResponse(BaseModel):
    success: bool
    snapshot: Optional[dict[str, object]] = None
    error: Optional[str] = None


class ScrapeCommitRequest(BaseModel):
    snapshot: dict[str, object]


class ScrapeCommitResponse(BaseModel):
    success: bool
    product_id: Optional[int] = None
    error: Optional[str] = None


class VersionResponse(BaseModel):
    api_version: str


class BackendLogEntry(BaseModel):
    time: datetime
    level: str
    message: str


class UvicornLogEntry(BaseModel):
    line: str
