use loco_rs::prelude::*;
use sea_orm::QueryOrder;
use serde::{Deserialize, Serialize};

pub use super::_entities::reading_records::{self, ActiveModel, Entity, Model};

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

impl Model {
    /// Find reading records by user ID
    pub async fn list_by_user(db: &DatabaseConnection, user_id: i32) -> ModelResult<Vec<Model>> {
        let records = reading_records::Entity::find()
            .filter(reading_records::Column::UserId.eq(user_id))
            .order_by_desc(reading_records::Column::Id)
            .all(db)
            .await?;
        Ok(records)
    }

    /// Find or create a reading record for a user and book
    pub async fn find_or_create(
        db: &DatabaseConnection,
        user_id: i32,
        book_id: i32,
    ) -> ModelResult<Self> {
        // Try to find existing record
        let record = reading_records::Entity::find()
            .filter(reading_records::Column::UserId.eq(user_id))
            .filter(reading_records::Column::BookId.eq(book_id))
            .one(db)
            .await?;

        if let Some(record) = record {
            return Ok(record);
        }

        // Create new record
        let record = reading_records::ActiveModel {
            user_id: ActiveValue::Set(user_id),
            book_id: ActiveValue::Set(book_id),
            ..Default::default()
        };
        let record = record.insert(db).await?;
        Ok(record)
    }

    /// Update a reading record
    pub async fn update_record(
        &self,
        db: &DatabaseConnection,
        params: &CreateReadingRecordParams,
    ) -> ModelResult<Self> {
        let mut record: reading_records::ActiveModel = self.clone().into();
        record.last_read_chapter = ActiveValue::Set(params.last_read_chapter.clone());
        record.last_read_position = ActiveValue::Set(params.last_read_position);
        record.read_percentage = ActiveValue::Set(params.read_percentage);
        let record = record.update(db).await?;
        Ok(record)
    }
}
