// src/tables_data/handlers/get_table_data_count.rs
use tonic::Status;
use sqlx::PgPool;
use common::proto::komp_ac::common::CountResponse;
use common::proto::komp_ac::tables_data::GetTableDataCountRequest;
use crate::shared::schema_qualifier::qualify_table_name_for_data; // 1. IMPORT THE FUNCTION

pub async fn get_table_data_count(
    db_pool: &PgPool,
    request: GetTableDataCountRequest,
) -> Result<CountResponse, Status> {
    // We still need to verify that the table is logically defined for the profile.
    // The schema qualifier handles *how* to access it physically, but this check
    // ensures the request is valid in the context of the application's definitions.
    let schema = sqlx::query!(
        "SELECT id FROM schemas WHERE name = $1",
        request.profile_name
    )
    .fetch_optional(db_pool)
    .await
    .map_err(|e| Status::internal(format!("Profile lookup error for '{}': {}", request.profile_name, e)))?;

    let schema_id = match schema {
        Some(p) => p.id,
        None => return Err(Status::not_found(format!("Profile '{}' not found", request.profile_name))),
    };

    let table_defined_for_profile = sqlx::query_scalar!(
        r#"SELECT EXISTS(
            SELECT 1 FROM table_definitions
            WHERE schema_id = $1 AND table_name = $2
        ) AS "exists!" "#,
        schema_id,
        request.table_name
    )
    .fetch_one(db_pool)
    .await
    .map_err(|e| Status::internal(format!("Table definition verification error for '{}.{}': {}", request.profile_name, request.table_name, e)))?;

    if !table_defined_for_profile {
        // If the table isn't even defined for this profile in table_definitions,
        // it's an error, regardless of whether a physical table with that name exists somewhere.
        return Err(Status::not_found(format!(
            "Table '{}' is not defined for profile '{}'",
            request.table_name, request.profile_name
        )));
    }

    // 2. QUALIFY THE TABLE NAME using the imported function
    let qualified_table = qualify_table_name_for_data(
        db_pool,
        &request.profile_name,
        &request.table_name,
    )
    .await?;

    // 3. USE THE QUALIFIED NAME in the SQL query
    let query_sql = format!(
        r#"
        SELECT COUNT(*) AS count
        FROM {}
        WHERE deleted = FALSE
        "#,
        qualified_table
    );

    // The rest of the logic remains largely the same, but error messages can be more specific.
    let count_result = sqlx::query_scalar::<_, Option<i64>>(&query_sql)
        .fetch_one(db_pool)
        .await;

    match count_result {
        Ok(Some(count_val)) => Ok(CountResponse { count: count_val }),
        Ok(None) => {
            // This case should ideally not be reached with COUNT(*),
            // as it always returns a row, even if the count is 0.
            // If it does, it might indicate an issue or an empty table if the query was different.
            // For COUNT(*), a 0 count is expected if no non-deleted rows.
            Ok(CountResponse { count: 0 })
        }
        Err(e) => {
            // Check if the error is "relation does not exist" (PostgreSQL error code 42P01)
            if let Some(db_err) = e.as_database_error() {
                if db_err.code() == Some(std::borrow::Cow::Borrowed("42P01")) {
                    // This means the table (e.g., gen."2025_test_schema3") does not physically exist,
                    // even though it was defined in table_definitions. This is an inconsistency.
                    return Err(Status::internal(format!(
                        "Table '{}' is defined but does not physically exist in the database as {}.",
                        request.table_name, qualified_table
                    )));
                }
            }
            // For other errors, provide a general message.
            Err(Status::internal(format!(
                "Count query failed for table {}: {}",
                qualified_table, e
            )))
        }
    }
}
