use crate::entity::setting;
use actix_web::{web, HttpResponse};
use serde::{Deserialize, Serialize};

use super::api_prelude::*;

#[derive(Debug, Serialize, Deserialize)]
struct ThemeModeResponse {
    mode: String,
}

#[get("theme/mode")]
async fn theme_mode(state: web::Data<AppState>) -> crate::error::Result<HttpResponse> {
    let mode = setting::Entity::find()
        .filter(setting::Column::SettingName.eq("theme_mode".to_string()))
        .one(&state.db)
        .await?
        .map(|r| r.setting_value)
        .unwrap_or_else(|| "dark".to_string());

    Ok(HttpResponse::Ok().json(ThemeModeResponse { mode }))
}

#[derive(Debug, Serialize, Deserialize)]
struct ThemeModeRequest {
    mode: String,
}

#[put("theme/mode")]
async fn update_theme_mode(
    data: web::Json<ThemeModeRequest>,
    state: web::Data<AppState>,
) -> crate::error::Result<HttpResponse> {
    let ThemeModeRequest { mode } = data.0;
    let setting = setting::Entity::find()
        .filter(setting::Column::SettingName.eq("theme_mode".to_string()))
        .one(&state.db)
        .await?;

    if let Some(setting) = setting {
        let rec = setting::ActiveModel {
            id: Set(setting.id),
            setting_value: Set(mode.clone()),
            ..Default::default()
        };
        rec.update(&state.db).await?;
    } else {
        let rec = setting::ActiveModel {
            setting_name: Set("theme_mode".to_string()),
            setting_value: Set(mode.clone()),
            ..Default::default()
        };
        rec.save(&state.db).await?;
    }

    Ok(HttpResponse::Ok().json(ThemeModeResponse { mode }))
}

pub fn routes() -> Scope {
    web::scope("/settings")
        .service(theme_mode)
        .service(update_theme_mode)
}
