import { NextRequest, NextResponse } from 'next/server';
import {
  pgGetBankReconciliationPeriodById,
  pgSetBankReconciliationPeriodStatus,
  pgGetBankTransactionsForPeriod,
  pgGetReconciliationMatchesForPeriod,
  pgGetAllLedgerTransactionsForBankAccount,
} from '@/lib/postgres/bank-reconciliation';

/**
 * POST /api/admin/bank-reconciliation/periods/[id]/lock
 * Body: { action: 'lock' | 'complete' | 'reopen', actorId: string }
 *
 * lock     → status = 'locked'   (no further edits allowed)
 * complete → status = 'completed' (reconciliation finished)
 * reopen   → status = 'in-progress' (revert lock/complete)
 */
export async function POST(
  req: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  try {
    const { id: periodId } = await params;

    const period = await pgGetBankReconciliationPeriodById(periodId);
    if (!period) {
      return NextResponse.json({ error: 'Period not found' }, { status: 404 });
    }

    const body = await req.json();
    const { action, actorId } = body as { action: 'lock' | 'complete' | 'reopen'; actorId: string };

    if (!action || !actorId) {
      return NextResponse.json({ error: 'action and actorId are required' }, { status: 400 });
    }

    if (action === 'reopen') {
      const updated = await pgSetBankReconciliationPeriodStatus(periodId, 'in-progress', actorId);
      return NextResponse.json(updated, { status: 200 });
    }

    // Compute current difference before locking
    const [bankTransactions, matches, allLedger] = await Promise.all([
      pgGetBankTransactionsForPeriod(periodId),
      pgGetReconciliationMatchesForPeriod(periodId),
      pgGetAllLedgerTransactionsForBankAccount(period.bankAccountId),
    ]);

    const ledgerTransactions = allLedger.filter((lt) => {
      return lt.transactionDate >= period.periodStartDate &&
             lt.transactionDate <= period.periodEndDate;
    });

    const matchedBankIds = new Set(matches.map((m) => m.bankTransactionId));
    const matchedLedgerIds = new Set(matches.flatMap((m) => m.ledgerTransactionIds));

    let depositsInTransit = 0;
    let outstandingChecks = 0;
    let unmatchedBankInflows = 0;
    let unmatchedBankOutflows = 0;

    for (const bt of bankTransactions) {
      if (!matchedBankIds.has(bt.id)) {
        const isInward = bt.direction === 'inward' || bt.direction === 'debit';
        if (isInward) unmatchedBankInflows += bt.amount;
        else unmatchedBankOutflows += bt.amount;
      }
    }

    for (const lt of ledgerTransactions) {
      if (!matchedLedgerIds.has(lt.id)) {
        const isInward = lt.direction === 'inward' || lt.direction === 'credit';
        if (isInward) depositsInTransit += lt.amount;
        else outstandingChecks += lt.amount;
      }
    }

    const statementClosingBalance = period.statementEndBalance || 0;
    const adjustedBankBalance = statementClosingBalance + depositsInTransit - outstandingChecks;
    const adjustedBookBalance = statementClosingBalance + unmatchedBankInflows - unmatchedBankOutflows;
    const reconciliationDifference = adjustedBankBalance - adjustedBookBalance;

    const newStatus = action === 'lock' ? 'locked' : 'completed';
    const updated = await pgSetBankReconciliationPeriodStatus(
      periodId,
      newStatus,
      actorId,
      reconciliationDifference
    );

    return NextResponse.json(
      { ...updated, reconciliationDifference, adjustedBankBalance, adjustedBookBalance },
      { status: 200 }
    );
  } catch (error) {
    console.error('Error changing period status:', error);
    return NextResponse.json(
      { error: error instanceof Error ? error.message : 'Internal Server Error' },
      { status: 500 }
    );
  }
}
