import dotenv from 'dotenv';
import fs from 'fs';
import path from 'path';

// Load .env variables
const envPath = path.resolve(process.cwd(), '.env');
if (fs.existsSync(envPath)) {
  dotenv.config({ path: envPath });
}

const HASURA_ADMIN_SECRET = process.env.HASURA_ADMIN_SECRET || 'nearle-admin-secret';
const HASURA_QUERY_URL = 'https://api.workolik.com/v2/query';
const HASURA_METADATA_URL = 'https://api.workolik.com/v1/metadata';

let sourceName = 'default';

async function getSourceName() {
  const response = await fetch(HASURA_METADATA_URL, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-hasura-admin-secret': HASURA_ADMIN_SECRET,
    },
    body: JSON.stringify({
      type: 'export_metadata',
      args: {}
    }),
  });
  
  const data = await response.json();
  if (data.error) {
    throw new Error(`Hasura Metadata Error: ${data.error}`);
  }
  
  if (data.sources && data.sources.length > 0) {
    return data.sources[0].name;
  }
  return 'default';
}

async function runSql(sqlQuery) {
  const response = await fetch(HASURA_QUERY_URL, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-hasura-admin-secret': HASURA_ADMIN_SECRET,
    },
    body: JSON.stringify({
      type: 'run_sql',
      args: {
        source: sourceName,
        sql: sqlQuery,
        cascade: false,
        check_metadata_consistency: false,
      },
    }),
  });

  const data = await response.json();
  if (data.error) {
    throw new Error(`Hasura SQL Error: ${data.error}`);
  }
  return data;
}

async function main() {
  try {
    console.log('🔄 Connecting to Hasura Database...');
    sourceName = await getSourceName();
    console.log(`✅ Using database source: "${sourceName}"`);

    // 1. Let's introspect the tables to ensure we have the correct table names before running the trigger.
    const targetTables = ['orders', 'orderdetails', 'productstocks'];
    const columnsCheckSql = `
      SELECT table_name, column_name 
      FROM information_schema.columns 
      WHERE table_schema = 'public' 
      AND table_name IN ('orders', 'orderdetails', 'productstocks');
    `;
    
    console.log('🔍 Introspecting columns for orders, orderdetails, productstocks...');
    const colData = await runSql(columnsCheckSql);
    const cols = colData.result.slice(1);
    
    const getCols = (table) => cols.filter(r => r[0] === table).map(r => r[1]);
    const ordersCols = getCols('orders');
    const orderDetailsCols = getCols('orderdetails');
    const productStockCols = getCols('productstocks');
    
    console.log(`✅ orders columns: ${ordersCols.join(', ')}`);
    console.log(`✅ orderdetails columns: ${orderDetailsCols.join(', ')}`);
    console.log(`✅ productstocks columns: ${productStockCols.join(', ')}`);
    
    // Determine exact column names
    const orderPk = ordersCols.includes('orderheaderid') ? 'orderheaderid' : 'orderid';
    const detailOrderId = orderDetailsCols.includes('orderheaderid') ? 'orderheaderid' : 'orderid';
    const qtyCol = orderDetailsCols.includes('qty') ? 'qty' : 'orderqty';
    const stockCol = productStockCols.includes('physicalstock') ? 'physicalstock' : (productStockCols.includes('closing') ? 'closing' : 'stock');

    // 2. Define the SQL for the Trigger Functions
    console.log('🛠️ Creating trigger functions...');

    const createTriggerSql = `
      -- Function to reduce stock when a new order detail is inserted
      CREATE OR REPLACE FUNCTION update_stock_on_order_insert()
      RETURNS trigger AS $$
      DECLARE
         v_locationid INT;
      BEGIN
         -- Try to fetch locationid from orders
         BEGIN
             SELECT locationid INTO v_locationid FROM orders WHERE ${orderPk} = NEW.${detailOrderId};
         EXCEPTION WHEN OTHERS THEN
             v_locationid := NULL;
         END;
         
         IF v_locationid IS NOT NULL THEN
             UPDATE productstocks
             SET ${stockCol} = GREATEST(0, COALESCE(${stockCol}, 0) - COALESCE(NEW.${qtyCol}, 1))
             WHERE productid = NEW.productid AND locationid = v_locationid;
         END IF;

         RETURN NEW;
      END;
      $$ LANGUAGE plpgsql;

      -- Create the trigger on orderdetails table
      DROP TRIGGER IF EXISTS trigger_reduce_stock_on_order ON orderdetails;
      CREATE TRIGGER trigger_reduce_stock_on_order
      AFTER INSERT ON orderdetails
      FOR EACH ROW
      EXECUTE FUNCTION update_stock_on_order_insert();
    `;

    console.log('Deploying trigger...');
    await runSql(createTriggerSql);
    console.log('✅ Stock Reduction Trigger successfully deployed!');
    
    console.log('🎉 Setup complete. The database will now automatically reduce physicalstock when an order is created.');
    
  } catch (error) {
    console.error('❌ Error executing deployment script:');
    console.error(error.message);
  }
}

main();
