import { NextRequest, NextResponse } from 'next/server';

import {
  pgAddPayment,
  pgAddSupplierPayment,
  pgEndorseIncomingCheck,
  pgGetChecksReceived,
  pgSaveJournalEntry,
  pgUpdateCustomerBalance,
  pgUpdateSupplierBalance,
} from '@/lib/postgres/data-access';
import { getChartOfAccountsWithSeedMerge } from '@/lib/accounting/chart-of-accounts-runtime';

export async function POST(request: NextRequest) {
  try {
    const body = await request.json();
    const { checkId, endorsementType, endorsedToId, endorsedToName, endorsedToType, endorsementReference, notes } = body;

    if (!checkId || !endorsementType) {
      return NextResponse.json(
        { error: 'Missing required fields' },
        { status: 400 }
      );
    }

    // Get the check to access its details
    const checks = (await pgGetChecksReceived({ page: 1, pageSize: 5000 })).items as any[];
    const check = checks.find(c => c.id === checkId);
    if (!check) {
      return NextResponse.json(
        { error: 'Check not found' },
        { status: 404 }
      );
    }

    const chartAccounts = await getChartOfAccountsWithSeedMerge();
    const incomingChecksAccount = chartAccounts.find((acc: any) => String(acc?.code || '').trim() === '1015' && !acc?.inactive);
    const collectionChecksAccount = chartAccounts.find((acc: any) => String(acc?.code || '').trim() === '1020' && !acc?.inactive);

    if (endorsementType === 'transferred-to-collection') {
      const missingAccounts: Array<{ code: string; nameAr: string; nameEn: string }> = [];
      if (!incomingChecksAccount) {
        missingAccounts.push({
          code: '1015',
          nameAr: 'شيكات واردة',
          nameEn: 'Incoming Checks',
        });
      }
      if (!collectionChecksAccount) {
        missingAccounts.push({
          code: '1020',
          nameAr: 'شيكات برسم التحصيل',
          nameEn: 'Checks for Collection',
        });
      }

      if (missingAccounts.length > 0) {
        return NextResponse.json(
          {
            error: 'COLLECTION_ACCOUNTS_MISSING',
            message: 'Missing required collection accounts',
            missingAccounts,
          },
          { status: 400 }
        );
      }
    }

    // Update the check endorsement status
    const updated = await pgEndorseIncomingCheck(
          checkId,
          endorsementType,
          endorsedToId,
          endorsedToName,
          endorsedToType,
          endorsementReference,
          notes
        );
    if (!updated) {
      return NextResponse.json(
        { error: 'Failed to endorse check' },
        { status: 500 }
      );
    }

    // Create accounting entries based on endorsement type
    if (endorsementType === 'transferred-to-collection') {
      // Journal Entry: Transfer to Collection Account
      // Debit: Checks for Collection (Asset)
      // Credit: Incoming Checks (Asset)
      try {
        await pgSaveJournalEntry([{ 
          date: new Date().toISOString(),
          referenceType: 'payment',
          referenceId: `CHK-TRANSFER-${checkId}`,
          description: `نقل شيك رقم ${check.checkNumber} لصندوق شيكات برسم التحصيل / Transfer check #${check.checkNumber} to collection account`,
          lines: [
            {
              accountId: String(collectionChecksAccount?.id || '1020'),
              accountCode: '1020',
              accountName: String(collectionChecksAccount?.nameAr || 'شيكات برسم التحصيل'),
              debit: check.amount,
              credit: 0,
              description: `نقل شيك رقم ${check.checkNumber}`,
            },
            {
              accountId: String(incomingChecksAccount?.id || '1015'),
              accountCode: '1015',
              accountName: String(incomingChecksAccount?.nameAr || 'شيكات واردة'),
              debit: 0,
              credit: check.amount,
              description: `نقل شيك رقم ${check.checkNumber}`,
            },
          ],
          createdBy: 'System',
        }]);
      } catch (error) {
        console.error('Failed to create journal entry for check transfer:', error);
      }
    } else if (endorsementType === 'endorsed-to-party') {
      // Journal Entry: Endorse to Party
      // Debit: Accounts Receivable/Payable (depending on party type)
      // Credit: Incoming Checks
      const isCustomer = endorsedToType === 'customer';
      const accountCode = isCustomer ? '1100' : '2100'; // Customer AR or Supplier AP
      const accountId = isCustomer ? `1100-${endorsedToId}` : `2100-${endorsedToId}`;
      const accountName = isCustomer
        ? `الذمم المدينة / Accounts Receivable - ${endorsedToName}`
        : `الذمم الدائنة / Accounts Payable - ${endorsedToName}`;

      try {
        await pgSaveJournalEntry([{ 
          date: new Date().toISOString(),
          referenceType: 'payment',
          referenceId: `CHK-ENDORSE-${checkId}`,
          description: `تجير شيك رقم ${check.checkNumber} لصالح ${endorsedToName} / Endorse check #${check.checkNumber} to ${endorsedToName}`,
          lines: [
            {
              accountId,
              accountCode,
              accountName,
              debit: check.amount,
              credit: 0,
              description: `تجير شيك رقم ${check.checkNumber}`,
            },
            {
              accountId: '1015',
              accountCode: '1015',
              accountName: 'شيكات واردة / Incoming Checks',
              debit: 0,
              credit: check.amount,
              description: `تجير شيك رقم ${check.checkNumber}`,
            },
          ],
          createdBy: 'System',
        }]);
      } catch (error) {
        console.error('Failed to create journal entry for check endorsement:', error);
      }

      // Create payment record for the endorsed party
      try {
        if (isCustomer) {
          await pgAddPayment({
            date: new Date().toISOString(),
            customerId: endorsedToId,
            amount: check.amount,
          });
          await pgUpdateCustomerBalance(endorsedToId, -check.amount);
        } else {
          await pgAddSupplierPayment({
            date: new Date().toISOString(),
            supplierId: endorsedToId,
            amount: check.amount,
            reference: `CHK-${check.checkNumber}`,
            notes: `تجير شيك / Check endorsement: ${notes || ''}`,
          });
          await pgUpdateSupplierBalance(endorsedToId, -check.amount);
        }
      } catch (error) {
        console.error('Failed to create payment record for endorsed check:', error);
      }
    }

    return NextResponse.json({
      success: true,
      message: 'Check endorsed successfully',
      check: (await pgGetChecksReceived({ page: 1, pageSize: 5000 })).items.find(c => c.id === checkId),
    });
  } catch (error) {
    console.error('Error endorsing check:', error);
    return NextResponse.json(
      { error: 'Internal server error' },
      { status: 500 }
    );
  }
}
