use axum::debug_handler;
use loco_rs::prelude::*;
use serde::{Deserialize, Serialize};

use crate::models::reading_records::{CreateReadingRecordParams, Model as ReadingRecordModel};

#[derive(Debug, Deserialize, Serialize)]
pub struct SaveRecordParams {
    pub book_id: i32,
    pub last_read_chapter: Option<String>,
    pub last_read_position: Option<i32>,
    pub read_percentage: Option<f64>,
}

/// Save or update reading record
#[debug_handler]
pub async fn save_record(
    auth: auth::JWT,
    State(ctx): State<AppContext>,
    Json(params): Json<SaveRecordParams>,
) -> Result<Response> {
    let user = crate::models::users::Model::find_by_pid(&ctx.db, &auth.claims.pid.to_string())
        .await?;

    // Find or create the reading record
    let mut record = ReadingRecordModel::find_or_create(&ctx.db, user.id, params.book_id).await?;

    // Update the record
    let update_params = CreateReadingRecordParams {
        book_id: params.book_id,
        last_read_chapter: params.last_read_chapter,
        last_read_position: params.last_read_position,
        read_percentage: params.read_percentage,
    };

    record = record.update_record(&ctx.db, &update_params).await?;
    format::json(record)
}

/// Get user's reading history
#[debug_handler]
pub async fn history(
    auth: auth::JWT,
    State(ctx): State<AppContext>,
) -> Result<Response> {
    let user = crate::models::users::Model::find_by_pid(&ctx.db, &auth.claims.pid.to_string())
        .await?;

    let records = ReadingRecordModel::list_by_user(&ctx.db, user.id).await?;
    format::json(records)
}

pub fn routes() -> Routes {
    Routes::new()
        .prefix("reading")
        .add("/record", post(save_record))
        .add("/history", get(history))
}
