/**
 * Adds location_id to contract_lines so contract lines can be tagged per client
 * location. PK of contract_lines is (tenant, contract_line_id). Created by
 * 20251008000001_rename_billing_to_contracts.cjs.
 *
 * Follows the Citus-aware conditional FK pattern from
 * 20250613190110_add_location_to_tickets.cjs.
 *
 * @param {import('knex').Knex} knex
 */
exports.up = async function up(knex) {
  await knex.schema.alterTable('contract_lines', (table) => {
    table.uuid('location_id').nullable();
  });

  let clientLocationsDistributed = false;
  let contractLinesDistributed = false;
  let hasCitus = false;

  try {
    const citusCheck = await knex.raw(`
      SELECT EXISTS (
        SELECT 1 FROM pg_extension WHERE extname = 'citus'
      ) as has_citus
    `);
    hasCitus = citusCheck.rows[0].has_citus;

    if (hasCitus) {
      try {
        const locResult = await knex.raw(`
          SELECT EXISTS (
            SELECT 1 FROM pg_dist_partition
            WHERE logicalrelid = 'client_locations'::regclass
          ) as is_distributed
        `);
        clientLocationsDistributed = locResult.rows[0].is_distributed;
      } catch (error) {
        console.log('Error checking client_locations distribution:', error.message);
      }

      try {
        const linesResult = await knex.raw(`
          SELECT EXISTS (
            SELECT 1 FROM pg_dist_partition
            WHERE logicalrelid = 'contract_lines'::regclass
          ) as is_distributed
        `);
        contractLinesDistributed = linesResult.rows[0].is_distributed;
      } catch (error) {
        console.log('Error checking contract_lines distribution:', error.message);
      }
    } else {
      console.log('Citus extension not installed - proceeding with foreign key');
    }
  } catch (error) {
    console.log('Error checking for Citus extension - proceeding with foreign key');
  }

  const compatibleForFk =
    !hasCitus ||
    (!clientLocationsDistributed && !contractLinesDistributed) ||
    (clientLocationsDistributed && contractLinesDistributed);

  if (compatibleForFk) {
    console.log(
      'contract_lines and client_locations are compatible for FK - adding foreign key constraint'
    );
    await knex.schema.alterTable('contract_lines', (table) => {
      // ON UPDATE CASCADE is not supported by Citus when the distribution
      // key (tenant) is part of the FK, so we only set ON DELETE.
      table
        .foreign(['location_id', 'tenant'])
        .references(['location_id', 'tenant'])
        .inTable('client_locations')
        .onDelete('RESTRICT');
    });
  } else {
    console.log(
      'contract_lines and client_locations have incompatible distribution - skipping foreign key, adding index only'
    );
  }

  await knex.schema.alterTable('contract_lines', (table) => {
    table.index(['tenant', 'contract_id', 'location_id'], 'idx_contract_lines_location');
  });
};

/**
 * @param {import('knex').Knex} knex
 */
exports.down = async function down(knex) {
  let clientLocationsDistributed = false;
  let contractLinesDistributed = false;
  let hasCitus = false;
  let shouldDropForeignKey = true;

  try {
    const citusCheck = await knex.raw(`
      SELECT EXISTS (
        SELECT 1 FROM pg_extension WHERE extname = 'citus'
      ) as has_citus
    `);
    hasCitus = citusCheck.rows[0].has_citus;

    if (hasCitus) {
      try {
        const locResult = await knex.raw(`
          SELECT EXISTS (
            SELECT 1 FROM pg_dist_partition
            WHERE logicalrelid = 'client_locations'::regclass
          ) as is_distributed
        `);
        clientLocationsDistributed = locResult.rows[0].is_distributed;
      } catch (error) {
        // Ignore
      }

      try {
        const linesResult = await knex.raw(`
          SELECT EXISTS (
            SELECT 1 FROM pg_dist_partition
            WHERE logicalrelid = 'contract_lines'::regclass
          ) as is_distributed
        `);
        contractLinesDistributed = linesResult.rows[0].is_distributed;
      } catch (error) {
        // Ignore
      }

      shouldDropForeignKey =
        (!clientLocationsDistributed && !contractLinesDistributed) ||
        (clientLocationsDistributed && contractLinesDistributed);
    }
  } catch (error) {
    // pg_dist_partition doesn't exist: FK was created.
  }

  await knex.schema.alterTable('contract_lines', (table) => {
    table.dropIndex(['tenant', 'contract_id', 'location_id'], 'idx_contract_lines_location');
    if (shouldDropForeignKey) {
      table.dropForeign(['location_id', 'tenant']);
    }
    table.dropColumn('location_id');
  });
};
