import * as fs from 'fs';
import * as path from 'path';
import { getPgPool } from '../lib/postgres/client';
import { runMigrations } from '../lib/postgres/migrations';
import {
  pgSaveCustomers,
  pgSaveSuppliers,
  pgSaveMaterials,
  pgSaveExpenses,
  pgSaveProductShapeDefinitions,
  pgSaveSalesReps,
  pgSaveManagedUnits,
  pgSaveItemGroups,
  pgSaveWarehouses,
  pgSaveBanks,
  pgSaveCustomerPricing,
  pgSaveItemUnits,
  pgSaveInternalTransfers,
  pgSaveInventoryMovements,
  pgSaveCustomerCategories,
  pgSaveParties,
  pgSaveChartOfAccounts,
  pgSaveChecksIssued,
  pgSaveChecksReceived,
  pgSaveCurrencies,
  pgSaveDailyExchangeRates,
  pgSaveEmployees,
  pgSaveExchangeRateSources,
  pgSaveInternalTransferDocs,
  pgSaveJournalEntries,
  pgSavePayments,
  pgSaveProductionReports,
  pgSavePurchaseCreditNotes,
  pgSavePurchaseReturns,
  pgSaveShiftOverrides,
  pgSaveShipmentSequences,
  pgSaveShipments,
  pgSaveSupplierPaymentLocks,
  pgSaveSupplierPayments,
  pgSaveTransferLocks,
  pgSaveSequenceCounters,
  pgSaveInvoices,
  pgSavePurchaseOrders,
  pgSaveSettings,
} from '../lib/postgres/data-access';
import { upsertJsonStore } from '../lib/postgres/repositories';

const dbPath = path.join(process.cwd(), 'db');

function readJson<T>(fileName: string, fallback: T): T {
  const filePath = path.join(dbPath, fileName);
  if (!fs.existsSync(filePath)) return fallback;
  try {
    const raw = fs.readFileSync(filePath, 'utf-8');
    if (!raw.trim()) return fallback;
    return JSON.parse(raw) as T;
  } catch {
    return fallback;
  }
}

async function main() {
  await runMigrations();

  const settings = readJson<Record<string, unknown>>('settings.json', {});
  const customers = readJson<Array<Record<string, unknown>>>('customers.json', []);
  const suppliers = readJson<Array<Record<string, unknown>>>('suppliers.json', []);
  const materials = readJson<Array<Record<string, unknown>>>('materials.json', []);
  const expenses = readJson<Array<Record<string, unknown>>>('expenses.json', []);
  const productShapes = readJson<Array<Record<string, unknown>>>('product_shape_definitions.json', []);
  const salesReps = readJson<Array<Record<string, unknown>>>('sales_reps.json', []);
  const managedUnits = readJson<Array<Record<string, unknown>>>('managed_units.json', []);
  const itemGroups = readJson<Array<Record<string, unknown>>>('item_groups.json', []);
  const warehouses = readJson<Array<Record<string, unknown>>>('warehouses.json', []);
  const banks = readJson<Array<Record<string, unknown>>>('banks.json', []);
  const customerPricing = readJson<Array<Record<string, unknown>>>('customer_pricing.json', []);
  const itemUnits = readJson<Array<Record<string, unknown>>>('item_units.json', []);
  const internalTransfers = readJson<Array<Record<string, unknown>>>('internal_transfers.json', []);
  const inventoryMovements = readJson<Array<Record<string, unknown>>>('inventory_movements.json', []);
  const customerCategories = readJson<Array<Record<string, unknown>>>('customer_categories.json', []);
  const parties = readJson<Array<Record<string, unknown>>>('parties.json', []);
  const chartOfAccounts = readJson<unknown>('chart_of_accounts.json', []);
  const checksIssued = readJson<unknown>('checks_issued.json', []);
  const checksReceived = readJson<unknown>('checks_received.json', []);
  const currencies = readJson<unknown>('currencies.json', []);
  const dailyExchangeRates = readJson<unknown>('daily_exchange_rates.json', []);
  const employees = readJson<unknown>('employees.json', []);
  const exchangeRateSources = readJson<unknown>('exchange_rate_sources.json', []);
  const internalTransferDocs = readJson<unknown>('internal_transfer_docs.json', []);
  const journalEntries = readJson<unknown>('journal_entries.json', []);
  const payments = readJson<unknown>('payments.json', []);
  const productionReports = readJson<unknown>('production_reports.json', []);
  const purchaseCreditNotes = readJson<unknown>('purchase_credit_notes.json', []);
  const purchaseReturns = readJson<unknown>('purchase_returns.json', []);
  const shiftOverrides = readJson<unknown>('shiftOverrides.json', []);
  const shipmentSequences = readJson<unknown>('shipment_sequences.json', []);
  const shipments = readJson<unknown>('shipments.json', []);
  const supplierPaymentLocks = readJson<unknown>('supplier_payment_locks.json', []);
  const supplierPayments = readJson<unknown>('supplier_payments.json', []);
  const transferLocks = readJson<unknown>('transfer_locks.json', []);
  const sequenceCounters = readJson<unknown>('_sequences.json', {});
  const invoices = readJson<Array<Record<string, unknown>>>('invoices.json', []);
  const purchaseOrders = readJson<Array<Record<string, unknown>>>('purchase_orders.json', []);

  await pgSaveSettings(settings);
  await pgSaveCustomers(customers);
  await pgSaveSuppliers(suppliers);
  await pgSaveMaterials(materials);
  await pgSaveExpenses(expenses);
  await pgSaveProductShapeDefinitions(productShapes);
  await pgSaveSalesReps(salesReps);
  await pgSaveManagedUnits(managedUnits);
  await pgSaveItemGroups(itemGroups);
  await pgSaveWarehouses(warehouses);
  await pgSaveBanks(banks);
  await pgSaveCustomerPricing(customerPricing);
  await pgSaveItemUnits(itemUnits);
  await pgSaveInternalTransfers(internalTransfers);
  await pgSaveInventoryMovements(inventoryMovements);
  await pgSaveCustomerCategories(customerCategories);
  await pgSaveParties(parties);
  await pgSaveChartOfAccounts(chartOfAccounts);
  await pgSaveChecksIssued(checksIssued);
  await pgSaveChecksReceived(checksReceived);
  await pgSaveCurrencies(currencies);
  await pgSaveDailyExchangeRates(dailyExchangeRates);
  await pgSaveEmployees(employees);
  await pgSaveExchangeRateSources(exchangeRateSources);
  await pgSaveInternalTransferDocs(internalTransferDocs);
  await pgSaveJournalEntries(journalEntries);
  await pgSavePayments(payments);
  await pgSaveProductionReports(productionReports);
  await pgSavePurchaseCreditNotes(purchaseCreditNotes);
  await pgSavePurchaseReturns(purchaseReturns);
  await pgSaveShiftOverrides(shiftOverrides);
  await pgSaveShipmentSequences(shipmentSequences);
  await pgSaveShipments(shipments);
  await pgSaveSupplierPaymentLocks(supplierPaymentLocks);
  await pgSaveSupplierPayments(supplierPayments);
  await pgSaveTransferLocks(transferLocks);
  await pgSaveSequenceCounters(sequenceCounters);
  await pgSaveInvoices(invoices);
  await pgSavePurchaseOrders(purchaseOrders);

  // Keep remaining legacy files in generic JSON store for progressive migration.
  const files = fs.existsSync(dbPath) ? fs.readdirSync(dbPath).filter((file) => file.endsWith('.json')) : [];
  for (const fileName of files) {
    const payload = readJson<unknown>(fileName, null);
    await upsertJsonStore(fileName, payload);
  }

  console.log('Seed completed.');
  console.log('customers:', customers.length);
  console.log('suppliers:', suppliers.length);
  console.log('materials:', materials.length);
  console.log('expenses:', expenses.length);
  console.log('product_shape_definitions:', productShapes.length);
  console.log('sales_reps:', salesReps.length);
  console.log('managed_units:', managedUnits.length);
  console.log('item_groups:', itemGroups.length);
  console.log('warehouses:', warehouses.length);
  console.log('banks:', banks.length);
  console.log('customer_pricing:', customerPricing.length);
  console.log('chart_of_accounts loaded');
  console.log('checks_issued loaded');
  console.log('checks_received loaded');
  console.log('currencies loaded');
  console.log('daily_exchange_rates loaded');
  console.log('employees loaded');
  console.log('exchange_rate_sources loaded');
  console.log('internal_transfer_docs loaded');
  console.log('journal_entries loaded');
  console.log('payments loaded');
  console.log('production_reports loaded');
  console.log('purchase_credit_notes loaded');
  console.log('purchase_returns loaded');
  console.log('shift_overrides loaded');
  console.log('shipment_sequences loaded');
  console.log('shipments loaded');
  console.log('supplier_payment_locks loaded');
  console.log('supplier_payments loaded');
  console.log('transfer_locks loaded');
  console.log('sequence_counters loaded');
  console.log('invoices:', invoices.length);
  console.log('purchase_orders:', purchaseOrders.length);
}

main()
  .catch((error) => {
    console.error('Seed failed:', error);
    process.exitCode = 1;
  })
  .finally(async () => {
    await getPgPool().end();
  });
