"""Pydantic schemas for scanner and client-side cookie reports."""

from __future__ import annotations

import uuid
from datetime import datetime
from enum import StrEnum

from pydantic import BaseModel, Field


class ScanStatus(StrEnum):
    PENDING = "pending"
    RUNNING = "running"
    COMPLETED = "completed"
    FAILED = "failed"


class ScanTrigger(StrEnum):
    MANUAL = "manual"
    SCHEDULED = "scheduled"
    CLIENT_REPORT = "client_report"


# ── Client-side cookie report ────────────────────────────────────────


class ReportedCookie(BaseModel):
    """A single cookie/storage item reported by the client-side reporter."""

    name: str = Field(..., min_length=1, max_length=255)
    domain: str = Field(..., min_length=1, max_length=255)
    storage_type: str = Field(default="cookie", max_length=30)
    value_length: int = Field(default=0, ge=0)
    path: str | None = None
    is_secure: bool | None = None
    same_site: str | None = None
    script_source: str | None = None


class CookieReportRequest(BaseModel):
    """Payload from the client-side cookie reporter."""

    site_id: uuid.UUID
    page_url: str = Field(..., max_length=2000)
    cookies: list[ReportedCookie] = Field(..., max_length=500)
    collected_at: datetime
    user_agent: str = Field(default="", max_length=500)


class CookieReportResponse(BaseModel):
    """Acknowledgement response for a cookie report."""

    accepted: bool = True
    cookies_received: int
    new_cookies: int = 0


# ── Scan job schemas ─────────────────────────────────────────────────


class ScanResultResponse(BaseModel):
    """A single scan result — a cookie found on a specific page."""

    id: uuid.UUID
    scan_job_id: uuid.UUID
    page_url: str
    cookie_name: str
    cookie_domain: str
    storage_type: str
    attributes: dict | None = None
    script_source: str | None = None
    auto_category: str | None = None
    initiator_chain: list[str] | None = None
    found_at: datetime
    created_at: datetime

    model_config = {"from_attributes": True}


class ScanJobResponse(BaseModel):
    """Response schema for a scan job."""

    id: uuid.UUID
    site_id: uuid.UUID
    status: str
    trigger: str
    pages_scanned: int
    pages_total: int | None
    cookies_found: int
    error_message: str | None
    started_at: datetime | None
    completed_at: datetime | None
    created_at: datetime
    updated_at: datetime

    model_config = {"from_attributes": True}


class ScanJobDetailResponse(ScanJobResponse):
    """Scan job with results included."""

    results: list[ScanResultResponse] = []


class TriggerScanRequest(BaseModel):
    """Request to trigger a new scan."""

    site_id: uuid.UUID
    max_pages: int = Field(default=50, ge=1, le=500)


# ── Diff engine schemas ──────────────────────────────────────────────


class DiffStatus(StrEnum):
    NEW = "new"
    REMOVED = "removed"
    CHANGED = "changed"


class CookieDiffItem(BaseModel):
    """A single cookie difference between two scans."""

    name: str
    domain: str
    storage_type: str
    diff_status: DiffStatus
    details: str | None = None


class ScanDiffResponse(BaseModel):
    """Diff between two scans."""

    current_scan_id: uuid.UUID
    previous_scan_id: uuid.UUID | None
    new_cookies: list[CookieDiffItem] = []
    removed_cookies: list[CookieDiffItem] = []
    changed_cookies: list[CookieDiffItem] = []
    total_new: int = 0
    total_removed: int = 0
    total_changed: int = 0
