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;
    }
}

export async function up(queryInterface: QueryInterface): Promise<void> {
    // 1. ActivityType
    const activityCols = {
        hsn_code: { type: DataTypes.STRING(20), allowNull: true },
        sac_code: { type: DataTypes.STRING(20), allowNull: true },
        gst_rate: { type: DataTypes.DECIMAL(5, 2), allowNull: true },
        gl_code: { type: DataTypes.STRING(20), allowNull: true },
        credit_nature: { type: DataTypes.STRING(50), allowNull: true }
    };

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

    // 2. GST Fields mapping for Multiple Tables
    const gstFields = {
        gst_rate: { type: DataTypes.DECIMAL(5, 2), allowNull: true },
        gst_amt: { type: DataTypes.DECIMAL(15, 2), allowNull: true },
        cgst_rate: { type: DataTypes.DECIMAL(5, 2), allowNull: true },
        cgst_amt: { type: DataTypes.DECIMAL(15, 2), allowNull: true },
        sgst_rate: { type: DataTypes.DECIMAL(5, 2), allowNull: true },
        sgst_amt: { type: DataTypes.DECIMAL(15, 2), allowNull: true },
        igst_rate: { type: DataTypes.DECIMAL(5, 2), allowNull: true },
        igst_amt: { type: DataTypes.DECIMAL(15, 2), allowNull: true },
        utgst_rate: { type: DataTypes.DECIMAL(5, 2), allowNull: true },
        utgst_amt: { type: DataTypes.DECIMAL(15, 2), allowNull: true },
        cess_rate: { type: DataTypes.DECIMAL(5, 2), allowNull: true },
        cess_amt: { type: DataTypes.DECIMAL(15, 2), allowNull: true },
        total_amt: { type: DataTypes.DECIMAL(15, 2), allowNull: true },
    };

    const tables = ['dealer_proposal_cost_items', 'dealer_completion_expenses', 'claim_credit_notes'];

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

    // Add missing expense_date to DealerCompletionExpense
    if (!(await columnExists(queryInterface, 'dealer_completion_expenses', 'expense_date'))) {
        await queryInterface.addColumn('dealer_completion_expenses', 'expense_date', { type: DataTypes.DATEONLY, allowNull: true });
    }

    // 3. ClaimInvoice
    const invoiceCols = {
        irn: { type: DataTypes.STRING(500), allowNull: true },
        ack_no: { type: DataTypes.STRING(255), allowNull: true },
        ack_date: { type: DataTypes.DATE, allowNull: true },
        signed_invoice: { type: DataTypes.TEXT, allowNull: true },
        signed_invoice_url: { type: DataTypes.STRING(500), allowNull: true },
        dealer_claim_number: { type: DataTypes.STRING(100), allowNull: true },
        qr_code: { type: DataTypes.TEXT, allowNull: true },
        qr_image: { type: DataTypes.TEXT, allowNull: true },
        dealer_claim_date: { type: DataTypes.DATEONLY, allowNull: true },
        billing_no: { type: DataTypes.STRING(100), allowNull: true },
        billing_date: { type: DataTypes.DATEONLY, allowNull: true },
        taxable_value: { type: DataTypes.DECIMAL(15, 2), allowNull: true },
        cgst_total: { type: DataTypes.DECIMAL(15, 2), allowNull: true },
        sgst_total: { type: DataTypes.DECIMAL(15, 2), allowNull: true },
        igst_total: { type: DataTypes.DECIMAL(15, 2), allowNull: true },
        utgst_total: { type: DataTypes.DECIMAL(15, 2), allowNull: true },
        cess_total: { type: DataTypes.DECIMAL(15, 2), allowNull: true },
        tcs_amt: { type: DataTypes.DECIMAL(15, 2), allowNull: true },
        round_off_amt: { type: DataTypes.DECIMAL(15, 2), allowNull: true },
        place_of_supply: { type: DataTypes.STRING(255), allowNull: true },
        total_value_in_words: { type: DataTypes.STRING(500), allowNull: true },
        tax_value_in_words: { type: DataTypes.STRING(500), allowNull: true },
        credit_nature: { type: DataTypes.STRING(100), allowNull: true },
        consignor_gsin: { type: DataTypes.STRING(255), allowNull: true },
        gstin_date: { type: DataTypes.DATEONLY, allowNull: true }
    };

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

    // Ensure file_path exists as 'file_path'
    try {
        if (!(await columnExists(queryInterface, 'claim_invoices', 'file_path'))) {
            if (await columnExists(queryInterface, 'claim_invoices', 'invoice_file_path')) {
                await queryInterface.renameColumn('claim_invoices', 'invoice_file_path', 'file_path');
            } else {
                await queryInterface.addColumn('claim_invoices', 'file_path', { type: DataTypes.STRING(500), allowNull: true });
            }
        }
    } catch (e) {
        // Silently continue
    }
}

export async function down(queryInterface: QueryInterface): Promise<void> {
    // Note: Best effort rollback (usually not recommended to drop columns in shared dev unless necessary)
    await queryInterface.removeColumn('dealer_completion_expenses', 'expense_date').catch(() => { });
}
