use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use sqlx::FromRow;
use uuid::Uuid;

use super::patch::Patch;

#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct Collection {
    pub id: Uuid,
    pub user_id: Uuid,
    pub name: String,
    pub description: Option<String>,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

/// Shape returned by `GET /me/collections`. Enriched with the manga
/// count and up to three sample cover paths so a collection card can
/// render without extra round-trips.
#[derive(Debug, Clone, Serialize, FromRow)]
pub struct CollectionSummary {
    pub id: Uuid,
    pub user_id: Uuid,
    pub name: String,
    pub description: Option<String>,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
    pub manga_count: i64,
    /// Cover image keys of up to three sample mangas (newest-added
    /// first). `Vec<String>` rather than `Option<...>` so an empty
    /// collection renders as `[]` rather than `null`.
    pub sample_covers: Vec<String>,
}

/// Row returned by `GET /collections/:id/pages`. Joins through
/// `chapters` and `mangas` so the collection detail view can render a
/// thumbnail + breadcrumb without per-row follow-up fetches.
#[derive(Debug, Clone, Serialize, FromRow)]
pub struct CollectionPageItem {
    pub page_id: Uuid,
    pub chapter_id: Uuid,
    pub manga_id: Uuid,
    pub page_number: i32,
    pub chapter_number: i32,
    pub chapter_title: Option<String>,
    pub manga_title: String,
    pub storage_key: String,
    pub added_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Deserialize)]
pub struct NewCollection {
    pub name: String,
    #[serde(default)]
    pub description: Option<String>,
}

#[derive(Debug, Clone, Deserialize, Default)]
pub struct CollectionPatch {
    pub name: Option<String>,
    /// Three-state: missing key leaves description alone; explicit
    /// `null` clears it; a string sets it. See `Patch`.
    #[serde(default)]
    pub description: Patch<String>,
}
