/**
 * Add ocr_extracted_data (JSONB) to form16a_submissions for audit/support.
 * Stores the raw OCR response when a submission is created from an extracted PDF.
 *
 * If form16a_submissions does not exist (e.g. 20260220-create-form16-tables was marked
 * run but used the wrong module on a previous deploy), this migration creates the table
 * and form_16_credit_notes first, then adds the column. Safe for UAT/fresh DBs.
 */

import { QueryInterface, DataTypes } from 'sequelize';

async function tableExists(queryInterface: QueryInterface, tableName: string): Promise<boolean> {
  const [rows] = await queryInterface.sequelize.query(
    `SELECT EXISTS (
      SELECT 1 FROM information_schema.tables
      WHERE table_schema = 'public' AND table_name = :tableName
    ) AS "exists"`,
    { replacements: { tableName } }
  );
  const val = (rows as { exists: boolean | string }[])?.[0]?.exists;
  return val === true || val === 't';
}

async function columnExists(queryInterface: QueryInterface, tableName: string, columnName: string): Promise<boolean> {
  const [rows] = await queryInterface.sequelize.query(
    `SELECT EXISTS (
      SELECT 1 FROM information_schema.columns
      WHERE table_schema = 'public' AND table_name = :tableName AND column_name = :columnName
    ) AS "exists"`,
    { replacements: { tableName, columnName } }
  );
  const val = (rows as { exists: boolean | string }[])?.[0]?.exists;
  return val === true || val === 't';
}

/** Create form16a_submissions and form_16_credit_notes if missing (same as 20260220-create-form16-tables). */
async function ensureForm16Tables(queryInterface: QueryInterface): Promise<void> {
  const exists = await tableExists(queryInterface, 'form16a_submissions');
  if (exists) return;

  await queryInterface.createTable('form16a_submissions', {
    id: {
      type: DataTypes.INTEGER,
      primaryKey: true,
      autoIncrement: true,
    },
    request_id: {
      type: DataTypes.UUID,
      allowNull: false,
      references: { model: 'workflow_requests', key: 'request_id' },
      onDelete: 'CASCADE',
      unique: true,
    },
    dealer_code: {
      type: DataTypes.STRING(50),
      allowNull: false,
    },
    form16a_number: {
      type: DataTypes.STRING(50),
      allowNull: false,
      unique: true,
    },
    financial_year: {
      type: DataTypes.STRING(20),
      allowNull: false,
    },
    quarter: {
      type: DataTypes.STRING(10),
      allowNull: false,
    },
    version: {
      type: DataTypes.INTEGER,
      allowNull: false,
      defaultValue: 1,
    },
    tds_amount: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: false,
    },
    total_amount: {
      type: DataTypes.DECIMAL(15, 2),
      allowNull: false,
    },
    tan_number: {
      type: DataTypes.STRING(20),
      allowNull: false,
    },
    deductor_name: {
      type: DataTypes.STRING(255),
      allowNull: false,
    },
    document_url: {
      type: DataTypes.TEXT,
      allowNull: true,
    },
    status: {
      type: DataTypes.STRING(20),
      allowNull: false,
      defaultValue: 'pending',
    },
    validation_status: {
      type: DataTypes.STRING(20),
      allowNull: true,
    },
    validation_notes: {
      type: DataTypes.TEXT,
      allowNull: true,
    },
    submitted_date: {
      type: DataTypes.DATE,
      allowNull: true,
    },
    processed_date: {
      type: DataTypes.DATE,
      allowNull: true,
    },
    processed_by: {
      type: DataTypes.UUID,
      allowNull: true,
      references: { model: 'users', key: 'user_id' },
    },
    created_at: {
      type: DataTypes.DATE,
      allowNull: false,
      defaultValue: DataTypes.NOW,
    },
    updated_at: {
      type: DataTypes.DATE,
      allowNull: false,
      defaultValue: DataTypes.NOW,
    },
  });

  await queryInterface.addIndex('form16a_submissions', ['request_id'], { name: 'idx_form16a_submissions_request_id' });
  await queryInterface.addIndex('form16a_submissions', ['dealer_code'], { name: 'idx_form16a_submissions_dealer_code' });
  await queryInterface.addIndex('form16a_submissions', ['status'], { name: 'idx_form16a_submissions_status' });
  await queryInterface.addIndex('form16a_submissions', ['financial_year', 'quarter'], { name: 'idx_form16a_submissions_fy_quarter' });

  if (!(await tableExists(queryInterface, 'form_16_credit_notes'))) {
    await queryInterface.createTable('form_16_credit_notes', {
      id: {
        type: DataTypes.INTEGER,
        primaryKey: true,
        autoIncrement: true,
      },
      submission_id: {
        type: DataTypes.INTEGER,
        allowNull: false,
        references: { model: 'form16a_submissions', key: 'id' },
        onDelete: 'CASCADE',
      },
      credit_note_number: {
        type: DataTypes.STRING(50),
        allowNull: false,
        unique: true,
      },
      sap_document_number: {
        type: DataTypes.STRING(50),
        allowNull: true,
      },
      amount: {
        type: DataTypes.DECIMAL(15, 2),
        allowNull: false,
      },
      issue_date: {
        type: DataTypes.DATEONLY,
        allowNull: false,
      },
      financial_year: {
        type: DataTypes.STRING(20),
        allowNull: false,
      },
      quarter: {
        type: DataTypes.STRING(10),
        allowNull: false,
      },
      status: {
        type: DataTypes.STRING(20),
        allowNull: false,
        defaultValue: 'pending',
      },
      remarks: {
        type: DataTypes.TEXT,
        allowNull: true,
      },
      issued_by: {
        type: DataTypes.UUID,
        allowNull: true,
        references: { model: 'users', key: 'user_id' },
      },
      created_at: {
        type: DataTypes.DATE,
        allowNull: false,
        defaultValue: DataTypes.NOW,
      },
      updated_at: {
        type: DataTypes.DATE,
        allowNull: false,
        defaultValue: DataTypes.NOW,
      },
    });
    await queryInterface.addIndex('form_16_credit_notes', ['submission_id'], { name: 'idx_form_16_credit_notes_submission_id' });
    await queryInterface.addIndex('form_16_credit_notes', ['status'], { name: 'idx_form_16_credit_notes_status' });
  }
}

export async function up(queryInterface: QueryInterface): Promise<void> {
  await ensureForm16Tables(queryInterface);

  const hasColumn = await columnExists(queryInterface, 'form16a_submissions', 'ocr_extracted_data');
  if (!hasColumn) {
    await queryInterface.addColumn(
      'form16a_submissions',
      'ocr_extracted_data',
      {
        type: DataTypes.JSONB,
        allowNull: true,
      }
    );
  }
}

export async function down(queryInterface: QueryInterface): Promise<void> {
  const hasColumn = await columnExists(queryInterface, 'form16a_submissions', 'ocr_extracted_data');
  if (hasColumn) {
    await queryInterface.removeColumn('form16a_submissions', 'ocr_extracted_data');
  }
}
