'use server';

import { prisma } from '@/lib/prisma';
import { parseCSV, autoMatchTransactions, getReconciliationSummary } from '@/lib/bankReconciliation';
import { redirect } from 'next/navigation';

export async function uploadBankStatement(formData: FormData) {
  const file = formData.get('file') as File;
  const bankName = String(formData.get('bankName') ?? '').trim();
  const accountNumber = String(formData.get('accountNumber') ?? '').trim();

  if (!file) throw new Error('No file selected');
  if (file.type !== 'text/csv' && !file.name.endsWith('.csv')) {
    throw new Error('Only CSV files are supported');
  }

  const content = await file.text();
  const transactions = parseCSV(content);

  if (transactions.length === 0) {
    throw new Error('No valid transactions found in CSV');
  }

  // Create the statement
  const statement = await prisma.bankStatement.create({
    data: {
      filename: file.name,
      bankName: bankName || null,
      accountNumber: accountNumber ? accountNumber.slice(-4) : null,
      statementMonth: new Date(),
      startDate: transactions[0].date,
      endDate: transactions[transactions.length - 1].date,
      totalTransactions: transactions.length,
      totalAmount: transactions.reduce((sum, t) => sum + t.amount, 0),
      lines: {
        create: transactions.map((t) => ({
          date: t.date,
          description: t.description,
          amount: t.amount,
          balance: t.balance,
          reference: t.reference,
        })),
      },
    },
  });

  // Auto-match transactions
  await autoMatchTransactions(statement.id);

  // Update statement status
  const summary = await getReconciliationSummary(statement.id);
  if (summary?.reconciled) {
    await prisma.bankStatement.update({
      where: { id: statement.id },
      data: { status: 'RECONCILED', reconciliedAt: new Date() },
    });
  } else {
    await prisma.bankStatement.update({
      where: { id: statement.id },
      data: { status: 'IN_PROGRESS' },
    });
  }

  redirect(`/admin/accounts/reconciliation?id=${statement.id}`);
}

export async function manualMatch(
  bankLineId: string,
  transactionType: string,
  transactionId: string,
  notes?: string
) {
  const bankLine = await prisma.bankStatementLine.findUnique({
    where: { id: bankLineId },
  });

  if (!bankLine) throw new Error('Bank line not found');

  // Get system transaction amount
  let systemAmount = 0;
  let description = '';

  if (transactionType === 'ORDER') {
    const order = await prisma.order.findUnique({
      where: { id: transactionId },
      select: { total: true, id: true },
    });
    if (!order) throw new Error('Order not found');
    systemAmount = order.total;
    description = `Order #${order.id.slice(0, 8)}`;
  } else if (transactionType === 'MANUAL_SALE') {
    const sale = await prisma.manualSale.findUnique({
      where: { id: transactionId },
      select: { total: true, id: true },
    });
    if (!sale) throw new Error('Manual sale not found');
    systemAmount = sale.total;
    description = `Manual sale #${sale.id.slice(0, 8)}`;
  } else if (transactionType === 'EXPENSE') {
    const expense = await prisma.expense.findUnique({
      where: { id: transactionId },
      select: { amount: true, category: true },
    });
    if (!expense) throw new Error('Expense not found');
    systemAmount = expense.amount;
    description = expense.category;
  }

  // Delete existing match if any
  await prisma.bankReconciliation.deleteMany({
    where: { bankLineId },
  });

  // Create new match
  await prisma.bankReconciliation.create({
    data: {
      statementId: bankLine.statementId,
      bankLineId,
      transactionType,
      transactionId,
      description,
      systemAmount,
      bankAmount: bankLine.amount,
      amountMatches: Math.abs(systemAmount - bankLine.amount) < 1,
      matchedBy: 'ADMIN', // In real app, would capture IP
      notes,
      confidence: Math.abs(systemAmount - bankLine.amount) < 1 ? 100 : 50,
    },
  });

  // Mark as matched
  await prisma.bankStatementLine.update({
    where: { id: bankLineId },
    data: { matched: true },
  });
}

export async function unmatchBankLine(bankLineId: string) {
  await prisma.bankReconciliation.deleteMany({
    where: { bankLineId },
  });

  await prisma.bankStatementLine.update({
    where: { id: bankLineId },
    data: { matched: false },
  });
}

export async function archiveStatement(statementId: string) {
  await prisma.bankStatement.update({
    where: { id: statementId },
    data: { status: 'ARCHIVED' },
  });
}

export async function markReconciled(statementId: string) {
  await prisma.bankStatement.update({
    where: { id: statementId },
    data: {
      status: 'RECONCILED',
      reconciliedAt: new Date(),
    },
  });
}
