'use strict';

module.exports = {
  async up(queryInterface, Sequelize) {
    const salesInvoiceTable = await queryInterface.describeTable('sales_invoice');

    const ensureColumn = async (tableName, tableSchema, columnName, definition) => {
      if (!Object.prototype.hasOwnProperty.call(tableSchema, columnName)) {
        await queryInterface.addColumn(tableName, columnName, definition);
      }
    };

    await ensureColumn('sales_invoice', salesInvoiceTable, 'customer_po_no', {
      type: Sequelize.STRING(50),
      allowNull: true
    });
    await ensureColumn('sales_invoice', salesInvoiceTable, 'sales_order_no', {
      type: Sequelize.STRING(50),
      allowNull: true
    });
    await ensureColumn('sales_invoice', salesInvoiceTable, 'billing_address', {
      type: Sequelize.TEXT,
      allowNull: true
    });
    await ensureColumn('sales_invoice', salesInvoiceTable, 'shipping_address', {
      type: Sequelize.TEXT,
      allowNull: true
    });
    await ensureColumn('sales_invoice', salesInvoiceTable, 'due_date', {
      type: Sequelize.DATEONLY,
      allowNull: true
    });
    await ensureColumn('sales_invoice', salesInvoiceTable, 'gst_type', {
      type: Sequelize.ENUM('CGST_SGST', 'IGST'),
      allowNull: true
    });
    await ensureColumn('sales_invoice', salesInvoiceTable, 'transport_details', {
      type: Sequelize.STRING(255),
      allowNull: true
    });
    await ensureColumn('sales_invoice', salesInvoiceTable, 'dispatched_qty', {
      type: Sequelize.DECIMAL(15, 3),
      allowNull: false,
      defaultValue: 0
    });
    await ensureColumn('sales_invoice', salesInvoiceTable, 'dispatch_status', {
      type: Sequelize.ENUM('NOT_DISPATCHED', 'PARTIALLY_DISPATCHED', 'FULLY_DISPATCHED'),
      allowNull: false,
      defaultValue: 'NOT_DISPATCHED'
    });

    try {
      await queryInterface.changeColumn('sales_invoice', 'status', {
        type: Sequelize.ENUM('DRAFT', 'APPROVED', 'CANCELLED'),
        allowNull: false,
        defaultValue: 'DRAFT'
      });
    } catch (_) {
      // Keep migration resilient across environments where enum alteration differs.
    }

    const fgDispatchTable = await queryInterface.describeTable('fg_dispatch');
    if (!Object.prototype.hasOwnProperty.call(fgDispatchTable, 'invoice_id')) {
      await queryInterface.addColumn('fg_dispatch', 'invoice_id', {
        type: Sequelize.INTEGER,
        allowNull: true,
        references: {
          model: 'sales_invoice',
          key: 'id'
        }
      });
    }

    const dispatchIndexes = await queryInterface.showIndex('fg_dispatch');
    const hasInvoiceIndex = dispatchIndexes.some((idx) => idx.name === 'idx_fg_dispatch_invoice_id');
    if (!hasInvoiceIndex) {
      await queryInterface.addIndex('fg_dispatch', ['invoice_id'], {
        name: 'idx_fg_dispatch_invoice_id'
      });
    }
  },

  async down(queryInterface, Sequelize) {
    const safeRemoveColumn = async (tableName, columnName) => {
      const table = await queryInterface.describeTable(tableName);
      if (Object.prototype.hasOwnProperty.call(table, columnName)) {
        await queryInterface.removeColumn(tableName, columnName);
      }
    };

    const dispatchIndexes = await queryInterface.showIndex('fg_dispatch');
    const hasInvoiceIndex = dispatchIndexes.some((idx) => idx.name === 'idx_fg_dispatch_invoice_id');
    if (hasInvoiceIndex) {
      await queryInterface.removeIndex('fg_dispatch', 'idx_fg_dispatch_invoice_id');
    }
    await safeRemoveColumn('fg_dispatch', 'invoice_id');

    await safeRemoveColumn('sales_invoice', 'dispatch_status');
    await safeRemoveColumn('sales_invoice', 'dispatched_qty');
    await safeRemoveColumn('sales_invoice', 'transport_details');
    await safeRemoveColumn('sales_invoice', 'gst_type');
    await safeRemoveColumn('sales_invoice', 'due_date');
    await safeRemoveColumn('sales_invoice', 'shipping_address');
    await safeRemoveColumn('sales_invoice', 'billing_address');
    await safeRemoveColumn('sales_invoice', 'sales_order_no');
    await safeRemoveColumn('sales_invoice', 'customer_po_no');

    try {
      await queryInterface.changeColumn('sales_invoice', 'status', {
        type: Sequelize.ENUM('DRAFT', 'SUBMITTED', 'POSTED', 'CANCELLED'),
        allowNull: false,
        defaultValue: 'DRAFT'
      });
    } catch (_) {
      // Keep down migration resilient across environments where enum alteration differs.
    }
  }
};
