// src/table_definition/handlers/delete_table.rs
use tonic::Status;
use sqlx::PgPool;
use common::proto::komp_ac::table_definition::{DeleteTableRequest, DeleteTableResponse};

pub async fn delete_table(
    db_pool: &PgPool,
    request: DeleteTableRequest,
) -> Result<DeleteTableResponse, Status> {
    let mut transaction = db_pool.begin().await
        .map_err(|e| Status::internal(format!("Failed to start transaction: {}", e)))?;

    // Step 1: Get schema and validate existence
    let schema = sqlx::query!(
        "SELECT id, name FROM schemas WHERE name = $1",
        request.profile_name
    )
    .fetch_optional(&mut *transaction)
    .await
    .map_err(|e| Status::internal(format!("Schema lookup failed: {}", e)))?;

    let (schema_id, schema_name) = match schema {
        Some(s) => (s.id, s.name),
        None => return Err(Status::not_found("Profile not found")),
    };

    // Step 2: Get table definition and validate existence
    let table_def = sqlx::query!(
        "SELECT id FROM table_definitions
        WHERE schema_id = $1 AND table_name = $2",
        schema_id,
        request.table_name
    )
    .fetch_optional(&mut *transaction)
    .await
    .map_err(|e| Status::internal(format!("Table lookup failed: {}", e)))?;

    let table_def_id = match table_def {
        Some(t) => t.id,
        None => return Err(Status::not_found("Table not found in profile")),
    };

    // Step 3: Drop the actual PostgreSQL table with CASCADE (schema-qualified)
    let drop_table_sql = format!(r#"DROP TABLE IF EXISTS "{}"."{}" CASCADE"#, schema_name, request.table_name);
    sqlx::query(&drop_table_sql)
        .execute(&mut *transaction)
        .await
        .map_err(|e| Status::internal(format!("Table drop failed: {}", e)))?;

    // Step 4: Delete from table_definitions
    sqlx::query!(
        "DELETE FROM table_definitions WHERE id = $1",
        table_def_id
    )
    .execute(&mut *transaction)
    .await
    .map_err(|e| Status::internal(format!("Definition deletion failed: {}", e)))?;

    // Step 5: Check and clean up schema if empty
    let remaining = sqlx::query!(
        "SELECT COUNT(*) as count FROM table_definitions WHERE schema_id = $1",
        schema_id
    )
    .fetch_one(&mut *transaction)
    .await
    .map_err(|e| Status::internal(format!("Count query failed: {}", e)))?;

    if remaining.count.unwrap_or(1) == 0 {
        // Drop the PostgreSQL schema if empty
        let drop_schema_sql = format!(r#"DROP SCHEMA IF EXISTS "{}" CASCADE"#, schema_name);
        sqlx::query(&drop_schema_sql)
            .execute(&mut *transaction)
            .await
            .map_err(|e| Status::internal(format!("Schema drop failed: {}", e)))?;

        // Delete the schema record
        sqlx::query!(
            "DELETE FROM schemas WHERE id = $1",
            schema_id
        )
        .execute(&mut *transaction)
        .await
        .map_err(|e| Status::internal(format!("Schema cleanup failed: {}", e)))?;
    }

    transaction.commit().await
        .map_err(|e| Status::internal(format!("Transaction commit failed: {}", e)))?;

    Ok(DeleteTableResponse {
        success: true,
        message: format!("Table '{}' and its definition were successfully removed", request.table_name),
    })
}
