use meilisearch_sdk::client::*;
use meilisearch_sdk::search::*;
use serde::{Deserialize, Serialize};

#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct BookMeili {
    pub id: i32,
    pub open_library_key: String,
    pub title: String,
    pub edition_count: i32,
    pub first_publish_year: i32,
    pub median_page_count: i32,
    pub goodread_id: String,
    pub description: String,
    pub cover: String,
    pub location: String,
    pub time_added: String,
    pub rating: i32,
    pub comments: String,
    pub author_name: Vec<String>,
    pub person: Vec<String>,
    pub place: Vec<String>,
    pub subject: Vec<String>,
    pub time: Vec<String>,
    pub isbn: Vec<String>,
}

pub async fn create_or_update_book(book: BookMeili, userid: i32, client: &Client) {
    // An index is where the documents are stored.
    let books = client.index(format!("books{}", userid));
    // Add some movies in the index. If the index 'movies' does not exist, Meilisearch creates it when you first add the documents.
    books.add_or_replace(&[book], Some("id")).await.unwrap();
}

pub async fn delete_book(bookid: i32, userid: i32, client: &Client) {
    // An index is where the documents are stored.
    let books = client.index(format!("books{}", userid));
    books.delete_document(bookid).await.unwrap();
}

pub async fn search_book(
    search: &str,
    page: usize,
    userid: i32,
    client: &Client,
) -> Result<(Vec<BookMeili>, usize), meilisearch_sdk::errors::Error> {
    // An index is where the documents are stored.
    let books = client.index(format!("books{}", userid));
    let results: SearchResults<BookMeili> = books
        .search()
        .with_query(search)
        .with_offset((page - 1) * 12)
        .execute::<BookMeili>()
        .await
        .unwrap();

    let formatted_results: Vec<BookMeili> =
        (results.hits).iter().map(|r| r.result.clone()).collect();
    //.iter()s.map(|r| r.formatted_result.unwrap()).collect();
    return Ok((formatted_results, results.estimated_total_hits));
}
