import Link from "next/link";
import { verifySession } from "@/lib/auth";

import { hasEmployeePermission } from "@/lib/employee-permissions";
import { getCurrentLocale, getTranslations } from "@/lib/i18n";
import { format } from "date-fns";
import { ar } from "date-fns/locale";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "@/components/ui/accordion";
import {
  Table,
  TableBody,
  TableCell,
  TableFooter,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { Badge } from "@/components/ui/badge";
import { formatCurrency as formatCurrencyUtil } from "@/lib/currency-formatter";
import { getCurrencySymbolAsync } from "@/lib/server-currency";
import { getChartOfAccountsWithSeedMerge } from "@/lib/accounting/chart-of-accounts-runtime";
import { ManualJournalEntryDialog } from "@/components/admin/manual-journal-entry-dialog";
import type { JournalEntry, PurchaseOrder, PurchaseReturn, Supplier } from "@/lib/types";

function parseStableEntryDate(value: string): Date {
  const normalized = String(value || '').trim();
  const dateOnlyMatch = normalized.match(/^(\d{4})-(\d{2})-(\d{2})$/);
  if (dateOnlyMatch) {
    const year = Number(dateOnlyMatch[1]);
    const month = Number(dateOnlyMatch[2]);
    const day = Number(dateOnlyMatch[3]);
    return new Date(year, month - 1, day, 12, 0, 0, 0);
  }
  return new Date(normalized);
}

export default async function JournalEntriesPage({
  searchParams,
}: {
  searchParams?: Promise<{ je?: string; q?: string }>;
}) {
  const resolvedSearchParams = searchParams ? await searchParams : undefined;
  const focusedJournalId = String(resolvedSearchParams?.je || '').trim();
  const quickQuery = String(resolvedSearchParams?.q || '').trim().toLowerCase();
  const session = await verifySession();
  const user = session.user;
  const locale = await getCurrentLocale();
  const t = getTranslations(locale);
  const tAccounting = t.Accounting ?? {};
  const currencySymbol = await getCurrencySymbolAsync();
  const formatAmount = (amount: number) => formatCurrencyUtil(amount, currencySymbol);
  const getEntryStatusLabel = (entry: JournalEntry) => String(entry.status || 'posted') === 'draft' ? 'مسودة' : 'أصلي';
  const getEntryStatusVariant = (entry: JournalEntry) => String(entry.status || 'posted') === 'draft' ? 'secondary' : 'default';
  const getEntryTypeCode = (referenceType: string) => {
    const map: Record<string, string> = {
      sales_invoice: 'SAL',
      purchase_order: 'PUR',
      payment: 'PAY',
      purchase_return: 'PRT',
      purchase_return_cancel: 'PRC',
      expense: 'EXP',
      manual: 'MAN',
    };
    return map[String(referenceType || '').trim()] || 'GEN';
  };
  const getCompactEntryId = (entry: JournalEntry) => {
    const id = String(entry.id || '').trim();
    const isDraft = id.startsWith('JED-') || String(entry.status || '').trim() === 'draft';
    const statusCode = isDraft ? 'D' : 'P';
    const normalized = id.replace(/^JED-/, '').replace(/^JE-/, '');
    const tail = (normalized.match(/[A-Za-z0-9]{6,}$/)?.[0] || normalized).slice(-8).toUpperCase();
    return `${statusCode}-${getEntryTypeCode(entry.referenceType)}-${tail}`;
  };
  const settings = await (await import('@/lib/postgres/data-access')).pgGetSettings();  const baseCurrencyCode = String(
    (settings as any)?.baseCurrencyCode
    || (settings as any)?.defaultCurrencyCode
    || (settings as any)?.appCurrency
    || 'ILS'
  );

  if (!user || !hasEmployeePermission(user, settings, 'admin.accounting')) {
    return (
        <div className="text-center">
            <h1 className="text-2xl font-bold">{t.Global.accessDenied}</h1>
            <p>{t.Global.noPermission}</p>
        </div>
    );
  }

  
  let journalEntries: JournalEntry[] = [];
  let purchaseOrders: PurchaseOrder[] = [];
  let purchaseReturns: PurchaseReturn[] = [];
  let suppliers: Supplier[] = [];
  
  const mergeById = <T extends { id: string }>(primary: T[], secondary: T[]) => {
    const map = new Map<string, T>();
    for (const item of secondary) {
      map.set(String(item.id || '').trim(), item);
    }
    for (const item of primary) {
      map.set(String(item.id || '').trim(), item);
    }
    return Array.from(map.values());
  };

  try {
    
    const { pgGetJournalEntries, pgGetPurchaseOrders, pgGetPurchaseReturns, pgGetSuppliers } = await import('@/lib/postgres/data-access');
    const [entriesResult, purchaseResult, returnsResult, suppliersResult] = await Promise.all([
    pgGetJournalEntries({ page: 1, pageSize: 10000 }),
    pgGetPurchaseOrders({ page: 1, pageSize: 5000 }),
    pgGetPurchaseReturns({ page: 1, pageSize: 5000 }),
    pgGetSuppliers({ page: 1, pageSize: 5000 })
    ]);
    journalEntries = (entriesResult.items || []) as JournalEntry[];
    purchaseOrders = (purchaseResult.items || []) as PurchaseOrder[];
    purchaseReturns = (returnsResult.items || []) as PurchaseReturn[];
    suppliers = (suppliersResult.items || []) as Supplier[];
    
  } catch {
    journalEntries = [];
    purchaseOrders = [];
    purchaseReturns = [];
    suppliers = [];
  }
  const purchaseByNumber = new Map(purchaseOrders.map((po) => [po.orderNumber, po]));
  const purchaseById = new Map(purchaseOrders.map((po) => [po.id, po]));
  const purchaseReturnById = new Map(purchaseReturns.map((pr) => [pr.id, pr]));
  const supplierById = new Map(suppliers.map((s) => [s.id, s]));
  const chartOfAccounts = await getChartOfAccountsWithSeedMerge();
  const manualEntryAccounts = (chartOfAccounts || [])
    .filter((account) => String(account.type || '') === 'account' && !Boolean(account.inactive))
    .map((account) => ({
      id: String(account.id || ''),
      code: String(account.code || ''),
      nameAr: String(account.nameAr || ''),
      nameEn: String(account.nameEn || ''),
      type: account.type,
      inactive: Boolean(account.inactive),
    }));
  
  // Sort by date descending
  const sortedEntries = [...journalEntries].sort((a, b) =>
    parseStableEntryDate(b.date).getTime() - parseStableEntryDate(a.date).getTime()
  );

  const filteredEntries = sortedEntries.filter((entry) => {
    if (focusedJournalId && String(entry.id || '').trim() !== focusedJournalId) {
      return false;
    }
    if (!quickQuery) return true;
    const haystack = `${String(entry.id || '')} ${String(entry.referenceId || '')} ${String(entry.description || '')}`.toLowerCase();
    return haystack.includes(quickQuery);
  });

  const getReferenceTypeLabel = (type: string) => {
    const labels: Record<string, string> = {
      'sales_invoice': tAccounting?.salesInvoice ?? 'فاتورة مبيعات',
      'purchase_order': tAccounting?.purchaseDocument ?? 'سند مشتريات',
      'payment': tAccounting?.payment ?? 'سند قبض',
      'expense': tAccounting?.expense ?? 'مصروف',
      'production': tAccounting?.production ?? 'إنتاج',
      'salary': tAccounting?.salary ?? 'راتب',
      'advance': tAccounting?.advance ?? 'سلفة',
      'purchase_return': tAccounting?.purchaseReturn ?? 'مردود مشتريات',
      'purchase_return_cancel': tAccounting?.purchaseReturnCancel ?? 'إلغاء مردود',
      'manual': tAccounting?.manual ?? 'يدوي',
    };
    return labels[type] || type;
  };

  return (
    <div className="p-6 space-y-6">
      <Card>
        <CardHeader>
          <div className="flex flex-wrap items-start justify-between gap-3">
            <div>
              <CardTitle>{tAccounting?.journalEntries ?? 'القيود اليومية'}</CardTitle>
              <CardDescription>
                {tAccounting?.journalDescription ?? 'سجل جميع القيود المحاسبية في النظام'}
              </CardDescription>
            </div>
            <ManualJournalEntryDialog accounts={manualEntryAccounts} />
          </div>
        </CardHeader>
        <CardContent>
          {(focusedJournalId || quickQuery) && (
            <div className="mb-4 flex flex-wrap items-center gap-2 text-xs">
              <Badge variant="secondary" className="text-xs">
                {focusedJournalId ? `تصفية برقم القيد: ${focusedJournalId}` : `بحث: ${quickQuery}`}
              </Badge>
              <Link href="/admin/accounting/entries" className="text-primary underline">
                إزالة التصفية
              </Link>
            </div>
          )}

          {filteredEntries.length === 0 ? (
            <p className="text-center text-muted-foreground py-12">
              {focusedJournalId || quickQuery
                ? 'لا يوجد قيد مطابق للتصفية الحالية.'
                : (tAccounting?.noEntries ?? 'لا توجد قيود محاسبية.')}
            </p>
          ) : (
            <Accordion type="single" collapsible className="w-full">
              {filteredEntries.map((entry) => {
                const safeLines = Array.isArray(entry.lines) ? entry.lines : [];
                const totalDebit = safeLines.reduce((sum, line) => sum + Number(line.debit || 0), 0);
                const totalCredit = safeLines.reduce((sum, line) => sum + Number(line.credit || 0), 0);
                const safeEntryId = typeof entry.id === 'object' ? String((entry.id as any)?.id || '') : String(entry.id || '');
                const safeReferenceId = typeof entry.referenceId === 'object' ? String((entry.referenceId as any)?.id || '') : String(entry.referenceId || '');
                const safeDescription = typeof entry.description === 'object' ? String((entry.description as any)?.description || '') : String(entry.description || '');
                const safeCreatedBy = typeof entry.createdBy === 'object' ? String((entry.createdBy as any)?.name || (entry.createdBy as any)?.id || '') : String(entry.createdBy || '');
                const safeCurrencyCode = typeof entry.currencyCode === 'object' ? String((entry.currencyCode as any)?.code || '') : String(entry.currencyCode || '');
                const safeReferenceType = typeof entry.referenceType === 'object' ? String((entry.referenceType as any)?.type || (entry.referenceType as any)?.id || '') : String(entry.referenceType || '');
                const isBalanced = Math.abs(totalDebit - totalCredit) < 0.01;
                const relatedPurchaseOrder = entry.referenceType === 'purchase_order'
                  ? (purchaseByNumber.get(entry.referenceId) || purchaseById.get(entry.referenceId))
                  : undefined;
                const purchaseDocumentTypeLabel = relatedPurchaseOrder?.documentType === 'shipment'
                  ? (tAccounting?.shipmentDocLabel ?? 'ارسالية')
                  : (tAccounting?.purchaseInvoice ?? 'فاتورة مشتريات');
                const entryDocumentCurrency = String(
                  entry.currencyCode || relatedPurchaseOrder?.currencyCode || baseCurrencyCode
                ).trim();
                const rawEntryFxRate = Number(entry.fxRate || relatedPurchaseOrder?.exchangeRate || 1);
                const entryFxRate = Number.isFinite(rawEntryFxRate) && rawEntryFxRate > 0 ? rawEntryFxRate : 1;
                const formatOriginalAmount = (amount: number, currencyCode: string) => (
                  `${amount.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} ${currencyCode}`
                );

                const relatedSupplierName = (() => {
                  if (entry.referenceType === 'purchase_order') {
                    return relatedPurchaseOrder?.supplierName;
                  }
                  if (entry.referenceType === 'purchase_return' || entry.referenceType === 'purchase_return_cancel') {
                    const pr = purchaseReturnById.get(entry.referenceId);
                    if (!pr) return undefined;
                    return supplierById.get(pr.supplierId)?.name;
                  }
                  return undefined;
                })();

                const entryTitle = (() => {
                  if (safeReferenceType !== 'purchase_order') return safeDescription;
                  const supplierName = relatedPurchaseOrder?.supplierName || relatedSupplierName || '';
                  const prefix = purchaseDocumentTypeLabel;
                  const fromLabel = tAccounting?.from ?? (locale === 'ar' ? 'من' : 'from');
                  return supplierName
                    ? `${prefix} ${safeReferenceId} ${fromLabel} ${supplierName}`
                    : `${prefix} ${safeReferenceId}`;
                })();

                return (
                  <AccordionItem
                    value={safeEntryId}
                    key={safeEntryId}
                    className={focusedJournalId === safeEntryId.trim() ? 'border-primary bg-primary/5 rounded-md px-2' : undefined}
                  >
                    <AccordionTrigger>
                      <div className="flex justify-between items-center w-full pe-4">
                        <div className="flex flex-col text-start gap-1">
                          <span className="font-semibold">{entryTitle}</span>
                          <p className="font-mono font-bold text-base mb-2">
                            {tAccounting?.entryNumber ?? 'رقم القيد'}: <span className="text-primary">{safeEntryId}</span>
                          </p>
                          <div className="flex flex-wrap items-center gap-2 mb-2">
                            <span className="text-sm text-muted-foreground">الرقم المختصر:</span>
                            <span className="font-mono text-sm font-bold text-primary">{getCompactEntryId(entry)}</span>
                            <Badge variant={getEntryStatusVariant(entry)} className="text-xs">{getEntryStatusLabel(entry)}</Badge>
                          </div>
                          <div className="flex gap-2 text-xs text-muted-foreground">
                            <span>{format(parseStableEntryDate(entry.date), "PPP")}</span>
                            <Badge variant="outline" className="text-xs">
                              {entry.referenceType === 'purchase_order'
                                ? purchaseDocumentTypeLabel
                                : getReferenceTypeLabel(entry.referenceType)}
                            </Badge>
                          </div>
                        </div>
                        <div className="flex flex-col text-end gap-1">
                          <span className="font-mono font-bold">{formatAmount(totalDebit)}</span>
                          {!isBalanced && (
                            <Badge variant="destructive" className="text-xs">
                              {tAccounting?.unbalanced ?? 'غير متوازن'}
                            </Badge>
                          )}
                        </div>
                      </div>
                    </AccordionTrigger>
                    <AccordionContent>
                      <div className="p-4 bg-muted/50 rounded-md">
                        <div className="mb-3 rounded-lg border-2 border-sky-500/70 bg-sky-50 px-4 py-3">
                          <div className="flex flex-wrap items-center justify-between gap-3">
                            <div>
                              <p className="text-xs font-semibold text-sky-900/80">رقم التدقيق المختصر</p>
                              <p className="font-mono text-2xl font-extrabold tracking-wide text-sky-900">{getCompactEntryId(entry)}</p>
                            </div>
                            <Badge variant={getEntryStatusVariant(entry)} className="text-sm px-3 py-1">
                              {getEntryStatusLabel(entry)}
                            </Badge>
                          </div>
                        </div>

                        <div className="mb-3 text-sm">
                          <p className="font-mono font-bold text-base mb-2">
                            {tAccounting?.entryNumber ?? 'رقم القيد'}:  <span className="text-primary">{safeEntryId}</span>
                          </p>
                          <div className="flex flex-wrap items-center gap-2 mb-2">
                            <span className="text-xs text-muted-foreground">الرقم المختصر: <span className="font-mono font-semibold text-foreground">{getCompactEntryId(entry)}</span></span>
                            <Badge variant={getEntryStatusVariant(entry)} className="text-xs">{getEntryStatusLabel(entry)}</Badge>
                          </div>
                          <div className="text-muted-foreground space-y-1">
                            <p>{tAccounting?.createdBy ?? 'تم الإنشاء بواسطة'}: {safeCreatedBy}</p>
                            <div className="flex items-center gap-2 flex-wrap">
                              <p className="m-0">{tAccounting?.reference ?? 'المرجع'}: {safeReferenceId}</p>
                              {entry.referenceType === 'purchase_order' && entry.referenceId && purchaseByNumber.has(entry.referenceId) && (
                                <Link
                                  href={`/admin/purchases/view/${purchaseByNumber.get(entry.referenceId)!.id}`}
                                  className="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 border border-input bg-background hover:bg-accent hover:text-accent-foreground h-9 px-3"
                                >
                                  معاينة
                                </Link>
                              )}
                            </div>
                            {entry.referenceType === 'purchase_order' && (
                              <p className="m-0">{tAccounting?.documentTypeLabel ?? 'نوع السند'}: {purchaseDocumentTypeLabel}</p>
                            )}
                            {relatedSupplierName && (
                              <p className="m-0">{tAccounting?.supplier ?? 'المورد'}: {relatedSupplierName}</p>
                            )}
                            <p>{tAccounting?.date ?? 'التاريخ'}: {format(parseStableEntryDate(entry.date), "PPPp", { locale: locale === 'ar' ? ar : undefined })}</p>
                            {safeCurrencyCode && (
                              <p className="m-0 text-primary font-medium">
                                {tAccounting?.currency ?? 'العملة'}: {safeCurrencyCode}
                                {safeCurrencyCode !== baseCurrencyCode ? ` — 1 ${safeCurrencyCode} = ${entryFxRate} ${baseCurrencyCode}` : ''}
                              </p>
                            )}
                          </div>
                        </div>
                        {(() => {
                          const hasFx = entryDocumentCurrency !== baseCurrencyCode;
                          return (
                            <Table>
                              <TableHeader>
                                <TableRow>
                                  <TableHead>{tAccounting?.accountCode ?? 'رمز الحساب'}</TableHead>
                                  <TableHead>{tAccounting?.accountName ?? 'اسم الحساب'}</TableHead>
                                  {hasFx && (
                                    <>
                                      <TableHead className="text-end">{tAccounting?.debit ?? 'مدين'} ({entryDocumentCurrency})</TableHead>
                                      <TableHead className="text-end">{tAccounting?.credit ?? 'دائن'} ({entryDocumentCurrency})</TableHead>
                                    </>
                                  )}
                                  <TableHead className="text-end">{tAccounting?.debit ?? 'مدين'} ({baseCurrencyCode})</TableHead>
                                  <TableHead className="text-end">{tAccounting?.credit ?? 'دائن'} ({baseCurrencyCode})</TableHead>
                                </TableRow>
                              </TableHeader>
                              <TableBody>
                                {Array.isArray(entry.lines) && entry.lines.map((line, index) => {
                                  const originalDebit = Number(line.originalDebit ?? (line.debit > 0 ? line.debit * entryFxRate : 0));
                                  const originalCredit = Number(line.originalCredit ?? (line.credit > 0 ? line.credit * entryFxRate : 0));
                                  const originalCurrency = String(line.currencyCode || entryDocumentCurrency || baseCurrencyCode).trim();
                                  const safeAccountCode = typeof line.accountCode === 'object' ? (line.accountCode as any)?.code || (line.accountCode as any)?.id || '' : String(line.accountCode || '');
                                  const safeAccountName = typeof line.accountName === 'object' ? (line.accountName as any)?.name || (line.accountName as any)?.id || '' : String(line.accountName || '');

                                  return (
                                    <TableRow key={index}>
                                      <TableCell className="font-mono">{safeAccountCode}</TableCell>
                                      <TableCell>{safeAccountName}</TableCell>
                                      {hasFx && (
                                        <>
                                          <TableCell className="text-end font-mono text-muted-foreground">
                                            {originalDebit > 0 ? formatOriginalAmount(originalDebit, originalCurrency) : '-'}
                                          </TableCell>
                                          <TableCell className="text-end font-mono text-muted-foreground">
                                            {originalCredit > 0 ? formatOriginalAmount(originalCredit, originalCurrency) : '-'}
                                          </TableCell>
                                        </>
                                      )}
                                      <TableCell className="text-end font-mono">
                                        {line.debit > 0 ? formatAmount(line.debit) : '-'}
                                      </TableCell>
                                      <TableCell className="text-end font-mono">
                                        {line.credit > 0 ? formatAmount(line.credit) : '-'}
                                      </TableCell>
                                    </TableRow>
                                  );
                                })}
                              </TableBody>
                              <TableFooter>
                                <TableRow>
                                  <TableCell colSpan={hasFx ? 2 : 2} className="text-end font-bold">
                                    {tAccounting?.total ?? 'الإجمالي'}
                                  </TableCell>
                                  {hasFx && (
                                    <>
                                      <TableCell className="text-end font-bold font-mono text-muted-foreground">
                                        {formatOriginalAmount(
                                          safeLines.reduce((s, l) => s + Number(l.originalDebit ?? (l.debit > 0 ? l.debit * entryFxRate : 0)), 0),
                                          entryDocumentCurrency || baseCurrencyCode,
                                        )}
                                      </TableCell>
                                      <TableCell className="text-end font-bold font-mono text-muted-foreground">
                                        {formatOriginalAmount(
                                          safeLines.reduce((s, l) => s + Number(l.originalCredit ?? (l.credit > 0 ? l.credit * entryFxRate : 0)), 0),
                                          entryDocumentCurrency || baseCurrencyCode,
                                        )}
                                      </TableCell>
                                    </>
                                  )}
                                  <TableCell className="text-end font-bold font-mono">
                                    {formatAmount(totalDebit)}
                                  </TableCell>
                                  <TableCell className="text-end font-bold font-mono">
                                    {formatAmount(totalCredit)}
                                  </TableCell>
                                </TableRow>
                              </TableFooter>
                            </Table>
                          );
                        })()}
                      </div>
                    </AccordionContent>
                  </AccordionItem>
                );
              })}
            </Accordion>
          )}
        </CardContent>
      </Card>
    </div>
  );
}
