"""
Linux BenchTools - Peripheral Schemas
"""

from pydantic import BaseModel, Field
from typing import Optional, List, Dict, Any
from datetime import date, datetime


# ========================================
# BASE SCHEMAS
# ========================================

class PeripheralBase(BaseModel):
    """Base schema for peripherals"""
    nom: str = Field(..., min_length=1, max_length=255)
    type_principal: str = Field(..., min_length=1, max_length=100)
    sous_type: Optional[str] = Field(None, max_length=100)
    marque: Optional[str] = Field(None, max_length=100)
    modele: Optional[str] = Field(None, max_length=255)
    fabricant: Optional[str] = Field(None, max_length=255)
    produit: Optional[str] = Field(None, max_length=255)
    numero_serie: Optional[str] = Field(None, max_length=255)
    ean_upc: Optional[str] = Field(None, max_length=50)

    # Achat
    boutique: Optional[str] = Field(None, max_length=255)
    date_achat: Optional[date] = None
    prix: Optional[float] = Field(None, ge=0)
    devise: Optional[str] = Field("EUR", max_length=10)
    garantie_duree_mois: Optional[int] = Field(None, ge=0)
    garantie_expiration: Optional[date] = None

    # Évaluation
    rating: Optional[float] = Field(0.0, ge=0, le=5)

    # Stock
    quantite_totale: Optional[int] = Field(1, ge=0)
    quantite_disponible: Optional[int] = Field(1, ge=0)
    seuil_alerte: Optional[int] = Field(0, ge=0)

    # Métadonnées
    etat: Optional[str] = Field("Neuf", max_length=50)
    localisation: Optional[str] = Field(None, max_length=255)
    proprietaire: Optional[str] = Field(None, max_length=100)
    tags: Optional[str] = None  # JSON string
    # Documentation
    description: Optional[str] = None  # Description courte
    synthese: Optional[str] = None  # Synthèse complète markdown
    cli: Optional[str] = None  # DEPRECATED: Sortie CLI (lsusb -v) filtrée
    cli_yaml: Optional[str] = None  # Données structurées CLI au format YAML
    cli_raw: Optional[str] = None  # Sortie CLI brute (Markdown)
    specifications: Optional[str] = None  # Spécifications techniques (Markdown)
    notes: Optional[str] = None  # Notes libres (Markdown)

    # Linux
    device_path: Optional[str] = Field(None, max_length=255)
    sysfs_path: Optional[str] = Field(None, max_length=500)
    vendor_id: Optional[str] = Field(None, max_length=20)
    product_id: Optional[str] = Field(None, max_length=20)
    usb_device_id: Optional[str] = Field(None, max_length=20)
    iManufacturer: Optional[str] = None  # USB manufacturer string
    iProduct: Optional[str] = None  # USB product string
    class_id: Optional[str] = Field(None, max_length=20)
    driver_utilise: Optional[str] = Field(None, max_length=100)
    modules_kernel: Optional[str] = None  # JSON string
    udev_rules: Optional[str] = None
    identifiant_systeme: Optional[str] = None

    # Installation
    installation_auto: Optional[bool] = False
    driver_requis: Optional[str] = None
    firmware_requis: Optional[str] = None
    paquets_necessaires: Optional[str] = None  # JSON string
    commandes_installation: Optional[str] = None
    problemes_connus: Optional[str] = None
    solutions: Optional[str] = None
    compatibilite_noyau: Optional[str] = Field(None, max_length=100)

    # Connectivité
    interface_connexion: Optional[str] = Field(None, max_length=100)
    connecte_a: Optional[str] = Field(None, max_length=255)
    consommation_electrique_w: Optional[float] = Field(None, ge=0)

    # Localisation physique
    location_id: Optional[int] = None
    location_details: Optional[str] = Field(None, max_length=500)
    location_auto: Optional[bool] = True

    # Appareil complet
    is_complete_device: Optional[bool] = False
    device_type: Optional[str] = Field(None, max_length=50)
    linked_device_id: Optional[int] = None
    device_id: Optional[int] = None

    # Données spécifiques
    caracteristiques_specifiques: Optional[Dict[str, Any]] = None


class PeripheralCreate(PeripheralBase):
    """Schema for creating a peripheral"""
    pass


class PeripheralUpdate(BaseModel):
    """Schema for updating a peripheral (all fields optional)"""
    nom: Optional[str] = Field(None, min_length=1, max_length=255)
    type_principal: Optional[str] = Field(None, min_length=1, max_length=100)
    sous_type: Optional[str] = Field(None, max_length=100)
    marque: Optional[str] = Field(None, max_length=100)
    modele: Optional[str] = Field(None, max_length=255)
    fabricant: Optional[str] = Field(None, max_length=255)
    produit: Optional[str] = Field(None, max_length=255)
    numero_serie: Optional[str] = Field(None, max_length=255)
    ean_upc: Optional[str] = Field(None, max_length=50)
    boutique: Optional[str] = Field(None, max_length=255)
    date_achat: Optional[date] = None
    prix: Optional[float] = Field(None, ge=0)
    devise: Optional[str] = Field(None, max_length=10)
    garantie_duree_mois: Optional[int] = Field(None, ge=0)
    garantie_expiration: Optional[date] = None
    rating: Optional[float] = Field(None, ge=0, le=5)
    quantite_totale: Optional[int] = Field(None, ge=0)
    quantite_disponible: Optional[int] = Field(None, ge=0)
    seuil_alerte: Optional[int] = Field(None, ge=0)
    etat: Optional[str] = Field(None, max_length=50)
    localisation: Optional[str] = Field(None, max_length=255)
    proprietaire: Optional[str] = Field(None, max_length=100)
    tags: Optional[str] = None
    notes: Optional[str] = None
    device_path: Optional[str] = Field(None, max_length=255)
    vendor_id: Optional[str] = Field(None, max_length=20)
    product_id: Optional[str] = Field(None, max_length=20)
    usb_device_id: Optional[str] = Field(None, max_length=20)
    iManufacturer: Optional[str] = None
    iProduct: Optional[str] = None
    connecte_a: Optional[str] = Field(None, max_length=255)
    location_id: Optional[int] = None
    location_details: Optional[str] = Field(None, max_length=500)
    is_complete_device: Optional[bool] = None
    device_type: Optional[str] = Field(None, max_length=50)
    linked_device_id: Optional[int] = None
    device_id: Optional[int] = None
    caracteristiques_specifiques: Optional[Dict[str, Any]] = None


class PeripheralSummary(BaseModel):
    """Summary schema for peripheral lists"""
    id: int
    nom: str
    type_principal: str
    sous_type: Optional[str]
    marque: Optional[str]
    modele: Optional[str]
    etat: str
    rating: float
    prix: Optional[float]
    en_pret: bool
    is_complete_device: bool
    quantite_disponible: int
    thumbnail_url: Optional[str] = None

    class Config:
        from_attributes = True


class PeripheralDetail(PeripheralBase):
    """Detailed schema with all information"""
    id: int
    date_creation: datetime
    date_modification: Optional[datetime]
    en_pret: bool
    pret_actuel_id: Optional[int]
    prete_a: Optional[str]

    class Config:
        from_attributes = True


class PeripheralListResponse(BaseModel):
    """Paginated list response"""
    items: List[PeripheralSummary]
    total: int
    page: int
    page_size: int
    total_pages: int


# ========================================
# PHOTO SCHEMAS
# ========================================

class PeripheralPhotoBase(BaseModel):
    """Base schema for peripheral photos"""
    description: Optional[str] = None
    is_primary: Optional[bool] = False


class PeripheralPhotoCreate(PeripheralPhotoBase):
    """Schema for creating a photo"""
    peripheral_id: int
    filename: str
    stored_path: str
    mime_type: Optional[str]
    size_bytes: Optional[int]


class PeripheralPhotoSchema(PeripheralPhotoBase):
    """Full photo schema"""
    id: int
    peripheral_id: int
    filename: str
    stored_path: str
    thumbnail_path: Optional[str]
    mime_type: Optional[str]
    size_bytes: Optional[int]
    uploaded_at: datetime

    class Config:
        from_attributes = True


# ========================================
# DOCUMENT SCHEMAS
# ========================================

class PeripheralDocumentBase(BaseModel):
    """Base schema for peripheral documents"""
    doc_type: str = Field(..., max_length=50)  # manual, warranty, invoice, datasheet, other
    description: Optional[str] = None


class PeripheralDocumentCreate(PeripheralDocumentBase):
    """Schema for creating a document"""
    peripheral_id: int
    filename: str
    stored_path: str
    mime_type: Optional[str]
    size_bytes: Optional[int]


class PeripheralDocumentSchema(PeripheralDocumentBase):
    """Full document schema"""
    id: int
    peripheral_id: int
    filename: str
    stored_path: str
    mime_type: Optional[str]
    size_bytes: Optional[int]
    uploaded_at: datetime

    class Config:
        from_attributes = True


# ========================================
# LINK SCHEMAS
# ========================================

class PeripheralLinkBase(BaseModel):
    """Base schema for peripheral links"""
    link_type: str = Field(..., max_length=50)  # manufacturer, support, drivers, documentation, custom
    label: str = Field(..., min_length=1, max_length=255)
    url: str


class PeripheralLinkCreate(PeripheralLinkBase):
    """Schema for creating a link"""
    peripheral_id: int


class PeripheralLinkSchema(PeripheralLinkBase):
    """Full link schema"""
    id: int
    peripheral_id: int

    class Config:
        from_attributes = True


# ========================================
# LOAN SCHEMAS
# ========================================

class LoanBase(BaseModel):
    """Base schema for loans"""
    emprunte_par: str = Field(..., min_length=1, max_length=255)
    email_emprunteur: Optional[str] = Field(None, max_length=255)
    telephone: Optional[str] = Field(None, max_length=50)
    date_pret: date
    date_retour_prevue: date
    caution_montant: Optional[float] = Field(None, ge=0)
    etat_depart: Optional[str] = Field(None, max_length=50)
    raison_pret: Optional[str] = None
    notes: Optional[str] = None


class LoanCreate(LoanBase):
    """Schema for creating a loan"""
    peripheral_id: int


class LoanReturn(BaseModel):
    """Schema for returning a loan"""
    date_retour_effectif: date
    etat_retour: Optional[str] = Field(None, max_length=50)
    problemes_retour: Optional[str] = None
    caution_rendue: bool = True
    notes: Optional[str] = None


class LoanSchema(LoanBase):
    """Full loan schema"""
    id: int
    peripheral_id: int
    date_retour_effectif: Optional[date]
    statut: str
    caution_rendue: bool
    etat_retour: Optional[str]
    problemes_retour: Optional[str]
    created_by: Optional[str]
    rappel_envoye: bool
    date_rappel: Optional[datetime]

    class Config:
        from_attributes = True


# ========================================
# LOCATION SCHEMAS
# ========================================

class LocationBase(BaseModel):
    """Base schema for locations"""
    nom: str = Field(..., min_length=1, max_length=255)
    type: str = Field(..., max_length=50)  # root, piece, placard, tiroir, etagere, meuble, boite
    parent_id: Optional[int] = None
    description: Optional[str] = None
    ordre_affichage: Optional[int] = 0


class LocationCreate(LocationBase):
    """Schema for creating a location"""
    pass


class LocationUpdate(BaseModel):
    """Schema for updating a location"""
    nom: Optional[str] = Field(None, min_length=1, max_length=255)
    type: Optional[str] = Field(None, max_length=50)
    parent_id: Optional[int] = None
    description: Optional[str] = None
    ordre_affichage: Optional[int] = None


class LocationSchema(LocationBase):
    """Full location schema"""
    id: int
    image_path: Optional[str]
    qr_code_path: Optional[str]

    class Config:
        from_attributes = True


class LocationTreeNode(LocationSchema):
    """Location with children for tree view"""
    children: List['LocationTreeNode'] = []

    class Config:
        from_attributes = True


# ========================================
# HISTORY SCHEMAS
# ========================================

class PeripheralHistorySchema(BaseModel):
    """Peripheral location history schema"""
    id: int
    peripheral_id: int
    from_location_id: Optional[int]
    to_location_id: Optional[int]
    from_device_id: Optional[int]
    to_device_id: Optional[int]
    action: str
    timestamp: datetime
    notes: Optional[str]
    user: Optional[str]

    class Config:
        from_attributes = True
