use cfg_if::cfg_if;
use leptos::*;
use validator::Validate;
use crate::backend::data::{ApiResponse, Company};
use crate::components::data_form::ForValidation;

cfg_if! { if #[cfg(feature = "ssr")] {
    use sqlx::{query_as, PgPool, query};
    use crate::error::AppError;
    use crate::backend::get_pool;
    use log::info;

    pub async fn check_company(pool: &PgPool) -> Result<(), AppError> {
        let count: (i64,) = query_as("SELECT COUNT(id) FROM company")
            .fetch_one(pool)
            .await?;

        if count.0 == 0 {
            info!("Creating initial company");
            query("INSERT INTO company(name, street, house_number, zip_code, city) VALUES('Company name', '', '', '', '')")
                .execute(pool).await?;
        }

        Ok(())
    }
}}

#[server(GetCompany, "/api", "Url", "get_company")]
pub async fn get_company() -> Result<ApiResponse<Company>, ServerFnError> {
    use crate::perm_check;

    perm_check!(is_logged_in);

    let pool = get_pool().await?;

    let cmp = sqlx::query_as::<_, Company>("SELECT * FROM company")
        .fetch_one(&pool)
        .await?;

    Ok(ApiResponse::Data(cmp))
}

#[server(UpdateCompany, "/api", "Url", "update_company")]
pub async fn update_company(company: Company) -> Result<ApiResponse<()>, ServerFnError> {
    use crate::perm_check;

    perm_check!(is_admin);

    let pool = get_pool().await?;

    sqlx::query(
        "UPDATE company SET name = $1, street = $2, house_number = $3, zip_code = $4, city = $5 \
        WHERE id = $6")
    .bind(company.name.clone())
    .bind(company.street.clone())
    .bind(company.house_number.clone())
    .bind(company.zip_code.clone())
    .bind(company.city.clone())
    .bind(company.id())
    .execute(&pool)
    .await?;

    Ok(ApiResponse::Data(()))
}

impl ForValidation for UpdateCompany {
    fn entity(&self) -> &dyn Validate {
        &self.company
    }
}