import { QueryInterface, DataTypes } from 'sequelize';

/**
 * Migration: Create dealer_proposal_cost_items table
 * 
 * Purpose: Separate table for cost breakups to enable better querying, reporting, and data integrity
 * This replaces the JSONB costBreakup field in dealer_proposal_details
 * 
 * Benefits:
 * - Better querying and filtering
 * - Easier to update individual cost items
 * - Better for analytics and reporting
 * - Maintains referential integrity
 */
export async function up(queryInterface: QueryInterface): Promise<void> {
  // Check if table already exists
  const [tables] = await queryInterface.sequelize.query(`
    SELECT table_name 
    FROM information_schema.tables 
    WHERE table_schema = 'public' 
    AND table_name = 'dealer_proposal_cost_items';
  `);

  if (tables.length === 0) {
    // Create dealer_proposal_cost_items table
    await queryInterface.createTable('dealer_proposal_cost_items', {
      cost_item_id: {
        type: DataTypes.UUID,
        primaryKey: true,
        defaultValue: DataTypes.UUIDV4,
        field: 'cost_item_id'
      },
      proposal_id: {
        type: DataTypes.UUID,
        allowNull: false,
        field: 'proposal_id',
        references: {
          model: 'dealer_proposal_details',
          key: 'proposal_id'
        },
        onDelete: 'CASCADE',
        onUpdate: 'CASCADE'
      },
      request_id: {
        type: DataTypes.UUID,
        allowNull: false,
        field: 'request_id',
        references: {
          model: 'workflow_requests',
          key: 'request_id'
        },
        onDelete: 'CASCADE',
        onUpdate: 'CASCADE',
        comment: 'Denormalized for easier querying without joins'
      },
      item_description: {
        type: DataTypes.STRING(500),
        allowNull: false,
        field: 'item_description'
      },
      amount: {
        type: DataTypes.DECIMAL(15, 2),
        allowNull: false,
        field: 'amount',
        comment: 'Cost amount in INR'
      },
      item_order: {
        type: DataTypes.INTEGER,
        allowNull: false,
        defaultValue: 0,
        field: 'item_order',
        comment: 'Order of item in the cost breakdown list'
      },
      created_at: {
        type: DataTypes.DATE,
        allowNull: false,
        defaultValue: DataTypes.NOW,
        field: 'created_at'
      },
      updated_at: {
        type: DataTypes.DATE,
        allowNull: false,
        defaultValue: DataTypes.NOW,
        field: 'updated_at'
      }
    });

    // Create indexes for better query performance
    await queryInterface.addIndex('dealer_proposal_cost_items', ['proposal_id'], {
      name: 'idx_proposal_cost_items_proposal_id'
    });

    await queryInterface.addIndex('dealer_proposal_cost_items', ['request_id'], {
      name: 'idx_proposal_cost_items_request_id'
    });

    await queryInterface.addIndex('dealer_proposal_cost_items', ['proposal_id', 'item_order'], {
      name: 'idx_proposal_cost_items_proposal_order'
    });

    console.log('✅ Created dealer_proposal_cost_items table');
  } else {
    console.log('Note: dealer_proposal_cost_items table already exists');
  }

  // Migrate existing JSONB costBreakup data to the new table
  try {
    const [existingProposals] = await queryInterface.sequelize.query(`
      SELECT proposal_id, request_id, cost_breakup
      FROM dealer_proposal_details
      WHERE cost_breakup IS NOT NULL
      AND cost_breakup::text != 'null'
      AND cost_breakup::text != '[]';
    `);

    if (Array.isArray(existingProposals) && existingProposals.length > 0) {
      console.log(`📦 Migrating ${existingProposals.length} existing proposal(s) with cost breakups...`);
      
      for (const proposal of existingProposals as any[]) {
        const proposalId = proposal.proposal_id;
        const requestId = proposal.request_id;
        let costBreakup = proposal.cost_breakup;

        // Parse JSONB if it's a string
        if (typeof costBreakup === 'string') {
          try {
            costBreakup = JSON.parse(costBreakup);
          } catch (e) {
            console.warn(`⚠️ Failed to parse costBreakup for proposal ${proposalId}:`, e);
            continue;
          }
        }

        // Ensure it's an array
        if (!Array.isArray(costBreakup)) {
          console.warn(`⚠️ costBreakup is not an array for proposal ${proposalId}`);
          continue;
        }

        // Insert cost items
        for (let i = 0; i < costBreakup.length; i++) {
          const item = costBreakup[i];
          if (item && item.description && item.amount !== undefined) {
            await queryInterface.sequelize.query(`
              INSERT INTO dealer_proposal_cost_items 
              (proposal_id, request_id, item_description, amount, item_order, created_at, updated_at)
              VALUES (:proposalId, :requestId, :description, :amount, :order, NOW(), NOW())
              ON CONFLICT DO NOTHING;
            `, {
              replacements: {
                proposalId,
                requestId,
                description: item.description,
                amount: item.amount,
                order: i
              }
            });
          }
        }
      }

      console.log('✅ Migrated existing cost breakups to new table');
    }
  } catch (error: any) {
    console.warn('⚠️ Could not migrate existing cost breakups:', error.message);
    // Don't fail the migration if migration of existing data fails
  }
}

export async function down(queryInterface: QueryInterface): Promise<void> {
  // Drop indexes first
  try {
    await queryInterface.removeIndex('dealer_proposal_cost_items', 'idx_proposal_cost_items_proposal_order');
  } catch (e) {
    // Index might not exist
  }

  try {
    await queryInterface.removeIndex('dealer_proposal_cost_items', 'idx_proposal_cost_items_request_id');
  } catch (e) {
    // Index might not exist
  }

  try {
    await queryInterface.removeIndex('dealer_proposal_cost_items', 'idx_proposal_cost_items_proposal_id');
  } catch (e) {
    // Index might not exist
  }

  // Drop table
  await queryInterface.dropTable('dealer_proposal_cost_items');
  console.log('✅ Dropped dealer_proposal_cost_items table');
}

