from pydantic import BaseModel, Field, field_validator
from typing import Optional, List
from uuid import UUID
from datetime import datetime

VALID_TYPES      = {"note", "issue"}
VALID_STATUSES   = {"open", "researching", "resolved"}
VALID_SEVERITIES = {"low", "medium", "high", "critical"}
VALID_CATEGORIES = {"technical", "install_support", "general"}
VALID_ENTITIES   = {"device", "app_user", "customer"}


class EntryLinkIn(BaseModel):
    entity_type: str
    entity_id: str

    @field_validator("entity_type")
    @classmethod
    def check_entity_type(cls, v):
        if v not in VALID_ENTITIES:
            raise ValueError(f"entity_type must be one of {VALID_ENTITIES}")
        return v


class EntryCreate(BaseModel):
    type: str
    title: str = Field(..., max_length=500)
    body: Optional[str] = None
    status: Optional[str] = None
    severity: Optional[str] = None
    category: Optional[str] = None
    links: List[EntryLinkIn] = []

    @field_validator("type")
    @classmethod
    def check_type(cls, v):
        if v not in VALID_TYPES:
            raise ValueError(f"type must be one of {VALID_TYPES}")
        return v

    @field_validator("status")
    @classmethod
    def check_status(cls, v):
        if v is not None and v not in VALID_STATUSES:
            raise ValueError(f"status must be one of {VALID_STATUSES}")
        return v

    @field_validator("severity")
    @classmethod
    def check_severity(cls, v):
        if v is not None and v not in VALID_SEVERITIES:
            raise ValueError(f"severity must be one of {VALID_SEVERITIES}")
        return v

    @field_validator("category")
    @classmethod
    def check_category(cls, v):
        if v is not None and v not in VALID_CATEGORIES:
            raise ValueError(f"category must be one of {VALID_CATEGORIES}")
        return v


class EntryUpdate(BaseModel):
    title: Optional[str] = Field(None, max_length=500)
    body: Optional[str] = None
    status: Optional[str] = None
    severity: Optional[str] = None
    category: Optional[str] = None


class EntryLinkOut(BaseModel):
    id: UUID
    entity_type: str
    entity_id: str
    model_config = {"from_attributes": True}


class EntryOut(BaseModel):
    id: UUID
    type: str
    title: str
    body: Optional[str]
    status: Optional[str]
    severity: Optional[str]
    category: Optional[str]
    author_id: str
    author_name: Optional[str]
    created_at: datetime
    updated_at: datetime
    links: List[EntryLinkOut] = []
    model_config = {"from_attributes": True}


class EntryListResponse(BaseModel):
    data: List[EntryOut]
    pagination: dict


class LinksReplaceIn(BaseModel):
    links: List[EntryLinkIn]
