import type { QueryInterface } from 'sequelize';
import type { Migration } from '../migrate';

const indexExists = async (table: string, indexName: string, queryInterface: QueryInterface) => {
  const indexes = await queryInterface.showIndex(table);
  return indexes && Array.isArray(indexes) && indexes.some((index: { name: string }) => index.name === indexName);
};

const createIndexIfNotExists = async (
  queryInterface: QueryInterface,
  table: string,
  columns: string[],
  indexName: string
) => {
  if (await indexExists(table, indexName, queryInterface)) {
    /* eslint-disable no-console */
    console.log(`Index ${indexName} already exists on ${table}, skipping...`);
    return;
  }
  await queryInterface.addIndex(table, columns, { name: indexName });
};

export const up: Migration = async ({ context: queryInterface }) => {
  try {
    await createIndexIfNotExists(
      queryInterface,
      'subscriptions',
      ['current_period_start', 'current_period_end'],
      'idx_subscription_period'
    );
    await createIndexIfNotExists(queryInterface, 'subscriptions', ['status'], 'idx_subscription_status');

    await createIndexIfNotExists(
      queryInterface,
      'subscription_items',
      ['subscription_id', 'price_id'],
      'idx_subscription_item_subscription_id_price_id'
    );

    await createIndexIfNotExists(
      queryInterface,
      'invoices',
      ['status', 'collection_method'],
      'idx_invoice_status_collection'
    );
    await createIndexIfNotExists(queryInterface, 'invoices', ['subscription_id'], 'idx_invoice_subscription_id');
    await createIndexIfNotExists(queryInterface, 'invoices', ['currency_id'], 'idx_invoice_currency_id');
    await createIndexIfNotExists(queryInterface, 'invoices', ['customer_id'], 'idx_invoice_customer_id');

    await createIndexIfNotExists(queryInterface, 'payment_intents', ['invoice_id'], 'idx_payment_intent_invoice_id');
    await createIndexIfNotExists(queryInterface, 'payment_intents', ['customer_id'], 'idx_payment_intent_customer_id');
    await createIndexIfNotExists(queryInterface, 'payment_intents', ['currency_id'], 'idx_payment_intent_currency_id');
    await createIndexIfNotExists(
      queryInterface,
      'payment_intents',
      ['status', 'updated_at'],
      'idx_payment_intent_status_updated_at'
    );

    await createIndexIfNotExists(
      queryInterface,
      'webhook_attempts',
      ['webhook_endpoint_id'],
      'idx_webhook_attempts_webhook_endpoint_id'
    );
    await createIndexIfNotExists(queryInterface, 'webhook_attempts', ['event_id'], 'idx_webhook_attempts_event_id');

    await createIndexIfNotExists(
      queryInterface,
      'usage_records',
      ['subscription_item_id', 'timestamp'],
      'idx_usage_records_subscription_item_id_timestamp'
    );

    await createIndexIfNotExists(
      queryInterface,
      'webhook_endpoints',
      ['status', 'livemode'],
      'idx_webhook_endpoint_status_livemode'
    );

    await createIndexIfNotExists(
      queryInterface,
      'payment_stats',
      ['timestamp', 'currency_id'],
      'idx_payment_stats_timestamp_currency_id'
    );

    await createIndexIfNotExists(queryInterface, 'payouts', ['updated_at', 'status'], 'idx_payouts_updated_at_status');

    await createIndexIfNotExists(
      queryInterface,
      'refunds',
      ['status', 'type', 'updated_at'],
      'idx_refunds_status_type_updated_at'
    );
    await createIndexIfNotExists(
      queryInterface,
      'refunds',
      ['subscription_id', 'type'],
      'idx_refunds_subscription_id_type'
    );
    await createIndexIfNotExists(
      queryInterface,
      'refunds',
      ['payment_intent_id', 'type'],
      'idx_refunds_payment_intent_id_type'
    );
  } catch (error) {
    console.error('Failed to create indexes', error);
    throw error;
  }
};
export const down: Migration = async ({ context: queryInterface }) => {
  await queryInterface.removeIndex('subscriptions', 'idx_subscription_period');
  await queryInterface.removeIndex('subscriptions', 'idx_subscription_status');
  await queryInterface.removeIndex('subscription_items', 'idx_subscription_item_subscription_id_price_id');
  await queryInterface.removeIndex('invoices', 'idx_invoice_status_collection');
  await queryInterface.removeIndex('invoices', 'idx_invoice_subscription_id');
  await queryInterface.removeIndex('invoices', 'idx_invoice_currency_id');
  await queryInterface.removeIndex('invoices', 'idx_invoice_customer_id');
  await queryInterface.removeIndex('payment_intents', 'idx_payment_intent_invoice_id');
  await queryInterface.removeIndex('payment_intents', 'idx_payment_intent_customer_id');
  await queryInterface.removeIndex('payment_intents', 'idx_payment_intent_currency_id');
  await queryInterface.removeIndex('payment_intents', 'idx_payment_intent_status_updated_at');
  await queryInterface.removeIndex('webhook_attempts', 'idx_webhook_attempts_webhook_endpoint_id');
  await queryInterface.removeIndex('webhook_attempts', 'idx_webhook_attempts_event_id');
  await queryInterface.removeIndex('usage_records', 'idx_usage_records_subscription_item_id_timestamp');
  await queryInterface.removeIndex('webhook_endpoints', 'idx_webhook_endpoint_status_livemode');
  await queryInterface.removeIndex('payment_stats', 'idx_payment_stats_timestamp_currency_id');
  await queryInterface.removeIndex('payouts', 'idx_payouts_updated_at_status');
  await queryInterface.removeIndex('refunds', 'idx_refunds_status_type_updated_at');
  await queryInterface.removeIndex('refunds', 'idx_refunds_subscription_id_type');
  await queryInterface.removeIndex('refunds', 'idx_refunds_payment_intent_id_type');
};
