"""Pydantic models for leads endpoints."""

from __future__ import annotations

from datetime import datetime
from typing import Any
from uuid import UUID

from pydantic import BaseModel, field_validator


VALID_LEAD_STATUSES = (
    "new",
    "researching",
    "qualified",
    "outreach_ready",
    "contacted",
    "responded",
    "converted",
    "disqualified",
)

BULK_LEADS_MAX = 500


def _validate_email_format(v: str) -> str:
    """Reject obviously invalid email addresses (no external dep required)."""
    if not v or "@" not in v or v.startswith("@") or v.endswith("@"):
        raise ValueError("Invalid email address")
    return v


class LeadResponse(BaseModel):
    id: UUID
    project_id: str
    name: str
    email: str
    contact_phone: str | None
    company: str | None
    source: str | None
    status: str
    notes: str | None
    metadata: dict[str, Any] | None
    created_at: datetime
    updated_at: datetime


class CreateLeadRequest(BaseModel):
    name: str
    email: str
    contact_phone: str | None = None
    company: str | None = None
    source: str | None = None
    status: str = "new"
    notes: str | None = None
    metadata: dict[str, Any] | None = None

    @field_validator("email")
    @classmethod
    def validate_email(cls, v: str) -> str:
        return _validate_email_format(v)


class LeadStatsResponse(BaseModel):
    total: int
    by_status: dict[str, int]


class UpdateLeadRequest(BaseModel):
    name: str | None = None
    email: str | None = None
    contact_phone: str | None = None
    company: str | None = None
    source: str | None = None
    status: str | None = None
    notes: str | None = None
    metadata: dict[str, Any] | None = None

    @field_validator("name", "email", mode="before")
    @classmethod
    def not_null(cls, v: Any) -> Any:
        """Prevent clients from explicitly nulling NOT NULL columns."""
        if v is None:
            raise ValueError("cannot be set to null")
        return v

    @field_validator("email")
    @classmethod
    def validate_email(cls, v: str) -> str:
        return _validate_email_format(v)


class BulkCreateLeadsRequest(BaseModel):
    leads: list[CreateLeadRequest]

    @field_validator("leads")
    @classmethod
    def validate_batch_size(cls, v: list) -> list:
        if len(v) == 0:
            raise ValueError("leads array must not be empty")
        if len(v) > BULK_LEADS_MAX:
            raise ValueError(f"batch size exceeds limit of {BULK_LEADS_MAX}")
        return v


class BulkLeadItem(BaseModel):
    index: int
    status: str  # "created", "skipped", or "error"
    email: str | None
    reason: str | None = None  # populated for "skipped" and "error"
    lead: LeadResponse | None = None  # populated for "created"


class BulkLeadError(BaseModel):
    index: int
    email: str | None
    error: str


class BulkCreateLeadsResponse(BaseModel):
    created: int
    skipped: int
    errors: int
    items: list[BulkLeadItem]


class PublicLeadCaptureRequest(BaseModel):
    name: str
    email: str
    gym: str | None = None  # name of their gym/box
    contact_phone: str | None = None
    notes: str | None = None
    # Honeypot field — must be empty; bots fill it, humans don't
    website: str | None = None

    @field_validator("email")
    @classmethod
    def validate_email(cls, v: str) -> str:
        return _validate_email_format(v)


class PublicLeadCaptureResponse(BaseModel):
    ok: bool
    message: str
