import { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { CashAccountDTO, CreateCashAccountDTO } from '@/types/treasury';
import { commonService } from '@/services/commonService';
import { orgService } from '@/services/orgService';
import { treasuryService } from '@/services/treasuryService';
import { BankDTO } from '@/types/common';
import { OrgUnitDTO } from '@/types/org';
import { toast } from 'sonner';

const formSchema = z.object({
  code: z.string().min(1, 'Código é obrigatório').max(50, 'Código deve ter no máximo 50 caracteres'),
  name: z.string().min(1, 'Nome é obrigatório').max(200, 'Nome deve ter no máximo 200 caracteres'),
  type: z.enum(['CASH', 'BANK_ACCOUNT'], { required_error: 'Tipo é obrigatório' }),
  orgUnitId: z.string().min(1, 'Unidade Orgânica é obrigatória'),
  bankId: z.string().optional(),
  accountNumber: z.string().max(50).optional(),
  branchCode: z.string().max(20).optional(),
  iban: z.string()
    .max(34, 'IBAN deve ter no máximo 34 caracteres')
    .optional()
    .refine(
      (val) => {
        if (!val || val.trim() === '') return true; // Opcional
        // Validação básica de IBAN: 2 letras (código país) + 2 dígitos + até 30 caracteres alfanuméricos
        const ibanRegex = /^[A-Z]{2}\d{2}[A-Z0-9]{4,30}$/i;
        const cleaned = val.replace(/\s/g, ''); // Remove espaços
        return ibanRegex.test(cleaned);
      },
      { message: 'IBAN inválido. Formato esperado: 2 letras (país) + 2 dígitos + caracteres alfanuméricos' }
    ),
  swiftCode: z.string().max(11, 'Código SWIFT deve ter no máximo 11 caracteres').optional(),
  accountingCode: z.string().max(50, 'Código contabilístico deve ter no máximo 50 caracteres').optional(),
  accountType: z.enum(['RECEITA', 'DESPESA', 'MISTA']).optional(),
  overdraftLimit: z.number().min(0, 'Limite de descoberto deve ser positivo').optional(),
  currency: z.string().max(3).default('XOF'),
  isActive: z.boolean().default(true),
  category: z.enum(['TRANSIT', 'CENTRAL_CUT', 'SUB_ACCOUNT', 'REVENUE'], { required_error: 'Categoria é obrigatória' }).default('SUB_ACCOUNT'),
  parentId: z.string().optional().nullable(),
}).superRefine((data, ctx) => {
  if (data.type === 'BANK_ACCOUNT' && !data.bankId) {
    ctx.addIssue({
      code: z.ZodIssueCode.custom,
      message: 'Banco é obrigatório para contas bancárias',
      path: ['bankId'],
    });
  }
});

interface CashAccountFormModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  account?: CashAccountDTO | null;
  onSubmit: (data: CreateCashAccountDTO) => void;
}

export function CashAccountFormModal({
  open,
  onOpenChange,
  account,
  onSubmit,
}: CashAccountFormModalProps) {
  const [banks, setBanks] = useState<BankDTO[]>([]);
  const [orgUnits, setOrgUnits] = useState<OrgUnitDTO[]>([]);
  const [parentAccounts, setParentAccounts] = useState<CashAccountDTO[]>([]);
  const [isSubmitting, setIsSubmitting] = useState(false);

  const form = useForm<CreateCashAccountDTO>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      code: '',
      name: '',
      type: 'CASH',
      currency: 'XOF',
      isActive: true,
      orgUnitId: '',
      bankId: '',
      category: 'SUB_ACCOUNT',
      parentId: '',
      iban: '',
      swiftCode: '',
      accountingCode: '',
      accountType: undefined,
      overdraftLimit: undefined,
    },
  });

  const accountType = form.watch('type');

  useEffect(() => {
    if (open) {
      fetchDependencies();
    }
  }, [open]);

  useEffect(() => {
    if (account) {
      form.reset({
        code: account.code,
        name: account.name,
        type: account.type,
        orgUnitId: account.orgUnitId,
        bankId: account.bankId,
        accountNumber: account.accountNumber,
        branchCode: account.branchCode,
        iban: account.iban || '',
        swiftCode: account.swiftCode || '',
        accountingCode: account.accountingCode || '',
        accountType: account.accountType,
        overdraftLimit: account.overdraftLimit,
        currency: account.currency,
        isActive: account.isActive,
        category: account.category || 'SUB_ACCOUNT',
        parentId: account.parentId || '',
      });
    } else {
      form.reset({
        code: '',
        name: '',
        type: 'CASH',
        currency: 'XOF',
        isActive: true,
        orgUnitId: '',
        bankId: '',
        category: 'SUB_ACCOUNT',
        parentId: '',
        iban: '',
        swiftCode: '',
        accountingCode: '',
        accountType: undefined,
        overdraftLimit: undefined,
      });
    }
  }, [account, open]);

  const fetchDependencies = async () => {
    try {
      const [banksData, orgData, accountsData] = await Promise.all([
        commonService.getBanks({ page: 0, size: 100 }),
        orgService.getOrgUnits({ page: 0, size: 100 }),
        treasuryService.getCashAccounts({ activeOnly: true }),
      ]);
      setBanks(banksData.content);
      setOrgUnits(orgData.content);
      setParentAccounts(accountsData.filter(a => !account || a.id !== account.id)); // Avoid self-parenting
    } catch (error) {
      toast.error('Erro ao carregar listas de seleção');
    }
  };

  const handleSubmit = async (data: CreateCashAccountDTO) => {
    try {
      setIsSubmitting(true);
      await onSubmit(data);
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-2xl">
        <DialogHeader>
          <DialogTitle>{account ? 'Editar Conta' : 'Nova Conta de Caixa/Bancária'}</DialogTitle>
          <DialogDescription>
            {account ? 'Atualize os dados da conta' : 'Preencha os dados para criar uma nova conta'}
          </DialogDescription>
        </DialogHeader>

        <Form {...form}>
          <form onSubmit={form.handleSubmit(handleSubmit)} className="space-y-4">
            <div className="grid grid-cols-2 gap-4">
              <FormField
                control={form.control}
                name="code"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Código *</FormLabel>
                    <FormControl>
                      <Input placeholder="Ex: CAIXA-001" {...field} />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />

              <FormField
                control={form.control}
                name="type"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Tipo *</FormLabel>
                    <Select onValueChange={field.onChange} defaultValue={field.value}>
                      <FormControl>
                        <SelectTrigger>
                          <SelectValue placeholder="Selecione o tipo" />
                        </SelectTrigger>
                      </FormControl>
                      <SelectContent>
                        <SelectItem value="CASH">Caixa</SelectItem>
                        <SelectItem value="BANK_ACCOUNT">Conta Bancária</SelectItem>
                      </SelectContent>
                    </Select>
                    <FormMessage />
                  </FormItem>
                )}
              />
            </div>

            <FormField
              control={form.control}
              name="name"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Nome *</FormLabel>
                  <FormControl>
                    <Input placeholder="Ex: Caixa Principal" {...field} />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />

            <div className="grid grid-cols-2 gap-4">
              <FormField
                control={form.control}
                name="category"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Categoria (CUT)</FormLabel>
                    <Select onValueChange={field.onChange} defaultValue={field.value}>
                      <FormControl>
                        <SelectTrigger>
                          <SelectValue placeholder="Selecione a categoria" />
                        </SelectTrigger>
                      </FormControl>
                      <SelectContent>
                        <SelectItem value="CENTRAL_CUT">Conta Única (CUT)</SelectItem>
                        <SelectItem value="TRANSIT">Trânsito (Arrecadação)</SelectItem>
                        <SelectItem value="SUB_ACCOUNT">Sub-Conta (Movimentação)</SelectItem>
                        <SelectItem value="REVENUE">Receita</SelectItem>
                      </SelectContent>
                    </Select>
                    <FormMessage />
                  </FormItem>
                )}
              />

              <FormField
                control={form.control}
                name="parentId"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Conta Pai</FormLabel>
                    <Select onValueChange={field.onChange} defaultValue={field.value || undefined}>
                      <FormControl>
                        <SelectTrigger>
                          <SelectValue placeholder="Selecione a conta pai" />
                        </SelectTrigger>
                      </FormControl>
                      <SelectContent>
                        <SelectItem value="none">Nenhuma</SelectItem>
                        {parentAccounts.map((acc) => (
                          <SelectItem key={acc.id} value={acc.id}>
                            {acc.code} - {acc.name}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                    <FormMessage />
                  </FormItem>
                )}
              />
            </div>

            <FormField
              control={form.control}
              name="orgUnitId"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Unidade Orgânica *</FormLabel>
                  <Select onValueChange={field.onChange} defaultValue={field.value}>
                    <FormControl>
                      <SelectTrigger>
                        <SelectValue placeholder="Selecione a unidade responsável" />
                      </SelectTrigger>
                    </FormControl>
                    <SelectContent>
                      {orgUnits.map((org) => (
                        <SelectItem key={org.id} value={org.id}>
                          {org.code} - {org.name}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                  <FormMessage />
                </FormItem>
              )}
            />

            {accountType === 'BANK_ACCOUNT' && (
              <>
                <FormField
                  control={form.control}
                  name="bankId"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>Banco *</FormLabel>
                      <Select onValueChange={field.onChange} defaultValue={field.value}>
                        <FormControl>
                          <SelectTrigger>
                            <SelectValue placeholder="Selecione o banco" />
                          </SelectTrigger>
                        </FormControl>
                        <SelectContent>
                          {banks.map((bank) => (
                            <SelectItem key={bank.id} value={bank.id}>
                              {bank.name} ({bank.code})
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                      <FormMessage />
                    </FormItem>
                  )}
                />

                <div className="grid grid-cols-2 gap-4">
                  <FormField
                    control={form.control}
                    name="accountNumber"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Número da Conta</FormLabel>
                        <FormControl>
                          <Input placeholder="Número da conta bancária" {...field} />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />

                  <FormField
                    control={form.control}
                    name="branchCode"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Código da Agência</FormLabel>
                        <FormControl>
                          <Input placeholder="Código da agência" {...field} />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                </div>

                <div className="grid grid-cols-2 gap-4">
                  <FormField
                    control={form.control}
                    name="iban"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>IBAN</FormLabel>
                        <FormControl>
                          <Input placeholder="Ex: SN08SN0100152000045500003033" {...field} />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />

                  <FormField
                    control={form.control}
                    name="swiftCode"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Código SWIFT</FormLabel>
                        <FormControl>
                          <Input placeholder="Ex: BCEASNDA" {...field} />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                </div>

                <div className="grid grid-cols-2 gap-4">
                  <FormField
                    control={form.control}
                    name="accountingCode"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Código Contabilístico</FormLabel>
                        <FormControl>
                          <Input placeholder="Código contabilístico" {...field} />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />

                  <FormField
                    control={form.control}
                    name="accountType"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Tipo de Conta</FormLabel>
                        <Select onValueChange={field.onChange} defaultValue={field.value}>
                          <FormControl>
                            <SelectTrigger>
                              <SelectValue placeholder="Selecione o tipo" />
                            </SelectTrigger>
                          </FormControl>
                          <SelectContent>
                            <SelectItem value="RECEITA">Receita</SelectItem>
                            <SelectItem value="DESPESA">Despesa</SelectItem>
                            <SelectItem value="MISTA">Mista</SelectItem>
                          </SelectContent>
                        </Select>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                </div>

                <FormField
                  control={form.control}
                  name="overdraftLimit"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>Limite de Descoberto (XOF)</FormLabel>
                      <FormControl>
                        <Input
                          type="number"
                          step="0.01"
                          min="0"
                          placeholder="0.00"
                          {...field}
                          value={field.value || ''}
                          onChange={(e) => field.onChange(e.target.value ? parseFloat(e.target.value) : undefined)}
                        />
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />
              </>
            )}

            <FormField
              control={form.control}
              name="currency"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Moeda</FormLabel>
                  <FormControl>
                    <Input placeholder="XOF" {...field} />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />

            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => onOpenChange(false)} disabled={isSubmitting}>
                Cancelar
              </Button>
              <Button type="submit" disabled={isSubmitting}>
                {isSubmitting ? 'Salvando...' : account ? 'Atualizar' : 'Criar'}
              </Button>
            </DialogFooter>
          </form>
        </Form>
      </DialogContent>
    </Dialog>
  );
}

