import { QueryInterface, DataTypes } from 'sequelize';

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

/**
 * Migration: Fix column names in claim_invoices and claim_credit_notes tables
 * 
 * This migration handles the case where tables were created with old column names
 * and need to be updated to match the new schema.
 */
export async function up(queryInterface: QueryInterface): Promise<void> {
  try {
    // Check if claim_invoices table exists
    const [invoiceTables] = await queryInterface.sequelize.query(`
      SELECT table_name 
      FROM information_schema.tables 
      WHERE table_schema = 'public' 
      AND table_name = 'claim_invoices';
    `);

    if (invoiceTables.length > 0) {
      // Fix claim_invoices table
      const hasOldAmount = await columnExists(queryInterface, 'claim_invoices', 'amount');
      const hasNewAmount = await columnExists(queryInterface, 'claim_invoices', 'invoice_amount');

      if (hasOldAmount && !hasNewAmount) {
        // Rename amount to invoice_amount
        await queryInterface.renameColumn('claim_invoices', 'amount', 'invoice_amount');
        console.log('✅ Renamed claim_invoices.amount to invoice_amount');
      } else if (!hasOldAmount && !hasNewAmount) {
        // Add invoice_amount if neither exists
        await queryInterface.addColumn('claim_invoices', 'invoice_amount', {
          type: DataTypes.DECIMAL(15, 2),
          allowNull: true,
        });
        console.log('✅ Added invoice_amount column to claim_invoices');
      } else if (hasNewAmount) {
        console.log('✅ invoice_amount column already exists in claim_invoices');
      }

      // Check for status vs generation_status
      const hasStatus = await columnExists(queryInterface, 'claim_invoices', 'status');
      const hasGenerationStatus = await columnExists(queryInterface, 'claim_invoices', 'generation_status');

      if (hasStatus && !hasGenerationStatus) {
        // Rename status to generation_status
        await queryInterface.renameColumn('claim_invoices', 'status', 'generation_status');
        console.log('✅ Renamed claim_invoices.status to generation_status');
      } else if (!hasStatus && !hasGenerationStatus) {
        // Add generation_status if neither exists
        await queryInterface.addColumn('claim_invoices', 'generation_status', {
          type: DataTypes.STRING(50),
          allowNull: true,
        });
        console.log('✅ Added generation_status column to claim_invoices');
      } else if (hasGenerationStatus) {
        console.log('✅ generation_status column already exists in claim_invoices');
      }
    }

    // Check if claim_credit_notes table exists
    const [creditNoteTables] = await queryInterface.sequelize.query(`
      SELECT table_name 
      FROM information_schema.tables 
      WHERE table_schema = 'public' 
      AND table_name = 'claim_credit_notes';
    `);

    if (creditNoteTables.length > 0) {
      // Fix claim_credit_notes table
      const hasOldAmount = await columnExists(queryInterface, 'claim_credit_notes', 'credit_note_amount');
      const hasNewAmount = await columnExists(queryInterface, 'claim_credit_notes', 'credit_amount');

      if (hasOldAmount && !hasNewAmount) {
        // Rename credit_note_amount to credit_amount
        await queryInterface.renameColumn('claim_credit_notes', 'credit_note_amount', 'credit_amount');
        console.log('✅ Renamed claim_credit_notes.credit_note_amount to credit_amount');
      } else if (!hasOldAmount && !hasNewAmount) {
        // Add credit_amount if neither exists
        await queryInterface.addColumn('claim_credit_notes', 'credit_amount', {
          type: DataTypes.DECIMAL(15, 2),
          allowNull: true,
        });
        console.log('✅ Added credit_amount column to claim_credit_notes');
      } else if (hasNewAmount) {
        console.log('✅ credit_amount column already exists in claim_credit_notes');
      }

      // Check for status vs confirmation_status
      const hasStatus = await columnExists(queryInterface, 'claim_credit_notes', 'status');
      const hasConfirmationStatus = await columnExists(queryInterface, 'claim_credit_notes', 'confirmation_status');

      if (hasStatus && !hasConfirmationStatus) {
        // Rename status to confirmation_status
        await queryInterface.renameColumn('claim_credit_notes', 'status', 'confirmation_status');
        console.log('✅ Renamed claim_credit_notes.status to confirmation_status');
      } else if (!hasStatus && !hasConfirmationStatus) {
        // Add confirmation_status if neither exists
        await queryInterface.addColumn('claim_credit_notes', 'confirmation_status', {
          type: DataTypes.STRING(50),
          allowNull: true,
        });
        console.log('✅ Added confirmation_status column to claim_credit_notes');
      } else if (hasConfirmationStatus) {
        console.log('✅ confirmation_status column already exists in claim_credit_notes');
      }

      // Ensure invoice_id column exists
      const hasInvoiceId = await columnExists(queryInterface, 'claim_credit_notes', 'invoice_id');
      if (!hasInvoiceId) {
        await queryInterface.addColumn('claim_credit_notes', 'invoice_id', {
          type: DataTypes.UUID,
          allowNull: true,
          references: {
            model: 'claim_invoices',
            key: 'invoice_id',
          },
          onDelete: 'SET NULL',
          onUpdate: 'CASCADE',
        });
        console.log('✅ Added invoice_id column to claim_credit_notes');
      }

      // Ensure sap_document_number column exists
      const hasSapDoc = await columnExists(queryInterface, 'claim_credit_notes', 'sap_document_number');
      if (!hasSapDoc) {
        await queryInterface.addColumn('claim_credit_notes', 'sap_document_number', {
          type: DataTypes.STRING(100),
          allowNull: true,
        });
        console.log('✅ Added sap_document_number column to claim_credit_notes');
      }

      // Ensure credit_note_file_path column exists
      const hasFilePath = await columnExists(queryInterface, 'claim_credit_notes', 'credit_note_file_path');
      if (!hasFilePath) {
        await queryInterface.addColumn('claim_credit_notes', 'credit_note_file_path', {
          type: DataTypes.STRING(500),
          allowNull: true,
        });
        console.log('✅ Added credit_note_file_path column to claim_credit_notes');
      }

      // Ensure confirmed_by column exists
      const hasConfirmedBy = await columnExists(queryInterface, 'claim_credit_notes', 'confirmed_by');
      if (!hasConfirmedBy) {
        await queryInterface.addColumn('claim_credit_notes', 'confirmed_by', {
          type: DataTypes.UUID,
          allowNull: true,
          references: {
            model: 'users',
            key: 'user_id',
          },
          onDelete: 'SET NULL',
          onUpdate: 'CASCADE',
        });
        console.log('✅ Added confirmed_by column to claim_credit_notes');
      }

      // Ensure confirmed_at column exists
      const hasConfirmedAt = await columnExists(queryInterface, 'claim_credit_notes', 'confirmed_at');
      if (!hasConfirmedAt) {
        await queryInterface.addColumn('claim_credit_notes', 'confirmed_at', {
          type: DataTypes.DATE,
          allowNull: true,
        });
        console.log('✅ Added confirmed_at column to claim_credit_notes');
      }
    }

    // Ensure invoice_file_path exists in claim_invoices
    if (invoiceTables.length > 0) {
      const hasFilePath = await columnExists(queryInterface, 'claim_invoices', 'invoice_file_path');
      if (!hasFilePath) {
        await queryInterface.addColumn('claim_invoices', 'invoice_file_path', {
          type: DataTypes.STRING(500),
          allowNull: true,
        });
        console.log('✅ Added invoice_file_path column to claim_invoices');
      }

      // Ensure error_message exists
      const hasErrorMessage = await columnExists(queryInterface, 'claim_invoices', 'error_message');
      if (!hasErrorMessage) {
        await queryInterface.addColumn('claim_invoices', 'error_message', {
          type: DataTypes.TEXT,
          allowNull: true,
        });
        console.log('✅ Added error_message column to claim_invoices');
      }

      // Ensure generated_at exists
      const hasGeneratedAt = await columnExists(queryInterface, 'claim_invoices', 'generated_at');
      if (!hasGeneratedAt) {
        await queryInterface.addColumn('claim_invoices', 'generated_at', {
          type: DataTypes.DATE,
          allowNull: true,
        });
        console.log('✅ Added generated_at column to claim_invoices');
      }
    }

    // Ensure error_message exists in claim_credit_notes
    if (creditNoteTables.length > 0) {
      const hasErrorMessage = await columnExists(queryInterface, 'claim_credit_notes', 'error_message');
      if (!hasErrorMessage) {
        await queryInterface.addColumn('claim_credit_notes', 'error_message', {
          type: DataTypes.TEXT,
          allowNull: true,
        });
        console.log('✅ Added error_message column to claim_credit_notes');
      }
    }

  } catch (error: any) {
    console.error('Migration error:', error.message);
    throw error;
  }
}

export async function down(queryInterface: QueryInterface): Promise<void> {
  // This migration is idempotent and safe to run multiple times
  // The down migration would reverse the changes, but it's safer to keep the new schema
  console.log('Note: Down migration not implemented - keeping new column names');
}

