import { QueryInterface, DataTypes } from 'sequelize';

/**
 * Helper: returns true if the column exists in the table
 */
async function columnExists(
  queryInterface: QueryInterface,
  tableName: string,
  columnName: string
): Promise<boolean> {
  try {
    const description = await queryInterface.describeTable(tableName);
    return columnName in description;
  } catch {
    return false;
  }
}

/**
 * Migration: Refactor activity_types table
 *
 * Drops deprecated columns that will not be used going forward:
 *   hsn_code, sac_code, gst_rate, gl_code, credit_nature
 *
 * Adds new column:
 *   credit_posting_on  VARCHAR(50)  – indicates posting target (e.g. 'Spares', 'Vehicle')
 *
 * All drops are guarded so this migration is safe to run on a fresh database
 * where these columns were never added.
 */
export async function up(queryInterface: QueryInterface): Promise<void> {
  const TABLE = 'activity_types';

  // ── Drop deprecated columns (safe: only if they exist) ──────────────────────
  const columnsToDrop = ['hsn_code', 'sac_code', 'gst_rate', 'gl_code', 'credit_nature'];

  for (const col of columnsToDrop) {
    if (await columnExists(queryInterface, TABLE, col)) {
      await queryInterface.removeColumn(TABLE, col);
      console.log(`[Migration] Dropped column ${TABLE}.${col}`);
    } else {
      console.log(`[Migration] Column ${TABLE}.${col} does not exist – skipping drop`);
    }
  }

  // ── Add new column ────────────────────────────────────────────────────────────
  if (!(await columnExists(queryInterface, TABLE, 'credit_posting_on'))) {
    await queryInterface.addColumn(TABLE, 'credit_posting_on', {
      type: DataTypes.STRING(50),
      allowNull: true,
      defaultValue: null,
      comment: 'Indicates what the credit note is posted against (e.g. "Spares", "Vehicle")'
    });
    console.log(`[Migration] Added column ${TABLE}.credit_posting_on`);
  } else {
    console.log(`[Migration] Column ${TABLE}.credit_posting_on already exists – skipping add`);
  }
}

/**
 * Rollback: re-add the dropped columns and remove credit_posting_on.
 * Columns are restored as nullable so existing rows are unaffected.
 */
export async function down(queryInterface: QueryInterface): Promise<void> {
  const TABLE = 'activity_types';

  // Remove the newly added column
  if (await columnExists(queryInterface, TABLE, 'credit_posting_on')) {
    await queryInterface.removeColumn(TABLE, 'credit_posting_on');
  }

  // Restore dropped columns
  const columnsToRestore: Record<string, any> = {
    hsn_code: { type: DataTypes.STRING(20), allowNull: true, defaultValue: null },
    sac_code: { type: DataTypes.STRING(20), allowNull: true, defaultValue: null },
    gst_rate: { type: DataTypes.DECIMAL(5, 2), allowNull: true, defaultValue: null },
    gl_code: { type: DataTypes.STRING(20), allowNull: true, defaultValue: null },
    credit_nature: { type: DataTypes.STRING(50), allowNull: true, defaultValue: null }
  };

  for (const [col, spec] of Object.entries(columnsToRestore)) {
    if (!(await columnExists(queryInterface, TABLE, col))) {
      await queryInterface.addColumn(TABLE, col, spec);
    }
  }
}
