use crate::website::{Page, WebSite};
use actix_web::{
    get, post, put,
    web::{Data, Json},
    HttpResponse,
};
use std::sync::RwLock;

#[derive(serde::Deserialize, Clone)]
pub struct AddPageData {
    parent_page_id: usize,
    new_page: Page,
}

#[post("/add-page")]
pub async fn add_page(
    website: Data<RwLock<WebSite>>,
    add_page_data: Json<AddPageData>,
) -> HttpResponse {
    let add_page_data = add_page_data.into_inner();
    match website
        .write()
        .expect("Couldn't acquire website write lock")
        .add_page(add_page_data.parent_page_id, add_page_data.new_page.clone())
    {
        Ok(()) => HttpResponse::Ok().finish(),
        Err(msg) => {
            HttpResponse::BadRequest().body(format!("Error adding new page to website - {}", msg))
        }
    }
}

#[get("/page-data/{id}")]
pub async fn get_page_data(
    website: Data<RwLock<WebSite>>,
    id: actix_web::web::Path<usize>,
) -> HttpResponse {
    let id = id.into_inner();
    match website
        .read()
        .expect("Couldn't acquire website read lock")
        .get_page(id)
    {
        Some(page) => HttpResponse::Ok().json(page),
        None => HttpResponse::NotFound().body(format!("Page with id {} was not found", id)),
    }
}

#[put("/update-page/{id}")]
pub async fn update_page(
    id: actix_web::web::Path<usize>,
    website: Data<RwLock<WebSite>>,
    updated_page: Json<Page>,
) -> HttpResponse {
    let id = id.into_inner();
    let updated_page = updated_page.into_inner();
    match website
        .write()
        .expect("Couldn't acquire website write lock")
        .update_page(id, updated_page)
    {
        Ok(page) => HttpResponse::Ok().json(page),
        Err(msg) => {
            HttpResponse::NotFound().body(format!("Error updating page with id {} - {:?}", id, msg))
        }
    }
}