'use client';

import { useMemo, useState, useTransition } from 'react';
import { Plus, Trash2 } from 'lucide-react';
import { useRouter } from 'next/navigation';

import { Button } from '@/components/ui/button';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import AccountCodeSelector from '@/components/admin/account-code-selector';
import { useToast } from '@/hooks/use-toast';
import { handleCreateManualJournalEntry } from '@/lib/actions';

type AccountOption = {
  id: string;
  code: string;
  nameAr: string;
  nameEn: string;
  type: 'header' | 'account';
  inactive?: boolean;
};

type JournalLineDraft = {
  accountCode: string;
  debit: string;
  credit: string;
  description: string;
};

const makeEmptyLine = (): JournalLineDraft => ({
  accountCode: '',
  debit: '',
  credit: '',
  description: '',
});

function formatAsDateInput(value: Date) {
  const year = value.getFullYear();
  const month = String(value.getMonth() + 1).padStart(2, '0');
  const day = String(value.getDate()).padStart(2, '0');
  return `${year}-${month}-${day}`;
}

function parseMoney(text: string) {
  const value = Number(String(text || '').replace(/,/g, '').trim());
  if (!Number.isFinite(value)) return 0;
  return Math.max(0, value);
}

export function ManualJournalEntryDialog({ accounts }: { accounts: AccountOption[] }) {
  const router = useRouter();
  const { toast } = useToast();
  const [isPending, startTransition] = useTransition();

  const [open, setOpen] = useState(false);
  const [date, setDate] = useState(formatAsDateInput(new Date()));
  const [description, setDescription] = useState('');
  const [lines, setLines] = useState<JournalLineDraft[]>([makeEmptyLine(), makeEmptyLine()]);

  const accountOptions = useMemo(
    () => (accounts || [])
      .filter((account) => account.type === 'account' && !account.inactive)
      .sort((a, b) => String(a.code || '').localeCompare(String(b.code || ''), 'en', { numeric: true }))
      .map((account) => ({
        code: String(account.code || '').trim(),
        label: `${String(account.code || '').trim()} - ${String(account.nameAr || account.nameEn || '').trim()}`,
      })),
    [accounts],
  );

  const totals = useMemo(() => {
    const totalDebit = lines.reduce((sum, line) => sum + parseMoney(line.debit), 0);
    const totalCredit = lines.reduce((sum, line) => sum + parseMoney(line.credit), 0);
    return { totalDebit, totalCredit, balanced: Math.abs(totalDebit - totalCredit) <= 0.01 };
  }, [lines]);

  const resetForm = () => {
    setDate(formatAsDateInput(new Date()));
    setDescription('');
    setLines([makeEmptyLine(), makeEmptyLine()]);
  };

  const updateLine = (index: number, key: keyof JournalLineDraft, value: string) => {
    setLines((current) => current.map((line, idx) => (idx === index ? { ...line, [key]: value } : line)));
  };

  const addLine = () => {
    setLines((current) => [...current, makeEmptyLine()]);
  };

  const removeLine = (index: number) => {
    setLines((current) => {
      if (current.length <= 2) return current;
      return current.filter((_, idx) => idx !== index);
    });
  };

  const submit = () => {
    const safeDescription = String(description || '').trim();
    if (!date) {
      toast({ title: 'خطأ', description: 'يرجى تحديد تاريخ السند.', variant: 'destructive' });
      return;
    }
    if (safeDescription.length < 3) {
      toast({ title: 'خطأ', description: 'يرجى إدخال وصف واضح للسند.', variant: 'destructive' });
      return;
    }

    const payloadLines = lines
      .map((line) => ({
        accountCode: String(line.accountCode || '').trim(),
        debit: parseMoney(line.debit),
        credit: parseMoney(line.credit),
        description: String(line.description || '').trim(),
      }))
      .filter((line) => line.accountCode || line.debit > 0 || line.credit > 0 || line.description);

    if (payloadLines.length < 2) {
      toast({ title: 'خطأ', description: 'يجب إدخال سطرين على الأقل في القيد.', variant: 'destructive' });
      return;
    }

    const hasInvalidRow = payloadLines.some((line) => {
      if (!line.accountCode) return true;
      if (line.debit <= 0 && line.credit <= 0) return true;
      if (line.debit > 0 && line.credit > 0) return true;
      return false;
    });

    if (hasInvalidRow) {
      toast({
        title: 'خطأ',
        description: 'كل سطر يجب أن يحتوي حساباً ومبلغاً في جهة واحدة فقط (مدين أو دائن).',
        variant: 'destructive',
      });
      return;
    }

    const totalDebit = payloadLines.reduce((sum, line) => sum + line.debit, 0);
    const totalCredit = payloadLines.reduce((sum, line) => sum + line.credit, 0);
    if (Math.abs(totalDebit - totalCredit) > 0.01) {
      toast({ title: 'خطأ', description: 'القيد غير متوازن: مجموع المدين يجب أن يساوي مجموع الدائن.', variant: 'destructive' });
      return;
    }

    startTransition(async () => {
      const result = await handleCreateManualJournalEntry({
        date,
        description: safeDescription,
        lines: payloadLines,
      });

      if (!result?.success) {
        const errorCode = String((result as { error?: string })?.error || 'UNKNOWN_ERROR');
        const message = errorCode.startsWith('ACCOUNT_NOT_FOUND:')
          ? `الحساب غير موجود أو غير نشط: ${errorCode.replace('ACCOUNT_NOT_FOUND:', '')}`
          : errorCode === 'ENTRY_NOT_BALANCED'
            ? 'القيد غير متوازن.'
            : errorCode === 'LINE_AMOUNT_REQUIRED'
              ? 'كل سطر يجب أن يحتوي مبلغاً.'
              : errorCode === 'LINE_DEBIT_AND_CREDIT_NOT_ALLOWED'
                ? 'لا يمكن إدخال مدين ودائن في نفس السطر.'
                : errorCode === 'INVALID_INPUT'
                  ? 'البيانات المدخلة غير صحيحة.'
                  : 'فشل إنشاء سند القيد اليدوي.';

        toast({ title: 'تعذر الحفظ', description: message, variant: 'destructive' });
        return;
      }

      toast({ title: 'تم الحفظ', description: `تم إنشاء سند القيد كمسودة برقم ${result.entryId}.` });
      setOpen(false);
      resetForm();
      router.refresh();
    });
  };

  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogTrigger asChild>
        <Button type="button" className="gap-2">
          <Plus className="h-4 w-4" />
          إنشاء سند قيد يدوي
        </Button>
      </DialogTrigger>
      <DialogContent className="sm:max-w-4xl max-h-[90vh] overflow-y-auto">
        <DialogHeader>
          <DialogTitle>سند قيد يدوي</DialogTitle>
          <DialogDescription>
            أدخل جميع أركان القيد المحاسبي، وسيتم الحفظ كمسودة بانتظار المراجعة.
          </DialogDescription>
        </DialogHeader>

        <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
          <div className="space-y-1">
            <label className="text-sm font-medium">تاريخ القيد</label>
            <Input type="date" value={date} onChange={(event) => setDate(event.target.value)} />
          </div>
          <div className="space-y-1 md:col-span-1">
            <label className="text-sm font-medium">الوصف</label>
            <Input
              value={description}
              onChange={(event) => setDescription(event.target.value)}
              placeholder="مثال: قيد تسوية رصيد افتتاحي"
              maxLength={500}
            />
          </div>
        </div>

        <div className="space-y-2">
          <div className="grid grid-cols-12 gap-2 px-1 text-xs font-medium text-muted-foreground">
            <div className="col-span-4">الحساب</div>
            <div className="col-span-2">مدين</div>
            <div className="col-span-2">دائن</div>
            <div className="col-span-3">البيان</div>
            <div className="col-span-1">حذف</div>
          </div>

          {lines.map((line, index) => (
            <div key={`line-${index}`} className="grid grid-cols-12 gap-2 items-start">
              <div className="col-span-4">
                <AccountCodeSelector
                  value={line.accountCode}
                  options={accountOptions}
                  placeholder="اختر حساباً"
                  disablePortal
                  onValueChange={(value) => updateLine(index, 'accountCode', value)}
                />
              </div>
              <div className="col-span-2">
                <Input
                  type="number"
                  min="0"
                  step="0.01"
                  value={line.debit}
                  onChange={(event) => updateLine(index, 'debit', event.target.value)}
                  placeholder="0.00"
                />
              </div>
              <div className="col-span-2">
                <Input
                  type="number"
                  min="0"
                  step="0.01"
                  value={line.credit}
                  onChange={(event) => updateLine(index, 'credit', event.target.value)}
                  placeholder="0.00"
                />
              </div>
              <div className="col-span-3">
                <Textarea
                  value={line.description}
                  onChange={(event) => updateLine(index, 'description', event.target.value)}
                  placeholder="وصف السطر (اختياري)"
                  className="min-h-10"
                />
              </div>
              <div className="col-span-1">
                <Button
                  type="button"
                  variant="outline"
                  size="icon"
                  onClick={() => removeLine(index)}
                  disabled={lines.length <= 2}
                  title="حذف السطر"
                >
                  <Trash2 className="h-4 w-4" />
                </Button>
              </div>
            </div>
          ))}

          <Button type="button" variant="secondary" onClick={addLine} className="w-fit">
            إضافة سطر
          </Button>
        </div>

        <div className="rounded-md border bg-muted/30 p-3 text-sm space-y-1">
          <div className="flex items-center justify-between">
            <span>مجموع المدين</span>
            <span className="font-mono">{totals.totalDebit.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
          </div>
          <div className="flex items-center justify-between">
            <span>مجموع الدائن</span>
            <span className="font-mono">{totals.totalCredit.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
          </div>
          <div className="flex items-center justify-between font-semibold">
            <span>حالة التوازن</span>
            <span className={totals.balanced ? 'text-emerald-700' : 'text-rose-700'}>
              {totals.balanced ? 'متوازن' : 'غير متوازن'}
            </span>
          </div>
        </div>

        <DialogFooter>
          <Button type="button" variant="outline" onClick={() => setOpen(false)} disabled={isPending}>
            إلغاء
          </Button>
          <Button type="button" onClick={submit} disabled={isPending}>
            {isPending ? 'جاري الحفظ...' : 'حفظ كمسودة'}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
