'use client';

import { useEffect, useMemo, useState } from 'react';
import * as z from 'zod';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '@/components/ui/dialog';
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form';
import { useToast } from '@/hooks/use-toast';
import { useDocumentLock } from '@/hooks/use-document-lock';
import type { ChartOfAccount, GeneralBank } from '@/lib/types';
import { Pencil, Trash2 } from 'lucide-react';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Textarea } from '@/components/ui/textarea';
import { Checkbox } from '@/components/ui/checkbox';
import AccountCodeSelector, { type AccountCodeOption } from '@/components/admin/account-code-selector';
import { DocumentLockBanner } from '@/components/admin/document-lock-banner';

const generalBankSchema = z.object({
  code: z.string().trim().min(1, 'Bank code is required'),
  name: z.string().trim().min(1, 'Arabic name is required'),
  nameEn: z.string().trim().min(1, 'English name is required'),
  accountId: z.string().optional(),
  accountCode: z.string().optional(),
  swiftCode: z.string().trim().optional(),
  branchCode: z.string().trim().optional(),
  branch: z.string().trim().optional(),
  country: z.string().trim().optional(),
  city: z.string().trim().optional(),
  address: z.string().trim().optional(),
  phone: z.string().trim().optional(),
  email: z.string().email().optional().or(z.literal('')),
  ibanPattern: z.string().trim().optional(),
  notes: z.string().trim().optional(),
  isActive: z.boolean().optional().default(true),
});

type GeneralBankValues = z.infer<typeof generalBankSchema>;

export function GeneralBanksManager({
  initialBanks,
  chartOfAccounts,
  t,
  tGlobal,
}: {
  initialBanks: GeneralBank[];
  chartOfAccounts: ChartOfAccount[];
  t: any;
  tGlobal: any;
}) {
  const { toast } = useToast();
  const [banks, setBanks] = useState<GeneralBank[]>(initialBanks);
  const [editing, setEditing] = useState<GeneralBank | null>(null);
  const [search, setSearch] = useState('');
  const [isAdding, setIsAdding] = useState(false);
  const [accountCodeEditedManually, setAccountCodeEditedManually] = useState(false);

  const accountOptions: AccountCodeOption[] = useMemo(
    () => (chartOfAccounts || [])
      .filter((acc) => acc.type === 'account')
      .map((acc) => ({ code: acc.code, label: `${acc.code} - ${acc.nameAr}` })),
    [chartOfAccounts],
  );

  const accountsByCode = useMemo(
    () => new Map((chartOfAccounts || []).map((acc) => [String(acc.code || '').trim(), acc])),
    [chartOfAccounts],
  );

  const form = useForm<GeneralBankValues>({
    resolver: zodResolver(generalBankSchema),
    defaultValues: {
      code: '',
      name: '',
      nameEn: '',
      accountId: '',
      accountCode: '',
      swiftCode: '',
      branchCode: '',
      branch: '',
      country: '',
      city: '',
      address: '',
      phone: '',
      email: '',
      ibanPattern: '',
      notes: '',
      isActive: true,
    },
  });

  const filteredBanks = useMemo(() => {
    const q = search.toLowerCase().trim();
    if (!q) return banks;
    return banks.filter((b) =>
      [b.code, b.name, b.nameEn, b.swiftCode, b.branch, b.city, b.country, b.accountCode]
        .filter(Boolean)
        .some((v) => String(v).toLowerCase().includes(q))
    );
  }, [banks, search]);

  const dialogOpen = !!(editing || isAdding);
  const { lockStatus } = useDocumentLock('general-bank', editing?.id || '', { enabled: !!editing?.id });
  const isEditLocked = !!editing && lockStatus.isLocked;
  const watchedCode = String(form.watch('code') || '');
  const watchedName = String(form.watch('name') || '');
  const watchedNameEn = String(form.watch('nameEn') || '');
  const watchedCountry = String(form.watch('country') || '');

  const normalize = (value: string) => String(value || '').trim().toLowerCase();

  const findBestGeneralBankAccountCode = (code: string, name: string, nameEn: string, country: string): string => {
    const list = Array.isArray(accountOptions) ? accountOptions : [];
    if (list.length === 0) return '';

    const bankLike = list.filter((entry) => {
      const label = normalize(entry.label);
      return (
        entry.code.startsWith('1120')
        || label.includes('بنك')
        || label.includes('bank')
        || label.includes('شيك')
        || label.includes('check')
      );
    });
    const candidates = bankLike.length > 0 ? bankLike : list;

    const tokens = [normalize(code), normalize(name), normalize(nameEn), normalize(country)]
      .filter((entry) => entry.length > 1);

    const byToken = candidates.find((entry) => {
      const label = normalize(entry.label);
      return tokens.some((token) => label.includes(token));
    });
    if (byToken) return byToken.code;

    const exact1120 = candidates.find((entry) => entry.code === '1120');
    if (exact1120) return exact1120.code;

    const starts1120 = candidates.find((entry) => entry.code.startsWith('1120'));
    if (starts1120) return starts1120.code;

    return candidates[0]?.code || '';
  };

  const autoAssignAccountCode = () => {
    if (accountCodeEditedManually) return;
    const currentValue = String(form.getValues('accountCode') || '').trim();
    if (currentValue) return;

    const nextCode = findBestGeneralBankAccountCode(watchedCode, watchedName, watchedNameEn, watchedCountry);
    if (!nextCode) return;

    form.setValue('accountCode', nextCode, { shouldDirty: true, shouldValidate: true });
    const matched = accountsByCode.get(nextCode);
    form.setValue('accountId', String(matched?.id || ''), { shouldDirty: true, shouldValidate: false });
  };

  useEffect(() => {
    if (!dialogOpen) return;
    autoAssignAccountCode();
  }, [dialogOpen, watchedCode, watchedName, watchedNameEn, watchedCountry, accountCodeEditedManually, accountOptions]);

  const startEdit = (bank: GeneralBank) => {
    setIsAdding(false);
    setEditing(bank);
    setAccountCodeEditedManually(false);
    form.reset({
      code: bank.code || '',
      name: bank.name || '',
      nameEn: bank.nameEn || '',
      accountId: bank.accountId || '',
      accountCode: bank.accountCode || '',
      swiftCode: bank.swiftCode || '',
      branchCode: bank.branchCode || '',
      branch: bank.branch || '',
      country: bank.country || '',
      city: bank.city || '',
      address: bank.address || '',
      phone: bank.phone || '',
      email: bank.email || '',
      ibanPattern: bank.ibanPattern || '',
      notes: bank.notes || '',
      isActive: bank.isActive !== false,
    });
  };

  const startAdd = () => {
    setIsAdding(true);
    setEditing(null);
    setAccountCodeEditedManually(false);
    form.reset({
      code: '',
      name: '',
      nameEn: '',
      accountId: '',
      accountCode: '',
      swiftCode: '',
      branchCode: '',
      branch: '',
      country: '',
      city: '',
      address: '',
      phone: '',
      email: '',
      ibanPattern: '',
      notes: '',
      isActive: true,
    });
  };

  const onSave = async (values: GeneralBankValues) => {
    if (isEditLocked) return;

    try {
      const selectedAccountCode = String(values.accountCode || '').trim();
      const selectedAccount = accountsByCode.get(selectedAccountCode);
      const payload = {
        ...values,
        accountCode: selectedAccountCode || undefined,
        accountId: String(selectedAccount?.id || values.accountId || '').trim() || undefined,
      };

      if (editing) {
        const response = await fetch('/api/general-banks', {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ id: editing.id, ...payload }),
        });

        if (!response.ok) {
          toast({
            title: tGlobal?.error ?? 'Error',
            description: 'تعذر تحديث بيانات البنك.',
            variant: 'destructive',
          });
          return;
        }

        const updated = await response.json();
        setBanks((prev) => prev.map((b) => (b.id === updated.id ? updated : b)));
        setEditing(null);
        toast({
          title: tGlobal?.success ?? 'Success',
          description: 'تم تحديث بيانات البنك بنجاح.',
        });
      } else {
        const response = await fetch('/api/general-banks', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(payload),
        });

        if (!response.ok) {
          toast({
            title: tGlobal?.error ?? 'Error',
            description: 'تعذر إضافة البنك.',
            variant: 'destructive',
          });
          return;
        }

        const newBank = await response.json();
        setBanks((prev) => [newBank, ...prev]);
        setIsAdding(false);
        toast({
          title: tGlobal?.success ?? 'Success',
          description: 'تمت إضافة البنك بنجاح.',
        });
      }
    } catch (error) {
      console.error('Error saving bank:', error);
      toast({
        title: tGlobal?.error ?? 'Error',
        description: 'حدث خطأ غير متوقع.',
        variant: 'destructive',
      });
    }
  };

  const onDelete = async (id: string) => {
    const confirmed = typeof window !== 'undefined' ? window.confirm('هل تريد حذف هذا البنك؟') : true;
    if (!confirmed) return;

    try {
      const response = await fetch(`/api/general-banks?id=${encodeURIComponent(id)}`, { method: 'DELETE' });
      if (!response.ok) {
        toast({
          title: tGlobal?.error ?? 'Error',
          description: 'تعذر حذف البنك.',
          variant: 'destructive',
        });
        return;
      }

      setBanks((prev) => prev.filter((b) => b.id !== id));
      toast({
        title: tGlobal?.success ?? 'Success',
        description: 'تم حذف البنك بنجاح.',
      });
    } catch (error) {
      console.error('Error deleting bank:', error);
      toast({
        title: tGlobal?.error ?? 'Error',
        description: 'حدث خطأ غير متوقع.',
        variant: 'destructive',
      });
    }
  };

  return (
    <Card>
      <CardHeader>
        <CardTitle>General Banks</CardTitle>
        <CardDescription>Manage reference banks for incoming checks and customer payments</CardDescription>
      </CardHeader>
      <CardContent className="space-y-4">
        <div className="flex flex-col gap-2 md:flex-row md:items-center md:justify-between">
          <Input
            placeholder="Search banks..."
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="md:max-w-sm"
          />
          <Button onClick={startAdd}>Add Bank</Button>
        </div>

        <div className="rounded-md border overflow-auto">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead>Code</TableHead>
                <TableHead>Arabic Name</TableHead>
                <TableHead>English Name</TableHead>
                <TableHead>SWIFT Code</TableHead>
                <TableHead>Country</TableHead>
                <TableHead>City</TableHead>
                <TableHead>Account</TableHead>
                <TableHead className="text-center">Active</TableHead>
                <TableHead className="text-right">Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {filteredBanks.length === 0 ? (
                <TableRow>
                  <TableCell colSpan={9} className="text-center text-muted-foreground py-8">
                    No banks found
                  </TableCell>
                </TableRow>
              ) : (
                filteredBanks.map((bank) => (
                  <TableRow key={bank.id}>
                    <TableCell className="font-medium">{bank.code}</TableCell>
                    <TableCell>{bank.name}</TableCell>
                    <TableCell>{bank.nameEn}</TableCell>
                    <TableCell>{bank.swiftCode || '-'}</TableCell>
                    <TableCell>{bank.country || '-'}</TableCell>
                    <TableCell>{bank.city || '-'}</TableCell>
                    <TableCell>{bank.accountCode || '-'}</TableCell>
                    <TableCell className="text-center">
                      {bank.isActive !== false ? '✓' : '-'}
                    </TableCell>
                    <TableCell className="text-right">
                      <div className="inline-flex items-center gap-1">
                        <Button
                          type="button"
                          size="icon"
                          variant="outline"
                          onClick={() => startEdit(bank)}
                        >
                          <Pencil className="h-4 w-4" />
                        </Button>
                        <Button
                          type="button"
                          size="icon"
                          variant="destructive"
                          onClick={() => onDelete(bank.id)}
                        >
                          <Trash2 className="h-4 w-4" />
                        </Button>
                      </div>
                    </TableCell>
                  </TableRow>
                ))
              )}
            </TableBody>
          </Table>
        </div>
      </CardContent>

      <Dialog
        open={dialogOpen}
        onOpenChange={(open) => {
          if (!open) {
            setEditing(null);
            setIsAdding(false);
            setAccountCodeEditedManually(false);
          }
        }}
      >
        <DialogContent className="w-[96vw] max-w-4xl max-h-[92vh] overflow-hidden p-0">
          <DialogHeader>
            <div className="px-6 pt-6">
              <DialogTitle>
                {editing ? 'Edit Bank' : 'Add Bank'}
              </DialogTitle>
              <DialogDescription className="sr-only">
                {editing ? 'Update general bank details.' : 'Create a new general bank record.'}
              </DialogDescription>
            </div>
          </DialogHeader>
          <Form {...form}>
            <form onSubmit={form.handleSubmit(onSave)} className="h-full flex flex-col min-h-0">
              {editing && (
                <div className="px-6 pt-2">
                  <DocumentLockBanner lockStatus={lockStatus} />
                </div>
              )}
              <div className="px-6 pb-4 border-b">
                <Tabs defaultValue="identity" className="w-full">
                  <TabsList className="grid w-full grid-cols-4">
                    <TabsTrigger value="identity">Basic</TabsTrigger>
                    <TabsTrigger value="branch">Branch</TabsTrigger>
                    <TabsTrigger value="contact">Contact</TabsTrigger>
                    <TabsTrigger value="accounting">Accounting</TabsTrigger>
                  </TabsList>

                  <div className="mt-4 max-h-[58vh] overflow-y-auto pe-1">
                    <TabsContent value="identity" className="space-y-4 m-0">
                      <div className="rounded-lg border p-4 space-y-4">
                        <p className="text-sm font-medium">Bank Identity</p>
                        <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
                          <FormField control={form.control} name="code" render={({ field }) => (
                            <FormItem>
                              <FormLabel>Bank Code *</FormLabel>
                              <FormControl><Input {...field} placeholder="e.g., CBJO" /></FormControl>
                              <FormMessage />
                            </FormItem>
                          )} />
                          <FormField control={form.control} name="swiftCode" render={({ field }) => (
                            <FormItem>
                              <FormLabel>SWIFT Code</FormLabel>
                              <FormControl><Input {...field} placeholder="11-char or 8-char" /></FormControl>
                              <FormMessage />
                            </FormItem>
                          )} />
                        </div>

                        <FormField control={form.control} name="name" render={({ field }) => (
                          <FormItem>
                            <FormLabel>Arabic Name *</FormLabel>
                            <FormControl><Input {...field} /></FormControl>
                            <FormMessage />
                          </FormItem>
                        )} />

                        <FormField control={form.control} name="nameEn" render={({ field }) => (
                          <FormItem>
                            <FormLabel>English Name *</FormLabel>
                            <FormControl><Input {...field} /></FormControl>
                            <FormMessage />
                          </FormItem>
                        )} />
                      </div>
                    </TabsContent>

                    <TabsContent value="branch" className="space-y-4 m-0">
                      <div className="rounded-lg border p-4 space-y-4">
                        <p className="text-sm font-medium">Branch & Location</p>
                        <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
                          <FormField control={form.control} name="branchCode" render={({ field }) => (
                            <FormItem>
                              <FormLabel>Branch Code</FormLabel>
                              <FormControl><Input {...field} /></FormControl>
                              <FormMessage />
                            </FormItem>
                          )} />
                          <FormField control={form.control} name="branch" render={({ field }) => (
                            <FormItem>
                              <FormLabel>Branch Name</FormLabel>
                              <FormControl><Input {...field} /></FormControl>
                              <FormMessage />
                            </FormItem>
                          )} />
                        </div>

                        <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
                          <FormField control={form.control} name="country" render={({ field }) => (
                            <FormItem>
                              <FormLabel>Country Code</FormLabel>
                              <FormControl><Input {...field} placeholder="JO, US, AE, etc." /></FormControl>
                              <FormMessage />
                            </FormItem>
                          )} />
                          <FormField control={form.control} name="city" render={({ field }) => (
                            <FormItem>
                              <FormLabel>City</FormLabel>
                              <FormControl><Input {...field} /></FormControl>
                              <FormMessage />
                            </FormItem>
                          )} />
                        </div>

                        <FormField control={form.control} name="address" render={({ field }) => (
                          <FormItem>
                            <FormLabel>Address</FormLabel>
                            <FormControl><Input {...field} /></FormControl>
                            <FormMessage />
                          </FormItem>
                        )} />
                      </div>
                    </TabsContent>

                    <TabsContent value="contact" className="space-y-4 m-0">
                      <div className="rounded-lg border p-4 space-y-4">
                        <p className="text-sm font-medium">Contact & Additional</p>
                        <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
                          <FormField control={form.control} name="phone" render={({ field }) => (
                            <FormItem>
                              <FormLabel>Phone</FormLabel>
                              <FormControl><Input {...field} type="tel" /></FormControl>
                              <FormMessage />
                            </FormItem>
                          )} />
                          <FormField control={form.control} name="email" render={({ field }) => (
                            <FormItem>
                              <FormLabel>Email</FormLabel>
                              <FormControl><Input {...field} type="email" /></FormControl>
                              <FormMessage />
                            </FormItem>
                          )} />
                        </div>

                        <FormField control={form.control} name="ibanPattern" render={({ field }) => (
                          <FormItem>
                            <FormLabel>IBAN Pattern</FormLabel>
                            <FormControl><Input {...field} placeholder="e.g., JO94CBJO..." /></FormControl>
                            <FormMessage />
                          </FormItem>
                        )} />

                        <FormField control={form.control} name="notes" render={({ field }) => (
                          <FormItem>
                            <FormLabel>Notes</FormLabel>
                            <FormControl><Textarea {...field} placeholder="Additional information" value={field.value || ''} /></FormControl>
                            <FormMessage />
                          </FormItem>
                        )} />
                      </div>
                    </TabsContent>

                    <TabsContent value="accounting" className="space-y-4 m-0">
                      <div className="rounded-lg border p-4 space-y-3">
                        <p className="text-sm font-medium">Accounting</p>
                        <p className="text-xs text-muted-foreground">
                          Link this reference bank to the most suitable chart-of-accounts bank ledger.
                        </p>
                        <FormField control={form.control} name="accountCode" render={({ field }) => (
                          <FormItem>
                            <FormLabel>Linked Account</FormLabel>
                            <FormControl>
                              <AccountCodeSelector
                                value={field.value || ''}
                                options={accountOptions}
                                placeholder="Optional - select account"
                                onValueChange={(value) => {
                                  setAccountCodeEditedManually(true);
                                  field.onChange(value);
                                  const matched = accountsByCode.get(String(value || '').trim());
                                  form.setValue('accountId', String(matched?.id || ''), { shouldDirty: true, shouldValidate: false });
                                }}
                              />
                            </FormControl>
                            <FormMessage />
                          </FormItem>
                        )} />
                      </div>

                      <div className="rounded-lg border p-4">
                        <FormField control={form.control} name="isActive" render={({ field }) => (
                          <FormItem className="flex items-start gap-3 rounded-md border p-3">
                            <FormControl>
                              <Checkbox checked={field.value === true} onCheckedChange={(checked) => field.onChange(checked === true)} />
                            </FormControl>
                            <div className="space-y-1">
                              <FormLabel className="m-0">Active</FormLabel>
                              <p className="text-xs text-muted-foreground">Disable to archive this reference bank without deleting history.</p>
                            </div>
                          </FormItem>
                        )} />
                      </div>
                    </TabsContent>
                  </div>
                </Tabs>
              </div>

              <div className="px-6 py-4 border-t bg-background/95 backdrop-blur flex gap-2 justify-end">
                <Button
                  type="button"
                  variant="outline"
                  onClick={() => {
                    setEditing(null);
                    setIsAdding(false);
                    setAccountCodeEditedManually(false);
                  }}
                >
                  {tGlobal?.cancel ?? 'Cancel'}
                </Button>
                <Button type="submit" disabled={isEditLocked}>
                  {tGlobal?.save ?? 'Save'}
                </Button>
              </div>
            </form>
          </Form>
        </DialogContent>
      </Dialog>
    </Card>
  );
}
