'use client';

import { useMemo, useState } from 'react';
import { CardContent } from '@/components/ui/card';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { formatCurrency } from '@/lib/currency-formatter';

type BalanceRow = {
  id: string;
  name: string;
  type: 'customer' | 'supplier';
  accountCode?: string;
  balancePostedOnly: number;
  balanceAllEntries: number;
  searchText?: string;
};

type Props = {
  rows: BalanceRow[];
  currencySymbol: string;
};

function normalizeArabicForSearch(value: string): string {
  return value
    .toLowerCase()
    .replace(/[\u064B-\u0652\u0670]/g, '')
    .replace(/ـ/g, '')
    .replace(/[أإآٱ]/g, 'ا')
    .replace(/ة/g, 'ه')
    .replace(/ى/g, 'ي')
    .replace(/ؤ/g, 'و')
    .replace(/ئ/g, 'ي')
    .replace(/\s+/g, ' ')
    .trim();
}

function splitSearchTokens(value: string): string[] {
  const normalized = normalizeArabicForSearch(value);
  if (!normalized) return [];
  return normalized.split(' ').filter(Boolean);
}

function isWithinOneEditDistance(source: string, target: string): boolean {
  if (source === target) return true;

  const sourceLength = source.length;
  const targetLength = target.length;
  if (Math.abs(sourceLength - targetLength) > 1) return false;

  if (sourceLength === targetLength) {
    let mismatches = 0;
    for (let index = 0; index < sourceLength; index += 1) {
      if (source[index] !== target[index]) {
        mismatches += 1;
        if (mismatches > 1) return false;
      }
    }
    return true;
  }

  const shorter = sourceLength < targetLength ? source : target;
  const longer = sourceLength < targetLength ? target : source;

  let shortIndex = 0;
  let longIndex = 0;
  let skipped = false;

  while (shortIndex < shorter.length && longIndex < longer.length) {
    if (shorter[shortIndex] === longer[longIndex]) {
      shortIndex += 1;
      longIndex += 1;
      continue;
    }

    if (skipped) return false;
    skipped = true;
    longIndex += 1;
  }

  return true;
}

function matchesTokenWithTolerance(queryToken: string, searchableText: string, searchableTokens: string[]): boolean {
  if (searchableText.includes(queryToken)) return true;

  if (queryToken.length < 3) return false;

  return searchableTokens.some((token) => {
    if (Math.abs(token.length - queryToken.length) > 1) return false;
    return isWithinOneEditDistance(token, queryToken);
  });
}

export default function BalancesReportClient({ rows, currencySymbol }: Props) {
  const [searchQuery, setSearchQuery] = useState('');
  const [typeFilter, setTypeFilter] = useState<'all' | 'customer' | 'supplier'>('all');
  const [statusFilter, setStatusFilter] = useState<'all' | 'debit' | 'credit'>('all');
  const [entryMode, setEntryMode] = useState<'all_entries' | 'posted_only'>('all_entries');

  const getRowBalance = (row: BalanceRow) => (
    entryMode === 'posted_only' ? Number(row.balancePostedOnly || 0) : Number(row.balanceAllEntries || 0)
  );

  const filteredRows = useMemo(() => {
    const queryTokens = splitSearchTokens(searchQuery);

    return rows.filter((row) => {
      const typeLabel = row.type === 'customer' ? 'زبون' : 'مورد';
      const rowBalance = getRowBalance(row);
      const statusLabel = rowBalance > 0 ? 'مدين' : rowBalance < 0 ? 'دائن' : 'متوازن';
      const searchableText = normalizeArabicForSearch(
        [row.name, row.accountCode || '', typeLabel, statusLabel, row.searchText || ''].join(' ')
      );
      const searchableTokens = searchableText.split(' ').filter(Boolean);

      const matchesSearch =
        queryTokens.length === 0 ||
        queryTokens.every((token) => matchesTokenWithTolerance(token, searchableText, searchableTokens));

      const matchesType = typeFilter === 'all' || row.type === typeFilter;
      const matchesStatus =
        statusFilter === 'all' ||
        (statusFilter === 'debit' && getRowBalance(row) > 0) ||
        (statusFilter === 'credit' && getRowBalance(row) < 0);

      return matchesSearch && matchesType && matchesStatus;
    });
  }, [rows, searchQuery, typeFilter, statusFilter, entryMode]);

  const stats = useMemo(() => {
    const totalDebit = filteredRows
      .filter((row) => getRowBalance(row) > 0)
      .reduce((sum, row) => sum + getRowBalance(row), 0);
    const totalCredit = filteredRows
      .filter((row) => getRowBalance(row) < 0)
      .reduce((sum, row) => sum + Math.abs(getRowBalance(row)), 0);
    const netBalance = totalDebit - totalCredit;
    const customerCount = filteredRows.filter((row) => row.type === 'customer').length;
    const supplierCount = filteredRows.filter((row) => row.type === 'supplier').length;

    return {
      totalDebit,
      totalCredit,
      netBalance,
      customerCount,
      supplierCount,
      count: filteredRows.length,
    };
  }, [filteredRows, entryMode]);

  const hasActiveFilters = Boolean(searchQuery.trim()) || typeFilter !== 'all' || statusFilter !== 'all' || entryMode !== 'all_entries';
  const fmt = (amount: number) => formatCurrency(amount, currencySymbol);

  return (
    <CardContent className="space-y-4">
      <div className="grid grid-cols-1 gap-3 md:grid-cols-5">
        <Input
          value={searchQuery}
          onChange={(event) => setSearchQuery(event.target.value)}
          placeholder="ابحث بأي معلومة (الاسم، الهاتف، العنوان، رمز الحساب...)"
        />
        <Select value={typeFilter} onValueChange={(value) => setTypeFilter(value as 'all' | 'customer' | 'supplier')}>
          <SelectTrigger>
            <SelectValue placeholder="نوع الطرف" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="all">كل الأنواع</SelectItem>
            <SelectItem value="customer">زبائن</SelectItem>
            <SelectItem value="supplier">موردين</SelectItem>
          </SelectContent>
        </Select>
        <Select value={statusFilter} onValueChange={(value) => setStatusFilter(value as 'all' | 'debit' | 'credit')}>
          <SelectTrigger>
            <SelectValue placeholder="الحالة" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="all">كل الحالات</SelectItem>
            <SelectItem value="debit">مدين</SelectItem>
            <SelectItem value="credit">دائن</SelectItem>
          </SelectContent>
        </Select>
        <Select value={entryMode} onValueChange={(value) => setEntryMode(value as 'all_entries' | 'posted_only')}>
          <SelectTrigger>
            <SelectValue placeholder="القيود المحتسبة" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="all_entries">الأصلية + المسودة</SelectItem>
            <SelectItem value="posted_only">الأصلية فقط</SelectItem>
          </SelectContent>
        </Select>
        <Button
          type="button"
          variant="outline"
          disabled={!hasActiveFilters}
          onClick={() => {
            setSearchQuery('');
            setTypeFilter('all');
            setStatusFilter('all');
            setEntryMode('all_entries');
          }}
        >
          إزالة التصفية
        </Button>
      </div>

      <div className="grid grid-cols-1 gap-4 md:grid-cols-5">
        <div className="rounded-md border p-4">
          <p className="text-sm text-muted-foreground">الذمم بعد التصفية</p>
          <p className="text-2xl font-bold">{stats.count}</p>
        </div>
        <div className="rounded-md border p-4">
          <p className="text-sm text-muted-foreground">عدد الزبائن</p>
          <p className="text-2xl font-bold">{stats.customerCount}</p>
        </div>
        <div className="rounded-md border p-4">
          <p className="text-sm text-muted-foreground">عدد الموردين</p>
          <p className="text-2xl font-bold">{stats.supplierCount}</p>
        </div>
        <div className="rounded-md border p-4">
          <p className="text-sm text-muted-foreground">إجمالي المدين (بعد التصفية)</p>
          <p className="text-2xl font-bold text-red-600">{fmt(stats.totalDebit)}</p>
        </div>
        <div className="rounded-md border p-4">
          <p className="text-sm text-muted-foreground">إجمالي الدائن (بعد التصفية)</p>
          <p className="text-2xl font-bold text-green-600">{fmt(stats.totalCredit)}</p>
        </div>
      </div>

      <div className="rounded-md border p-4">
        <p className="text-sm text-muted-foreground">صافي الرصيد بعد التصفية</p>
        <p className={`text-2xl font-bold ${stats.netBalance >= 0 ? 'text-red-600' : 'text-green-600'}`}>
          {fmt(Math.abs(stats.netBalance))} {stats.netBalance >= 0 ? '(مدين)' : '(دائن)'}
        </p>
      </div>

      <div className="overflow-x-auto rounded-md border">
        <Table>
          <TableHeader>
            <TableRow>
              <TableHead>الاسم</TableHead>
              <TableHead>النوع</TableHead>
              <TableHead>رمز الحساب</TableHead>
              <TableHead className="text-right">الرصيد</TableHead>
              <TableHead className="text-right">الحالة</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {filteredRows.length === 0 ? (
              <TableRow>
                <TableCell colSpan={5} className="py-8 text-center text-muted-foreground">
                  لا توجد نتائج مطابقة للتصفية الحالية.
                </TableCell>
              </TableRow>
            ) : (
              filteredRows.map((row) => {
                const balance = getRowBalance(row);
                const status = balance > 0 ? 'مدين' : balance < 0 ? 'دائن' : 'متوازن';
                return (
                  <TableRow key={row.id}>
                    <TableCell className="font-medium">{row.name}</TableCell>
                    <TableCell>{row.type === 'customer' ? 'زبون' : 'مورد'}</TableCell>
                    <TableCell>{row.accountCode || '-'}</TableCell>
                    <TableCell className="text-right">{fmt(Math.abs(balance))}</TableCell>
                    <TableCell
                      className={`text-right font-semibold ${
                        balance > 0 ? 'text-red-600' : balance < 0 ? 'text-green-600' : 'text-muted-foreground'
                      }`}
                    >
                      {status}
                    </TableCell>
                  </TableRow>
                );
              })
            )}
          </TableBody>
        </Table>
      </div>
    </CardContent>
  );
}
