use rusqlite::{params, Connection};

use crate::error::{AppError, AppResult};
use crate::shared::types::Lang;

pub struct BookAIGuideLineTable {
    pub user_id: String,
    pub book_id: String,
    pub global_resume: Option<String>,
    pub themes: Option<String>,
    pub verbe_tense: Option<i64>,
    pub narrative_type: Option<i64>,
    pub langue: Option<i64>,
    pub dialogue_type: Option<i64>,
    pub tone: Option<String>,
    pub atmosphere: Option<String>,
    pub current_resume: Option<String>,
    pub last_update: i64,
}

pub struct BookGuideLineTable {
    pub user_id: String,
    pub book_id: String,
    pub tone: Option<String>,
    pub atmosphere: Option<String>,
    pub writing_style: Option<String>,
    pub themes: Option<String>,
    pub symbolism: Option<String>,
    pub motifs: Option<String>,
    pub narrative_voice: Option<String>,
    pub pacing: Option<String>,
    pub intended_audience: Option<String>,
    pub key_messages: Option<String>,
    pub last_update: i64,
}

pub struct SyncedGuideLineResult {
    pub book_id: String,
    pub last_update: i64,
}

pub struct SyncedAIGuideLineResult {
    pub book_id: String,
    pub last_update: i64,
}

pub struct GuideLineQuery {
    pub tone: String,
    pub atmosphere: String,
    pub writing_style: String,
    pub themes: String,
    pub symbolism: String,
    pub motifs: String,
    pub narrative_voice: String,
    pub pacing: String,
    pub intended_audience: String,
    pub key_messages: String,
}

pub struct GuideLineAIQuery {
    pub _user_id: String,
    pub _book_id: String,
    pub global_resume: Option<String>,
    pub themes: Option<String>,
    pub verbe_tense: Option<i64>,
    pub narrative_type: Option<i64>,
    pub langue: Option<i64>,
    pub dialogue_type: Option<i64>,
    pub _tone: Option<String>,
    pub atmosphere: Option<String>,
    pub current_resume: Option<String>,
    pub _meta: String,
}

/// Fetches the guideline for a specific book.
/// * `conn` - Database connection
/// * `user_id` - The user identifier
/// * `book_id` - The book identifier
/// * `lang` - The language for error messages ("fr" or "en")
/// Returns an array of guideline query results.
/// Errors if the guideline cannot be retrieved.
pub fn fetch_guide_line(conn: &Connection, user_id: &str, book_id: &str, lang: Lang) -> AppResult<Vec<GuideLineQuery>> {
    let mut statement = conn
        .prepare("SELECT tone, atmosphere, writing_style, themes, symbolism, motifs, narrative_voice, pacing, intended_audience, key_messages FROM book_guide_line WHERE book_id=?1 AND user_id=?2")
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible de récupérer la ligne directrice.".to_string() } else { "Unable to retrieve guideline.".to_string() }))?;

    let guidelines = statement
        .query_map(params![book_id, user_id], |query_row| {
            Ok(GuideLineQuery {
                tone: query_row.get(0)?, atmosphere: query_row.get(1)?,
                writing_style: query_row.get(2)?, themes: query_row.get(3)?,
                symbolism: query_row.get(4)?, motifs: query_row.get(5)?,
                narrative_voice: query_row.get(6)?, pacing: query_row.get(7)?,
                intended_audience: query_row.get(8)?, key_messages: query_row.get(9)?,
            })
        })
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible de récupérer la ligne directrice.".to_string() } else { "Unable to retrieve guideline.".to_string() }))?
        .collect::<Result<Vec<_>, _>>()
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible de récupérer la ligne directrice.".to_string() } else { "Unable to retrieve guideline.".to_string() }))?;

    Ok(guidelines)
}

/// Updates or inserts a guideline for a specific book.
/// If the guideline exists, it updates it; otherwise, it inserts a new one.
/// * `conn` - Database connection
/// * `user_id` - The user identifier
/// * `book_id` - The book identifier
/// * `encrypted_tone` - The encrypted tone value
/// * `encrypted_atmosphere` - The encrypted atmosphere value
/// * `encrypted_writing_style` - The encrypted writing style value
/// * `encrypted_themes` - The encrypted themes value
/// * `encrypted_symbolism` - The encrypted symbolism value
/// * `encrypted_motifs` - The encrypted motifs value
/// * `encrypted_narrative_voice` - The encrypted narrative voice value
/// * `encrypted_pacing` - The encrypted pacing value
/// * `encrypted_key_messages` - The encrypted key messages value
/// * `encrypted_intended_audience` - The encrypted intended audience value
/// * `last_update` - The timestamp of the last update
/// * `lang` - The language for error messages ("fr" or "en")
/// Returns true if the operation was successful.
/// Errors if the guideline cannot be updated or inserted.
pub fn update_guide_line(
    conn: &Connection, user_id: &str, book_id: &str, encrypted_tone: Option<&str>,
    encrypted_atmosphere: Option<&str>, encrypted_writing_style: Option<&str>,
    encrypted_themes: Option<&str>, encrypted_symbolism: Option<&str>,
    encrypted_motifs: Option<&str>, encrypted_narrative_voice: Option<&str>,
    encrypted_pacing: Option<&str>, encrypted_key_messages: Option<&str>,
    encrypted_intended_audience: Option<&str>, last_update: i64, lang: Lang,
) -> AppResult<bool> {
    let update_result = conn
        .execute(
            "UPDATE book_guide_line SET tone=?1, atmosphere=?2, writing_style=?3, themes=?4, symbolism=?5, motifs=?6, narrative_voice=?7, pacing=?8, intended_audience=?9, key_messages=?10, last_update=?11 WHERE user_id=?12 AND book_id=?13",
            params![encrypted_tone, encrypted_atmosphere, encrypted_writing_style, encrypted_themes, encrypted_symbolism, encrypted_motifs, encrypted_narrative_voice, encrypted_pacing, encrypted_intended_audience, encrypted_key_messages, last_update, user_id, book_id],
        )
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible de mettre à jour la ligne directrice.".to_string() } else { "Unable to update guideline.".to_string() }))?;

    if update_result > 0 {
        Ok(true)
    } else {
        let insert_result = conn
            .execute(
                "INSERT INTO book_guide_line (user_id, book_id, tone, atmosphere, writing_style, themes, symbolism, motifs, narrative_voice, pacing, intended_audience, key_messages, last_update) VALUES (?1,?2,?3,?4,?5,?6,?7,?8,?9,?10,?11,?12,?13)",
                params![user_id, book_id, encrypted_tone, encrypted_atmosphere, encrypted_writing_style, encrypted_themes, encrypted_symbolism, encrypted_motifs, encrypted_narrative_voice, encrypted_pacing, encrypted_intended_audience, encrypted_key_messages, last_update],
            )
            .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible de mettre à jour la ligne directrice.".to_string() } else { "Unable to update guideline.".to_string() }))?;

        Ok(insert_result > 0)
    }
}

/// Inserts or updates an AI guideline for a specific book.
/// If the AI guideline exists, it updates it; otherwise, it inserts a new one.
/// * `conn` - Database connection
/// * `user_id` - The user identifier
/// * `book_id` - The book identifier
/// * `narrative_type` - The narrative type identifier
/// * `dialogue_type` - The dialogue type identifier
/// * `encrypted_plot_summary` - The encrypted plot summary
/// * `encrypted_tone_atmosphere` - The encrypted tone and atmosphere value
/// * `verb_tense` - The verb tense identifier
/// * `language` - The language identifier
/// * `encrypted_themes` - The encrypted themes value
/// * `last_update` - The timestamp of the last update
/// * `lang` - The language for error messages ("fr" or "en")
/// Returns true if the operation was successful.
/// Errors if the AI guideline cannot be inserted or updated.
pub fn insert_ai_guide_line(
    conn: &Connection, user_id: &str, book_id: &str, narrative_type: Option<i64>,
    dialogue_type: Option<i64>, encrypted_plot_summary: Option<&str>,
    encrypted_tone_atmosphere: Option<&str>, verb_tense: Option<i64>,
    language: Option<i64>, encrypted_themes: Option<&str>, last_update: i64, lang: Lang,
) -> AppResult<bool> {
    let update_result = conn
        .execute(
            "UPDATE book_ai_guide_line SET narrative_type=?1, dialogue_type=?2, global_resume=?3, atmosphere=?4, verbe_tense=?5, langue=?6, themes=?7, last_update=?8 WHERE user_id=?9 AND book_id=?10",
            params![narrative_type, dialogue_type, encrypted_plot_summary, encrypted_tone_atmosphere, verb_tense, language, encrypted_themes, last_update, user_id, book_id],
        )
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible d'insérer la ligne directrice IA.".to_string() } else { "Unable to insert AI guideline.".to_string() }))?;

    if update_result > 0 {
        Ok(true)
    } else {
        let insert_result = conn
            .execute(
                "INSERT INTO book_ai_guide_line (user_id, book_id, global_resume, themes, verbe_tense, narrative_type, langue, dialogue_type, tone, atmosphere, current_resume, last_update) VALUES (?1,?2,?3,?4,?5,?6,?7,?8,?9,?10,?11,?12)",
                params![user_id, book_id, encrypted_plot_summary, encrypted_themes, verb_tense, narrative_type, language, dialogue_type, encrypted_tone_atmosphere, encrypted_tone_atmosphere, encrypted_plot_summary, last_update],
            )
            .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible d'insérer la ligne directrice IA.".to_string() } else { "Unable to insert AI guideline.".to_string() }))?;

        Ok(insert_result > 0)
    }
}

/// Fetches the AI guideline for a specific book.
/// * `conn` - Database connection
/// * `user_id` - The user identifier
/// * `book_id` - The book identifier
/// * `lang` - The language for error messages ("fr" or "en")
/// Returns the AI guideline query result.
/// Errors if the AI guideline cannot be retrieved or is not found.
pub fn fetch_guide_line_ai(conn: &Connection, user_id: &str, book_id: &str, lang: Lang) -> AppResult<GuideLineAIQuery> {
    let mut statement = conn
        .prepare("SELECT narrative_type, dialogue_type, global_resume, atmosphere, verbe_tense, langue, themes, current_resume FROM book_ai_guide_line WHERE user_id=?1 AND book_id=?2")
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible de récupérer la ligne directrice IA.".to_string() } else { "Unable to retrieve AI guideline.".to_string() }))?;

    let ai_guideline = statement
        .query_row(params![user_id, book_id], |query_row| {
            Ok(GuideLineAIQuery {
                narrative_type: query_row.get(0)?, dialogue_type: query_row.get(1)?,
                global_resume: query_row.get(2)?, atmosphere: query_row.get(3)?,
                verbe_tense: query_row.get(4)?, langue: query_row.get(5)?,
                themes: query_row.get(6)?, current_resume: query_row.get(7)?,
                _user_id: user_id.to_string(), _book_id: book_id.to_string(),
                _tone: None, _meta: String::new(),
            })
        })
        .map_err(|error| match error {
            rusqlite::Error::QueryReturnedNoRows => AppError::NotFound(if lang == Lang::Fr { "Ligne directrice IA non trouvée.".to_string() } else { "AI guideline not found.".to_string() }),
            _ => AppError::Internal(if lang == Lang::Fr { "Impossible de récupérer la ligne directrice IA.".to_string() } else { "Unable to retrieve AI guideline.".to_string() }),
        })?;

    Ok(ai_guideline)
}

/// Fetches the book AI guideline table data for a specific book.
/// * `conn` - Database connection
/// * `user_id` - The user identifier
/// * `book_id` - The book identifier
/// * `lang` - The language for error messages ("fr" or "en")
/// Returns an array of book AI guideline table entries.
/// Errors if the AI guideline cannot be retrieved.
pub fn fetch_book_ai_guide_line(conn: &Connection, user_id: &str, book_id: &str, lang: Lang) -> AppResult<Vec<BookAIGuideLineTable>> {
    let mut statement = conn
        .prepare("SELECT user_id, book_id, global_resume, themes, verbe_tense, narrative_type, langue, dialogue_type, tone, atmosphere, current_resume, last_update FROM book_ai_guide_line WHERE user_id=?1 AND book_id=?2")
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible de récupérer la ligne directrice IA.".to_string() } else { "Unable to retrieve AI guideline.".to_string() }))?;

    let ai_guidelines = statement
        .query_map(params![user_id, book_id], |query_row| {
            Ok(BookAIGuideLineTable {
                user_id: query_row.get(0)?, book_id: query_row.get(1)?,
                global_resume: query_row.get(2)?, themes: query_row.get(3)?,
                verbe_tense: query_row.get(4)?, narrative_type: query_row.get(5)?,
                langue: query_row.get(6)?, dialogue_type: query_row.get(7)?,
                tone: query_row.get(8)?, atmosphere: query_row.get(9)?,
                current_resume: query_row.get(10)?, last_update: query_row.get(11)?,
            })
        })
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible de récupérer la ligne directrice IA.".to_string() } else { "Unable to retrieve AI guideline.".to_string() }))?
        .collect::<Result<Vec<_>, _>>()
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible de récupérer la ligne directrice IA.".to_string() } else { "Unable to retrieve AI guideline.".to_string() }))?;

    Ok(ai_guidelines)
}

/// Fetches the book guideline table data for a specific book.
/// * `conn` - Database connection
/// * `user_id` - The user identifier
/// * `book_id` - The book identifier
/// * `lang` - The language for error messages ("fr" or "en")
/// Returns an array of book guideline table entries.
/// Errors if the guideline cannot be retrieved.
pub fn fetch_book_guide_line_table(conn: &Connection, user_id: &str, book_id: &str, lang: Lang) -> AppResult<Vec<BookGuideLineTable>> {
    let mut statement = conn
        .prepare("SELECT user_id, book_id, tone, atmosphere, writing_style, themes, symbolism, motifs, narrative_voice, pacing, intended_audience, key_messages, last_update FROM book_guide_line WHERE user_id=?1 AND book_id=?2")
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible de récupérer la ligne directrice.".to_string() } else { "Unable to retrieve guideline.".to_string() }))?;

    let guidelines = statement
        .query_map(params![user_id, book_id], |query_row| {
            Ok(BookGuideLineTable {
                user_id: query_row.get(0)?, book_id: query_row.get(1)?,
                tone: query_row.get(2)?, atmosphere: query_row.get(3)?,
                writing_style: query_row.get(4)?, themes: query_row.get(5)?,
                symbolism: query_row.get(6)?, motifs: query_row.get(7)?,
                narrative_voice: query_row.get(8)?, pacing: query_row.get(9)?,
                intended_audience: query_row.get(10)?, key_messages: query_row.get(11)?,
                last_update: query_row.get(12)?,
            })
        })
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible de récupérer la ligne directrice.".to_string() } else { "Unable to retrieve guideline.".to_string() }))?
        .collect::<Result<Vec<_>, _>>()
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible de récupérer la ligne directrice.".to_string() } else { "Unable to retrieve guideline.".to_string() }))?;

    Ok(guidelines)
}

/// Fetches all synced guidelines for a specific user.
/// * `conn` - Database connection
/// * `user_id` - The user identifier
/// * `lang` - The language for error messages ("fr" or "en")
/// Returns an array of synced guideline results containing book_id and last_update.
/// Errors if the synced guidelines cannot be retrieved.
pub fn fetch_synced_guide_line(conn: &Connection, user_id: &str, lang: Lang) -> AppResult<Vec<SyncedGuideLineResult>> {
    let mut statement = conn
        .prepare("SELECT book_id, last_update FROM book_guide_line WHERE user_id = ?1")
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible de récupérer les lignes directrices synchronisées.".to_string() } else { "Unable to retrieve synced guidelines.".to_string() }))?;

    let synced_guidelines = statement
        .query_map(params![user_id], |query_row| {
            Ok(SyncedGuideLineResult { book_id: query_row.get(0)?, last_update: query_row.get(1)? })
        })
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible de récupérer les lignes directrices synchronisées.".to_string() } else { "Unable to retrieve synced guidelines.".to_string() }))?
        .collect::<Result<Vec<_>, _>>()
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible de récupérer les lignes directrices synchronisées.".to_string() } else { "Unable to retrieve synced guidelines.".to_string() }))?;

    Ok(synced_guidelines)
}

/// Fetches all synced AI guidelines for a specific user.
/// * `conn` - Database connection
/// * `user_id` - The user identifier
/// * `lang` - The language for error messages ("fr" or "en")
/// Returns an array of synced AI guideline results containing book_id and last_update.
/// Errors if the synced AI guidelines cannot be retrieved.
pub fn fetch_synced_ai_guide_line(conn: &Connection, user_id: &str, lang: Lang) -> AppResult<Vec<SyncedAIGuideLineResult>> {
    let mut statement = conn
        .prepare("SELECT book_id, last_update FROM book_ai_guide_line WHERE user_id = ?1")
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible de récupérer les lignes directrices IA synchronisées.".to_string() } else { "Unable to retrieve synced AI guidelines.".to_string() }))?;

    let synced_ai_guidelines = statement
        .query_map(params![user_id], |query_row| {
            Ok(SyncedAIGuideLineResult { book_id: query_row.get(0)?, last_update: query_row.get(1)? })
        })
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible de récupérer les lignes directrices IA synchronisées.".to_string() } else { "Unable to retrieve synced AI guidelines.".to_string() }))?
        .collect::<Result<Vec<_>, _>>()
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible de récupérer les lignes directrices IA synchronisées.".to_string() } else { "Unable to retrieve synced AI guidelines.".to_string() }))?;

    Ok(synced_ai_guidelines)
}

/// Checks if a guideline exists for a specific book.
/// * `conn` - Database connection
/// * `user_id` - The unique identifier of the user
/// * `book_id` - The unique identifier of the book
/// * `lang` - The language for error messages ("fr" or "en")
/// Returns true if the guideline exists, false otherwise.
/// Errors if the existence check fails.
pub fn guide_line_exist(conn: &Connection, user_id: &str, book_id: &str, lang: Lang) -> AppResult<bool> {
    let mut statement = conn
        .prepare("SELECT 1 FROM book_guide_line WHERE user_id=?1 AND book_id=?2")
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible de vérifier l'existence de la ligne directrice.".to_string() } else { "Unable to check guideline existence.".to_string() }))?;

    let exists = statement
        .query_row(params![user_id, book_id], |_query_row| Ok(true))
        .unwrap_or(false);

    Ok(exists)
}

/// Checks if an AI guideline exists for a specific book.
/// * `conn` - Database connection
/// * `user_id` - The unique identifier of the user
/// * `book_id` - The unique identifier of the book
/// * `lang` - The language for error messages ("fr" or "en")
/// Returns true if the AI guideline exists, false otherwise.
/// Errors if the existence check fails.
pub fn ai_guide_line_exist(conn: &Connection, user_id: &str, book_id: &str, lang: Lang) -> AppResult<bool> {
    let mut statement = conn
        .prepare("SELECT 1 FROM book_ai_guide_line WHERE user_id=?1 AND book_id=?2")
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible de vérifier l'existence de la ligne directrice IA.".to_string() } else { "Unable to check AI guideline existence.".to_string() }))?;

    let exists = statement
        .query_row(params![user_id, book_id], |_query_row| Ok(true))
        .unwrap_or(false);

    Ok(exists)
}

/// Inserts a synced AI guideline for a specific book.
/// * `conn` - Database connection
/// * `user_id` - The user identifier
/// * `book_id` - The book identifier
/// * `global_resume` - The global resume value (nullable)
/// * `themes` - The themes value (nullable)
/// * `verbe_tense` - The verb tense identifier (nullable)
/// * `narrative_type` - The narrative type identifier (nullable)
/// * `langue` - The language identifier (nullable)
/// * `dialogue_type` - The dialogue type identifier (nullable)
/// * `tone` - The tone value (nullable)
/// * `atmosphere` - The atmosphere value (nullable)
/// * `current_resume` - The current resume value (nullable)
/// * `last_update` - The last update timestamp
/// * `lang` - The language for error messages ("fr" or "en")
/// Returns true if the insertion was successful.
/// Errors if the AI guideline cannot be inserted.
pub fn insert_sync_ai_guide_line(
    conn: &Connection, user_id: &str, book_id: &str, global_resume: Option<&str>,
    themes: Option<&str>, verbe_tense: Option<i64>, narrative_type: Option<i64>,
    langue: Option<i64>, dialogue_type: Option<i64>, tone: Option<&str>,
    atmosphere: Option<&str>, current_resume: Option<&str>, last_update: i64, lang: Lang,
) -> AppResult<bool> {
    let insert_result = conn
        .execute(
            "INSERT INTO book_ai_guide_line (user_id, book_id, global_resume, themes, verbe_tense, narrative_type, langue, dialogue_type, tone, atmosphere, current_resume, last_update) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)",
            params![user_id, book_id, global_resume, themes, verbe_tense, narrative_type, langue, dialogue_type, tone, atmosphere, current_resume, last_update],
        )
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible d'insérer la ligne directrice IA.".to_string() } else { "Unable to insert AI guideline.".to_string() }))?;

    Ok(insert_result > 0)
}

/// Inserts a synced guideline for a specific book.
/// * `conn` - Database connection
/// * `user_id` - The user identifier
/// * `book_id` - The book identifier
/// * `tone` - The tone value (nullable)
/// * `atmosphere` - The atmosphere value (nullable)
/// * `writing_style` - The writing style value (nullable)
/// * `themes` - The themes value (nullable)
/// * `symbolism` - The symbolism value (nullable)
/// * `motifs` - The motifs value (nullable)
/// * `narrative_voice` - The narrative voice value (nullable)
/// * `pacing` - The pacing value (nullable)
/// * `intended_audience` - The intended audience value (nullable)
/// * `key_messages` - The key messages value (nullable)
/// * `last_update` - The last update timestamp
/// * `lang` - The language for error messages ("fr" or "en")
/// Returns true if the insertion was successful.
/// Errors if the guideline cannot be inserted.
pub fn insert_sync_guide_line(
    conn: &Connection, user_id: &str, book_id: &str, tone: Option<&str>,
    atmosphere: Option<&str>, writing_style: Option<&str>, themes: Option<&str>,
    symbolism: Option<&str>, motifs: Option<&str>, narrative_voice: Option<&str>,
    pacing: Option<&str>, intended_audience: Option<&str>, key_messages: Option<&str>,
    last_update: i64, lang: Lang,
) -> AppResult<bool> {
    let insert_result = conn
        .execute(
            "INSERT INTO book_guide_line (user_id, book_id, tone, atmosphere, writing_style, themes, symbolism, motifs, narrative_voice, pacing, intended_audience, key_messages, last_update) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13)",
            params![user_id, book_id, tone, atmosphere, writing_style, themes, symbolism, motifs, narrative_voice, pacing, intended_audience, key_messages, last_update],
        )
        .map_err(|_| AppError::Internal(if lang == Lang::Fr { "Impossible d'insérer la ligne directrice.".to_string() } else { "Unable to insert guideline.".to_string() }))?;

    Ok(insert_result > 0)
}
