import { pgQuery } from '../lib/postgres/client';
import {
  pgCreateBankReconciliationPeriod,
  pgBatchAddBankTransactions,
  pgAddLedgerTransaction,
} from '../lib/postgres/bank-reconciliation';
import { applyAutoMatchFromPreviewForPeriod } from '../lib/services/bank-reconciliation-auto-match';
import type {
  BankReconciliationPeriod,
  BankTransaction,
  LedgerTransaction,
} from '../lib/types';

const BANK_ACCOUNT_ID = 'bank-1776171260132-0';
const TEST_USER = 'test@system.local';

async function main() {
  try {
    const periodStart = '2024-03-01';
    const periodEnd = '2024-03-31';

    const cleanupRows = await pgQuery<{ id: string }>(
      `
      SELECT id
      FROM bank_reconciliation_periods
      WHERE bank_account_id = $1
        AND period_start_date = $2
        AND period_end_date = $3
      `,
      [BANK_ACCOUNT_ID, periodStart, periodEnd]
    );

    if (cleanupRows.rows.length > 0) {
      const ids = cleanupRows.rows.map((r) => r.id);
      const ledgerRows = await pgQuery<{ id: string }>(
        'SELECT id FROM ledger_transactions WHERE reconciliation_period_id = ANY($1::TEXT[])',
        [ids]
      );
      const ledgerIds = ledgerRows.rows.map((r) => r.id);
      if (ledgerIds.length > 0) {
        await pgQuery(
          'DELETE FROM bank_reconciliation_differences WHERE ledger_transaction_id = ANY($1::TEXT[])',
          [ledgerIds]
        );
      }
      await pgQuery('DELETE FROM bank_reconciliation_differences WHERE reconciliation_period_id = ANY($1::TEXT[])', [ids]);
      await pgQuery('DELETE FROM reconciliation_matches WHERE reconciliation_period_id = ANY($1::TEXT[])', [ids]);
      await pgQuery('DELETE FROM bank_transactions WHERE reconciliation_period_id = ANY($1::TEXT[])', [ids]);
      await pgQuery('DELETE FROM ledger_transactions WHERE reconciliation_period_id = ANY($1::TEXT[])', [ids]);
      await pgQuery('DELETE FROM bank_reconciliation_periods WHERE id = ANY($1::TEXT[])', [ids]);
    }

    const period = await pgCreateBankReconciliationPeriod({
      bankAccountId: BANK_ACCOUNT_ID,
      periodStartDate: periodStart,
      periodEndDate: periodEnd,
      statementStartBalance: 50000,
      statementEndBalance: 54000,
      status: 'draft',
      createdBy: TEST_USER,
    } as Omit<BankReconciliationPeriod, 'id' | 'createdAt' | 'updatedAt'>);

    await pgBatchAddBankTransactions([
      {
        reconciliationPeriodId: period.id,
        bankAccountId: BANK_ACCOUNT_ID,
        transactionDate: '2024-03-08',
        amount: 4000,
        direction: 'inward',
        description: 'Receipt INV-2001',
        bankReference: 'DEP-2001',
        type: 'transfer',
        currencyCode: 'USD',
      },
    ] as Omit<BankTransaction, 'id' | 'createdAt' | 'updatedAt'>[]);

    await pgAddLedgerTransaction({
      bankAccountId: BANK_ACCOUNT_ID,
      journalEntryId: 'je-afp-1',
      journalEntryLineIdx: 0,
      transactionDate: '2024-03-08',
      amount: 4000,
      direction: 'inward',
      description: 'Receipt INV-2001',
      referenceType: 'invoice',
      referenceId: 'inv-2001',
      postingStatus: 'posted',
      reconciliationStatus: 'unreconciled',
      currencyCode: 'USD',
      fxRate: 1,
    } as Omit<LedgerTransaction, 'id' | 'createdAt' | 'updatedAt'>);

    const result = await applyAutoMatchFromPreviewForPeriod(period.id, TEST_USER, 80);

    console.log(`Applied: ${result.appliedCount}`);
    console.log(`Skipped: ${result.skippedCount}`);
    console.log(`MatchedCount: ${result.matchedCount}`);

    if (result.appliedCount < 1) {
      throw new Error('Expected at least one match to be applied from preview');
    }

    console.log('Apply from preview flow test passed');
    process.exit(0);
  } catch (error) {
    console.error(error instanceof Error ? error.message : error);
    process.exit(1);
  }
}

main();
