"""NFO API request and response models.

This module defines Pydantic models for NFO management API operations.
"""
from datetime import datetime
from typing import List, Optional

from pydantic import BaseModel, Field


class MediaFilesStatus(BaseModel):
    """Status of media files (poster, logo, fanart) for a series.
    
    Attributes:
        has_poster: Whether poster.jpg exists
        has_logo: Whether logo.png exists
        has_fanart: Whether fanart.jpg exists
        poster_path: Path to poster file if exists
        logo_path: Path to logo file if exists
        fanart_path: Path to fanart file if exists
    """
    has_poster: bool = Field(
        default=False,
        description="Whether poster.jpg exists"
    )
    has_logo: bool = Field(
        default=False,
        description="Whether logo.png exists"
    )
    has_fanart: bool = Field(
        default=False,
        description="Whether fanart.jpg exists"
    )
    poster_path: Optional[str] = Field(
        default=None,
        description="Path to poster file if exists"
    )
    logo_path: Optional[str] = Field(
        default=None,
        description="Path to logo file if exists"
    )
    fanart_path: Optional[str] = Field(
        default=None,
        description="Path to fanart file if exists"
    )


class NFOCheckResponse(BaseModel):
    """Response for NFO existence check.
    
    Attributes:
        serie_id: Series identifier
        serie_folder: Series folder name
        has_nfo: Whether tvshow.nfo exists
        nfo_path: Path to NFO file if exists
        media_files: Status of media files
    """
    serie_id: str = Field(
        ...,
        description="Series identifier"
    )
    serie_folder: str = Field(
        ...,
        description="Series folder name"
    )
    has_nfo: bool = Field(
        ...,
        description="Whether tvshow.nfo exists"
    )
    nfo_path: Optional[str] = Field(
        default=None,
        description="Path to NFO file if exists"
    )
    media_files: MediaFilesStatus = Field(
        ...,
        description="Status of media files"
    )


class NFOCreateRequest(BaseModel):
    """Request to create NFO file.
    
    Attributes:
        serie_name: Name to search in TMDB
        year: Optional year to narrow search
        download_poster: Whether to download poster.jpg
        download_logo: Whether to download logo.png
        download_fanart: Whether to download fanart.jpg
        overwrite_existing: Whether to overwrite existing NFO
    """
    serie_name: Optional[str] = Field(
        default=None,
        description="Name to search in TMDB (defaults to folder name)"
    )
    year: Optional[int] = Field(
        default=None,
        description="Optional year to narrow search"
    )
    download_poster: bool = Field(
        default=True,
        description="Whether to download poster.jpg"
    )
    download_logo: bool = Field(
        default=True,
        description="Whether to download logo.png"
    )
    download_fanart: bool = Field(
        default=True,
        description="Whether to download fanart.jpg"
    )
    overwrite_existing: bool = Field(
        default=False,
        description="Whether to overwrite existing NFO"
    )


class NFOCreateResponse(BaseModel):
    """Response after NFO creation.
    
    Attributes:
        serie_id: Series identifier
        serie_folder: Series folder name
        nfo_path: Path to created NFO file
        media_files: Status of downloaded media files
        tmdb_id: TMDB ID of matched series
        message: Success message
    """
    serie_id: str = Field(
        ...,
        description="Series identifier"
    )
    serie_folder: str = Field(
        ...,
        description="Series folder name"
    )
    nfo_path: str = Field(
        ...,
        description="Path to created NFO file"
    )
    media_files: MediaFilesStatus = Field(
        ...,
        description="Status of downloaded media files"
    )
    tmdb_id: Optional[int] = Field(
        default=None,
        description="TMDB ID of matched series"
    )
    message: str = Field(
        ...,
        description="Success message"
    )


class NFOContentResponse(BaseModel):
    """Response containing NFO XML content.
    
    Attributes:
        serie_id: Series identifier
        serie_folder: Series folder name
        content: NFO XML content
        file_size: Size of NFO file in bytes
        last_modified: Last modification timestamp
    """
    serie_id: str = Field(
        ...,
        description="Series identifier"
    )
    serie_folder: str = Field(
        ...,
        description="Series folder name"
    )
    content: str = Field(
        ...,
        description="NFO XML content"
    )
    file_size: int = Field(
        ...,
        description="Size of NFO file in bytes"
    )
    last_modified: Optional[datetime] = Field(
        default=None,
        description="Last modification timestamp"
    )


class MediaDownloadRequest(BaseModel):
    """Request to download specific media files.
    
    Attributes:
        download_poster: Whether to download poster.jpg
        download_logo: Whether to download logo.png
        download_fanart: Whether to download fanart.jpg
        overwrite_existing: Whether to overwrite existing files
    """
    download_poster: bool = Field(
        default=False,
        description="Whether to download poster.jpg"
    )
    download_logo: bool = Field(
        default=False,
        description="Whether to download logo.png"
    )
    download_fanart: bool = Field(
        default=False,
        description="Whether to download fanart.jpg"
    )
    overwrite_existing: bool = Field(
        default=False,
        description="Whether to overwrite existing files"
    )


class NFOBatchCreateRequest(BaseModel):
    """Request to batch create NFOs for multiple series.
    
    Attributes:
        serie_ids: List of series IDs to process
        download_media: Whether to download media files
        skip_existing: Whether to skip series with existing NFOs
        max_concurrent: Maximum concurrent creations
    """
    serie_ids: List[str] = Field(
        ...,
        description="List of series IDs to process"
    )
    download_media: bool = Field(
        default=True,
        description="Whether to download media files"
    )
    skip_existing: bool = Field(
        default=True,
        description="Whether to skip series with existing NFOs"
    )
    max_concurrent: int = Field(
        default=3,
        ge=1,
        le=10,
        description="Maximum concurrent creations (1-10)"
    )


class NFOBatchResult(BaseModel):
    """Result for a single series in batch operation.
    
    Attributes:
        serie_id: Series identifier
        serie_folder: Series folder name
        success: Whether operation succeeded
        message: Success or error message
        nfo_path: Path to NFO file if successful
    """
    serie_id: str = Field(
        ...,
        description="Series identifier"
    )
    serie_folder: str = Field(
        ...,
        description="Series folder name"
    )
    success: bool = Field(
        ...,
        description="Whether operation succeeded"
    )
    message: str = Field(
        ...,
        description="Success or error message"
    )
    nfo_path: Optional[str] = Field(
        default=None,
        description="Path to NFO file if successful"
    )


class NFOBatchCreateResponse(BaseModel):
    """Response after batch NFO creation.
    
    Attributes:
        total: Total number of series processed
        successful: Number of successful creations
        failed: Number of failed creations
        skipped: Number of skipped series
        results: Detailed results for each series
    """
    total: int = Field(
        ...,
        description="Total number of series processed"
    )
    successful: int = Field(
        ...,
        description="Number of successful creations"
    )
    failed: int = Field(
        ...,
        description="Number of failed creations"
    )
    skipped: int = Field(
        ...,
        description="Number of skipped series"
    )
    results: List[NFOBatchResult] = Field(
        ...,
        description="Detailed results for each series"
    )


class NFOMissingSeries(BaseModel):
    """Information about a series missing NFO.
    
    Attributes:
        serie_id: Series identifier
        serie_folder: Series folder name
        serie_name: Display name
        has_media: Whether any media files exist
        media_files: Status of media files
    """
    serie_id: str = Field(
        ...,
        description="Series identifier"
    )
    serie_folder: str = Field(
        ...,
        description="Series folder name"
    )
    serie_name: str = Field(
        ...,
        description="Display name"
    )
    has_media: bool = Field(
        default=False,
        description="Whether any media files exist"
    )
    media_files: MediaFilesStatus = Field(
        ...,
        description="Status of media files"
    )


class NFOMissingResponse(BaseModel):
    """Response listing series without NFOs.
    
    Attributes:
        total_series: Total number of series in library
        missing_nfo_count: Number of series without NFO
        series: List of series missing NFO
    """
    total_series: int = Field(
        ...,
        description="Total number of series in library"
    )
    missing_nfo_count: int = Field(
        ...,
        description="Number of series without NFO"
    )
    series: List[NFOMissingSeries] = Field(
        ...,
        description="List of series missing NFO"
    )


class NfoDiagnosticsResponse(BaseModel):
    """Response for NFO diagnostics showing missing required tags."""

    has_nfo: bool = Field(..., description="Whether tvshow.nfo exists")
    nfo_path: Optional[str] = Field(None, description="Path to NFO file if exists")
    missing_tags: List[str] = Field(
        default_factory=list,
        description="List of missing required tag names"
    )
    required_tags: List[str] = Field(
        default_factory=list,
        description="All required tag names for reference"
    )


class NfoRepairResponse(BaseModel):
    """Response after NFO repair attempt."""

    success: bool = Field(..., description="Whether repair succeeded")
    message: str = Field(..., description="Human-readable result message")
    repaired_tags: List[str] = Field(
        default_factory=list,
        description="Tags that were missing before repair"
    )
