"""Pydantic schemas for PSA connection management."""
from __future__ import annotations
from datetime import datetime
from uuid import UUID
from pydantic import BaseModel, Field


class PsaConnectionCreate(BaseModel):
    provider: str = Field(default="connectwise", pattern="^(connectwise|autotask)$")
    display_name: str = Field(min_length=1, max_length=100)
    site_url: str = Field(min_length=1, max_length=255)
    company_id: str = Field(min_length=1, max_length=100)
    public_key: str = Field(min_length=1)
    private_key: str = Field(min_length=1)
    # Note: client_id is NOT per-MSP — it's a product-level GUID from settings.CW_CLIENT_ID


class PsaConnectionUpdate(BaseModel):
    display_name: str | None = None
    site_url: str | None = None
    company_id: str | None = None
    public_key: str | None = None
    private_key: str | None = None


class PsaConnectionResponse(BaseModel):
    id: UUID
    account_id: UUID
    provider: str
    display_name: str
    site_url: str
    company_id: str
    is_active: bool
    last_validated_at: datetime | None
    created_at: datetime
    updated_at: datetime
    public_key_hint: str
    private_key_hint: str

    model_config = {"from_attributes": True}


class PsaConnectionTestResponse(BaseModel):
    success: bool
    message: str
    server_version: str | None = None


# ── Ticket search & status schemas ────────────────────────────────


class PSATicketSearchResult(BaseModel):
    id: str
    summary: str
    company_name: str | None = None
    company_id: str | None = None
    board_name: str | None = None
    board_id: int | None = None
    status_name: str | None = None
    status_id: int | None = None
    priority_name: str | None = None
    priority_id: int | None = None
    closed: bool = False


class PSATicketStatusItem(BaseModel):
    id: int
    name: str
    is_closed: bool = False


# ── PSA post (note posting) schemas ──────────────────────────────


class PsaPostRequest(BaseModel):
    note_type: str = Field(pattern="^(internal_analysis|resolution|description)$")
    content: str = Field(min_length=1)
    update_status_id: int | None = None


class PsaPostResponse(BaseModel):
    id: str
    session_id: str
    ticket_id: str
    note_type: str
    status: str
    external_note_id: str | None = None
    error_message: str | None = None
    status_changed_from: str | None = None
    status_changed_to: str | None = None
    posted_at: str


class PsaPreviewResponse(BaseModel):
    content: str
    ticket: PSATicketSearchResult
    available_statuses: list[PSATicketStatusItem]
    character_count: int
    previous_posts: int


class PsaPostLogResponse(BaseModel):
    id: str
    ticket_id: str
    note_type: str
    status: str
    error_message: str | None = None
    status_changed_from: str | None = None
    status_changed_to: str | None = None
    posted_at: str
    content_preview: str  # first 200 chars


# ── Member mapping schemas ───────────────────────────────────────


class PsaMemberMappingResponse(BaseModel):
    id: str | None = None  # None for users without a mapping
    user_id: str
    user_email: str
    user_name: str
    external_member_id: str | None = None
    external_member_name: str | None = None
    matched_by: str | None = None


class PsaMemberMappingSaveRequest(BaseModel):
    user_id: str
    external_member_id: str
    external_member_name: str


class PsaMemberResponse(BaseModel):
    id: str
    identifier: str
    name: str
    email: str | None = None


class AutoMatchResult(BaseModel):
    matched: list[PsaMemberMappingResponse]
    unmatched_users: int


class PSABoardResponse(BaseModel):
    id: int
    name: str
