import Foundation

// MARK: - Manga Model

/// Representa la información completa de un manga.
///
/// `Manga` es una estructura inmutable que contiene toda la información relevante
/// sobre un manga, incluyendo título, descripción, géneros, estado de publicación
/// y metadatos adicionales como la URL de la imagen de portada.
///
/// Conforma a `Codable` para serialización/deserialización automática,
/// `Identifiable` para uso en listas de SwiftUI, y `Hashable` para comparaciones
/// y uso en sets.
///
/// # Example
/// ```swift
/// let manga = Manga(
///     slug: "one-piece_1695365223767",
///     title: "One Piece",
///     description: "La historia de Monkey D. Luffy y su tripulación...",
///     genres: ["Acción", "Aventura", "Comedia"],
///     status: "PUBLICANDOSE",
///     url: "https://manhwaweb.com/manga/one-piece_1695365223767",
///     coverImage: "https://example.com/cover.jpg"
/// )
/// print(manga.displayStatus) // "En publicación"
/// ```
struct Manga: Codable, Identifiable, Hashable {
    /// Identificador único del manga (computed, igual al slug)
    let id: String { slug }

    /// Slug único usado en URLs del sitio web
    let slug: String

    /// Título del manga
    let title: String

    /// Descripción o sinopsis del manga
    let description: String

    /// Array de géneros literarios del manga
    let genres: [String]

    /// Estado de publicación (crudo, sin traducir)
    let status: String

    /// URL completa del manga en el sitio web
    let url: String

    /// URL de la imagen de portada (opcional)
    let coverImage: String?

    /// Coding keys para mapeo JSON/codificación personalizada
    enum CodingKeys: String, CodingKey {
        case slug, title, description, genres, status, url, coverImage
    }

    /// Estado de publicación formateado para mostrar en la UI
    ///
    /// Traduce los estados crudos del sitio web a formato legible para el usuario.
    ///
    /// # Mapeos
    /// - `"PUBLICANDOSE"` → `"En publicación"`
    /// - `"FINALIZADO"` → `"Finalizado"`
    /// - `"EN_PAUSA"`, `"EN_ESPERA"` → `"En pausa"`
    /// - Otro → retorna el valor original sin modificar
    ///
    /// - Returns: String con el estado traducido y formateado
    var displayStatus: String {
        switch status {
        case "PUBLICANDOSE":
            return "En publicación"
        case "FINALIZADO":
            return "Finalizado"
        case "EN_PAUSA", "EN_ESPERA":
            return "En pausa"
        default:
            return status
        }
    }
}

// MARK: - Chapter Model

/// Representa un capítulo individual de un manga.
///
/// `Chapter` contiene información sobre un capítulo específico, incluyendo
/// su número, título, URL, y metadatos de lectura como si ha sido leído,
/// descargado, y la última página leída.
///
/// Las propiedades `isRead`, `isDownloaded`, y `lastReadPage` son mutables
/// para actualizar el estado de lectura del usuario.
///
/// # Example
/// ```swift
/// var chapter = Chapter(
///     number: 1,
///     title: "El inicio de la aventura",
///     url: "https://manhwaweb.com/leer/one-piece/1",
///     slug: "one-piece/1"
/// )
/// chapter.isRead = true
/// chapter.lastReadPage = 15
/// print(chapter.displayNumber) // "Capítulo 1"
/// ```
struct Chapter: Codable, Identifiable, Hashable {
    /// Identificador único del capítulo (computed, igual al número)
    let id: Int { number }

    /// Número del capítulo
    let number: Int

    /// Título del capítulo
    let title: String

    /// URL completa del capítulo en el sitio web
    let url: String

    /// Slug para identificar el capítulo en URLs
    let slug: String

    /// Indica si el capítulo ha sido marcado como leído
    var isRead: Bool = false

    /// Indica si el capítulo ha sido descargado localmente
    var isDownloaded: Bool = false

    /// Última página leída por el usuario
    var lastReadPage: Int = 0

    /// Número de capítulo formateado para mostrar en la UI
    ///
    /// - Returns: String con formato "Capítulo {número}"
    var displayNumber: String {
        return "Capítulo \(number)"
    }

    /// Progreso de lectura como Double para ProgressViews
    ///
    /// - Returns: Double representando la última página leída
    var progress: Double {
        return Double(lastReadPage)
    }
}

// MARK: - Manga Page (Image)

/// Representa una página individual (imagen) de un capítulo.
///
/// `MangaPage` contiene la URL de una imagen de manga y su posición
/// dentro del capítulo. Puede marcar si la imagen está cacheada localmente
/// para evitar descargas redundantes.
///
/// # Example
/// ```swift
/// let page = MangaPage(url: "https://example.com/page1.jpg", index: 0)
/// print(page.id) // URL completa
/// ```
struct MangaPage: Codable, Identifiable, Hashable {
    /// Identificador único de la página (computed, igual a la URL)
    let id: String { url }

    /// URL completa de la imagen
    let url: String

    /// Índice de la página en el capítulo (0-based)
    let index: Int

    /// Indica si la imagen está cacheada en almacenamiento local
    var isCached: Bool = false

    /// URL de la versión thumbnail de la imagen
    ///
    /// Actualmente retorna la misma URL. Futura implementación puede
    /// retornar una versión optimizada/miniatura de la imagen.
    ///
    /// - Returns: URL del thumbnail (o de la imagen completa)
    var thumbnailURL: String {
        // Para thumbnail podríamos usar una versión más pequeña
        return url
    }
}

// MARK: - Reading Progress

/// Almacena el progreso de lectura de un usuario.
///
/// `ReadingProgress` registra qué página de qué capítulo de qué manga
/// leyó el usuario, junto con un timestamp para sincronización.
///
/// # Example
/// ```swift
/// let progress = ReadingProgress(
///     mangaSlug: "one-piece",
///     chapterNumber: 1,
///     pageNumber: 15,
///     timestamp: Date()
/// )
/// if progress.isCompleted {
///     print("Capítulo completado")
/// }
/// ```
struct ReadingProgress: Codable {
    /// Slug del manga que se está leyendo
    let mangaSlug: String

    /// Número del capítulo
    let chapterNumber: Int

    /// Número de página actual
    let pageNumber: Int

    /// Fecha y hora en que se guardó el progreso
    let timestamp: Date

    /// Indica si el capítulo se considera completado
    ///
    /// Un capítulo se considera completado si el usuario ha leído
    /// más de 5 páginas. Este umbral evita marcar como completados
    /// capítulos que el usuario solo hojeó.
    ///
    /// - Returns: `true` si `pageNumber > 5`, `false` en caso contrario
    var isCompleted: Bool {
        // Considerar completado si leyó más de 5 páginas
        return pageNumber > 5
    }
}

// MARK: - Downloaded Chapter

/// Representa un capítulo descargado localmente en el dispositivo.
///
/// `DownloadedChapter` contiene metadata sobre un capítulo que ha sido
/// descargado, incluyendo todas sus páginas, fecha de descarga, y tamaño
/// total en disco.
///
/// # Example
/// ```swift
/// let downloaded = DownloadedChapter(
///     mangaSlug: "one-piece",
///     mangaTitle: "One Piece",
///     chapterNumber: 1,
///     pages: [page1, page2, page3],
///     downloadedAt: Date()
/// )
/// print(downloaded.displayTitle) // "One Piece - Capítulo 1"
/// ```
struct DownloadedChapter: Codable, Identifiable {
    /// Identificador único compuesto por manga-slug y número de capítulo
    let id: String { "\(mangaSlug)-chapter\(chapterNumber)" }

    /// Slug del manga
    let mangaSlug: String

    /// Título del manga
    let mangaTitle: String

    /// Número del capítulo
    let chapterNumber: Int

    /// Array de páginas del capítulo
    let pages: [MangaPage]

    /// Fecha y hora de descarga
    let downloadedAt: Date

    /// Tamaño total del capítulo en bytes
    var totalSize: Int64 = 0

    /// Título formateado para mostrar en la UI
    ///
    /// - Returns: String con formato "{MangaTitle} - Capítulo {number}"
    var displayTitle: String {
        "\(mangaTitle) - Capítulo \(chapterNumber)"
    }
}

// MARK: - API Response Models

/// Respuesta de API que contiene una lista de mangas.
///
/// Usado para respuestas paginadas o listas completas de mangas
/// desde un backend opcional.
struct MangaListResponse: Codable {
    /// Array de mangas en la respuesta
    let mangas: [Manga]

    /// Número total de mangas (útil para paginación)
    let total: Int
}

/// Respuesta de API que contiene la lista de capítulos de un manga.
struct ChapterListResponse: Codable {
    /// Array de capítulos del manga
    let chapters: [Chapter]

    /// Slug del manga al que pertenecen los capítulos
    let mangaSlug: String
}

/// Respuesta de API con las URLs de imágenes de un capítulo.
struct ChapterImagesResponse: Codable {
    /// Array de URLs de imágenes en orden
    let images: [String]

    /// Slug del capítulo
    let chapterSlug: String
}
