import { env as processEnv } from "node:process";
import { Pool } from "pg";

function required(value, fallback) {
  return value || fallback;
}

const pool = processEnv.DATABASE_URL
  ? new Pool({ connectionString: processEnv.DATABASE_URL })
  : new Pool({
      host: required(processEnv.PGHOST, "127.0.0.1"),
      port: Number(required(processEnv.PGPORT, "5432")),
      user: required(processEnv.PGUSER, "postgres"),
      password: processEnv.PGPASSWORD || "",
      database: required(processEnv.PGDATABASE, "qris_soundbox_platform")
    });

async function main() {
  const client = await pool.connect();
  try {
    await client.query("BEGIN");

    const auditTable = await client.query("SELECT to_regclass('public.audit_logs') AS name");
    const idsResult = await client.query(`
      SELECT id FROM transactions WHERE partner_reference LIKE 'PR-%' OR partner_reference LIKE 'DYN-%'
      UNION
      SELECT id FROM devices WHERE device_code LIKE 'DEV-%'
      UNION
      SELECT id FROM merchants WHERE legal_name LIKE 'Smoke Merchant %'
      UNION
      SELECT outlets.id
        FROM outlets
        JOIN merchants ON merchants.id = outlets.merchant_id
       WHERE merchants.legal_name LIKE 'Smoke Merchant %'
      UNION
      SELECT terminals.id
        FROM terminals
        JOIN outlets ON outlets.id = terminals.outlet_id
        JOIN merchants ON merchants.id = outlets.merchant_id
       WHERE merchants.legal_name LIKE 'Smoke Merchant %'
      UNION
      SELECT device_bindings.id
        FROM device_bindings
        JOIN devices ON devices.id = device_bindings.device_id
       WHERE devices.device_code LIKE 'DEV-%'
    `);
    const auditIds = idsResult.rows.map((row) => row.id);
    const auditResult = auditTable.rows[0]?.name && auditIds.length
      ? await client.query("DELETE FROM audit_logs WHERE entity_id = ANY($1::text[])", [auditIds])
      : { rowCount: 0 };
    const txResult = await client.query("DELETE FROM transactions WHERE partner_reference LIKE 'PR-%' OR partner_reference LIKE 'DYN-%' RETURNING id");
    const devResult = await client.query("DELETE FROM devices WHERE device_code LIKE 'DEV-%' RETURNING id");
    const merchantResult = await client.query("DELETE FROM merchants WHERE legal_name LIKE 'Smoke Merchant %' RETURNING id");

    await client.query("COMMIT");

    console.log(JSON.stringify({
      transactions_deleted: txResult.rowCount,
      devices_deleted: devResult.rowCount,
      merchants_deleted: merchantResult.rowCount,
      audit_logs_deleted: auditResult.rowCount,
      note: "outlets/terminals are removed via merchant cascade"
    }));
  } catch (error) {
    await client.query("ROLLBACK");
    console.error("cleanup failed", error instanceof Error ? error.message : String(error));
    process.exitCode = 1;
  } finally {
    client.release();
    await pool.end();
  }
}

main().catch((error) => {
  console.error("cleanup failed", error instanceof Error ? error.message : String(error));
  process.exitCode = 1;
});
