use super::{RpcHandler, DEV_DEFAULT_PASSWORD};
use anyhow::Result;

impl RpcHandler {
    pub(super) async fn handle_auth_login(
        &self,
        params: Option<serde_json::Value>,
    ) -> Result<serde_json::Value> {
        let params = params.ok_or_else(|| anyhow::anyhow!("Missing params"))?;
        let password = params
            .get("password")
            .and_then(|v| v.as_str())
            .ok_or_else(|| anyhow::anyhow!("Missing password"))?;

        let is_setup = self.auth_manager.is_setup().await?;
        if !is_setup {
            // Dev mode: allow default password so UI can log in without running setup
            if self.config.dev_mode && password == DEV_DEFAULT_PASSWORD {
                return Ok(serde_json::Value::Null);
            }
            return Err(anyhow::anyhow!(
                "User not set up. Please complete setup first."
            ));
        }

        let valid = self.auth_manager.verify_password(password).await?;
        if !valid {
            return Err(anyhow::anyhow!("Password Incorrect"));
        }

        Ok(serde_json::Value::Null)
    }

    pub(super) async fn handle_auth_logout(&self) -> Result<serde_json::Value> {
        Ok(serde_json::Value::Null)
    }

    pub(super) async fn handle_auth_change_password(
        &self,
        params: Option<serde_json::Value>,
    ) -> Result<serde_json::Value> {
        let params = params.ok_or_else(|| anyhow::anyhow!("Missing params"))?;
        let current_password = params
            .get("currentPassword")
            .and_then(|v| v.as_str())
            .ok_or_else(|| anyhow::anyhow!("Missing currentPassword"))?;
        let new_password = params
            .get("newPassword")
            .and_then(|v| v.as_str())
            .ok_or_else(|| anyhow::anyhow!("Missing newPassword"))?;
        let also_change_ssh = params
            .get("alsoChangeSsh")
            .and_then(|v| v.as_bool())
            .unwrap_or(true);

        self.auth_manager
            .change_password(current_password, new_password, also_change_ssh)
            .await?;

        Ok(serde_json::json!({ "success": true }))
    }

    pub(super) async fn handle_auth_onboarding_complete(&self) -> Result<serde_json::Value> {
        self.auth_manager.complete_onboarding().await?;
        Ok(serde_json::json!(true))
    }

    pub(super) async fn handle_auth_is_onboarding_complete(&self) -> Result<serde_json::Value> {
        let complete = self.auth_manager.is_onboarding_complete().await?;
        Ok(serde_json::json!(complete))
    }

    pub(super) async fn handle_auth_reset_onboarding(&self) -> Result<serde_json::Value> {
        self.auth_manager.reset_onboarding().await?;
        Ok(serde_json::json!(true))
    }
}
