from datetime import datetime
from typing import Any

from pydantic import BaseModel, Field


class TokenOut(BaseModel):
    access_token: str
    token_type: str = "bearer"


class LoginIn(BaseModel):
    email: str
    password: str


class RegisterIn(BaseModel):
    email: str = Field(min_length=3, max_length=255)
    password: str = Field(min_length=6)
    name: str = Field(min_length=1, max_length=255)
    privacy_accepted: bool = False
    marketing_consent: bool = False
    referral_code: str | None = None
    utm_source: str | None = None
    utm_medium: str | None = None
    utm_campaign: str | None = None


class UserOut(BaseModel):
    id: int
    email: str
    name: str
    is_admin: bool
    apply_auto_submit: bool
    last_feed_visit: datetime | None = None
    plan_key: str | None = None
    plan_name: str | None = None
    referral_code: str | None = None
    marketing_consent: bool = False
    onboarding_done: bool = False

    model_config = {"from_attributes": True}


class ProfileIn(BaseModel):
    headline: str | None = None
    summary: str | None = None
    skills: list[str] | None = None
    experience_years: int | None = None
    seniority: str | None = None
    languages: list[dict[str, Any]] | None = None
    english_fluent: bool | None = None
    salary_min: int | None = None
    salary_currency: str | None = None
    remote_only: bool | None = None
    target_countries: list[str] | None = None
    keywords: list[str] | None = None
    desired_roles: list[str] | None = None
    job_categories: list[str] | None = None
    employment_types: list[str] | None = None
    timezone: str | None = None
    location: str | None = None
    phone: str | None = None
    linkedin_url: str | None = None
    portfolio_url: str | None = None
    work_authorization: str | None = None


class ProfileOut(ProfileIn):
    id: int
    user_id: int
    updated_at: datetime | None = None

    model_config = {"from_attributes": True}


class JobOut(BaseModel):
    id: int
    external_id: str
    source: str
    title: str
    company: str
    location: str
    remote: bool
    salary_min: int | None = None
    salary_max: int | None = None
    salary_currency: str | None = None
    url: str
    url_openable: bool = True
    url_is_search: bool = False
    description: str
    lang: str
    tags: list[str] = []
    requires_english_fluent: bool = False
    hire_from_spain_ok: bool | None = None
    posted_at: datetime | None = None
    scraped_at: datetime | None = None
    match_score: float | None = None
    match_reasons: list[str] = []
    application_status: str | None = None
    contact_email: str | None = None
    contact_phone: str | None = None
    contact_name: str | None = None
    contact_linkedin: str | None = None
    contacts_json: dict[str, Any] | None = None
    signals: dict[str, Any] | None = None

    model_config = {"from_attributes": True}


class JobListOut(BaseModel):
    total: int
    items: list[JobOut]


class JobSourceOut(BaseModel):
    id: int
    key: str
    name: str
    enabled: bool
    config: dict[str, Any] = {}
    region: str = "intl"
    category: str = "general"
    tier_min: int = 0
    priority: int = 100
    connector_type: str = "html"
    last_run_at: datetime | None = None
    last_status: str
    last_error: str | None = None
    allowed: bool | None = True
    locked_reason: str | None = None

    model_config = {"from_attributes": True}


class JobSourceUpdate(BaseModel):
    enabled: bool | None = None
    config: dict[str, Any] | None = None


class ApplicationIn(BaseModel):
    job_id: int
    status: str = "saved"
    notes: str = ""


class ApplicationUpdate(BaseModel):
    status: str | None = None
    notes: str | None = None
    cv_version_id: int | None = None


class ApplicationOut(BaseModel):
    id: int
    job_id: int
    status: str
    notes: str
    adapter: str | None = None
    apply_log: list[Any] = []
    cv_version_id: int | None = None
    applied_at: datetime | None = None
    created_at: datetime | None = None
    job: JobOut | None = None
    silence: dict[str, Any] | None = None

    model_config = {"from_attributes": True}
