use serde::{Deserialize, Serialize};

use crate::db;

#[derive(Serialize, Clone)]
pub struct Person {
    /// Internal id
    pub person_id: i32,
    /// Country-specific id. For now only supports Peru's DNI.
    ///
    /// Example: `74185293`
    pub person_dni: String,
    /// Names
    ///
    /// Example: `Juan Carlos`
    pub person_names: String,
    /// First surname
    ///
    /// Example: `Perez`
    pub person_paternal_surname: String,
    /// Second surname
    ///
    /// Example: `Gomez`
    pub person_maternal_surname: String,
    /// Id of the online classroom user id linked to this user
    pub person_classroom_id: Option<i32>,
}

impl Person {
    pub fn default() -> Person {
        Person {
            person_id: -1,
            person_dni: "".to_string(),
            person_names: "".to_string(),
            person_paternal_surname: "".to_string(),
            person_maternal_surname: "".to_string(),
            person_classroom_id: None,
        }
    }

    pub async fn get_by_dni(dni: i32) -> Result<Person, sqlx::Error> {
        let db = db();

        let result = sqlx::query_as!(Person, "SELECT * FROM person WHERE person_dni = ?", dni)
            .fetch_one(db)
            .await?;

        Ok(result)
    }
}

#[derive(Deserialize)]
pub struct PersonCreate {
    pub person_dni: String,
    pub person_names: String,
    pub person_paternal_surname: String,
    pub person_maternal_surname: String,
}

impl PersonCreate {
    pub async fn create(&self) -> Result<(), sqlx::Error> {
        let db = db();

        sqlx::query!(
            "INSERT INTO person (person_dni, person_names, person_paternal_surname, person_maternal_surname) VALUES (?, ?, ?, ?)", 
            self.person_dni,
            self.person_names,
            self.person_paternal_surname,
            self.person_maternal_surname,
        )
            .execute(db)
            .await?;

        Ok(())
    }
}
