"use client";

import { useState, useEffect } from "react";

import { zodResolver } from "@hookform/resolvers/zod";
import { Loader2, ArrowUpDown, Calculator } from "lucide-react";
import { useForm } from "react-hook-form";
import { z } from "zod";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Form, FormControl, FormDescription, 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 { Textarea } from "@/components/ui/textarea";
import { formatCurrency } from "@/lib/utils";
import { TransactionType, TransactionCreateData } from "@/types/banking";

const transactionFormSchema = z.object({
  account_id: z.string().min(1, "Compte requis"),
  transaction_type: z.enum(["deposit", "withdrawal", "transfer", "interest", "fee", "adjustment"] as const),
  amount: z.number().min(0.01, "Le montant doit être supérieur à 0"),
  description: z.string().min(3, "La description doit contenir au moins 3 caractères"),
  reference: z.string().optional(),
  beneficiary_account_id: z.string().optional(),
  fee_amount: z.number().min(0, "Les frais doivent être positifs").optional(),
  notes: z.string().optional(),
});

type TransactionFormValues = z.infer<typeof transactionFormSchema>;

interface TransactionFormProps {
  readonly open: boolean;
  readonly onOpenChange: (open: boolean) => void;
  readonly mode: "create" | "edit";
  readonly initialData?: Partial<TransactionFormValues>;
  readonly accounts?: Array<{
    id: string;
    account_name: string;
    account_number: string;
    balance: number;
    account_type: string;
  }>;
  readonly onSubmit: (data: TransactionCreateData) => Promise<void>;
  readonly loading?: boolean;
}

const transactionTypes = [
  {
    value: "deposit",
    label: "Dépôt",
    description: "Ajout de fonds au compte",
    icon: "⬇️",
    color: "bg-green-100 text-green-700",
  },
  {
    value: "withdrawal",
    label: "Retrait",
    description: "Retrait de fonds du compte",
    icon: "⬆️",
    color: "bg-red-100 text-red-700",
  },
  {
    value: "transfer",
    label: "Transfert",
    description: "Transfert vers un autre compte",
    icon: "↔️",
    color: "bg-blue-100 text-blue-700",
  },
  {
    value: "interest",
    label: "Intérêts",
    description: "Intérêts créditeurs",
    icon: "📈",
    color: "bg-purple-100 text-purple-700",
  },
  {
    value: "fee",
    label: "Frais",
    description: "Frais bancaires",
    icon: "💰",
    color: "bg-orange-100 text-orange-700",
  },
  {
    value: "adjustment",
    label: "Ajustement",
    description: "Correction ou ajustement",
    icon: "⚖️",
    color: "bg-gray-100 text-gray-700",
  },
] as const;

export function TransactionForm({
  open,
  onOpenChange,
  mode,
  initialData,
  accounts = [],
  onSubmit,
  loading = false,
}: TransactionFormProps) {
  const [calculatedFees, setCalculatedFees] = useState<number>(0);

  const form = useForm<TransactionFormValues>({
    resolver: zodResolver(transactionFormSchema),
    defaultValues: {
      account_id: "",
      transaction_type: "deposit",
      amount: 0,
      description: "",
      reference: "",
      beneficiary_account_id: "",
      fee_amount: 0,
      notes: "",
      ...initialData,
    },
  });

  const watchedTransactionType = form.watch("transaction_type");
  const watchedAccountId = form.watch("account_id");
  const watchedAmount = form.watch("amount");

  const selectedAccount = accounts.find((acc) => acc.id === watchedAccountId);
  const selectedTransactionType = transactionTypes.find((type) => type.value === watchedTransactionType);

  // Calcul automatique des frais selon le type de transaction
  const calculateFees = (type: TransactionType, amount: number): number => {
    switch (type) {
      case "deposit":
      case "interest":
      case "adjustment":
        return 0;
      case "withdrawal":
        return amount * 0.005; // 0.5%
      case "transfer":
        return amount * 0.01; // 1%
      case "fee":
        return 0;
      default:
        return 0;
    }
  };

  // Mettre à jour les frais automatiquement
  useEffect(() => {
    if (watchedAmount && watchedTransactionType) {
      const fees = calculateFees(watchedTransactionType, watchedAmount);
      setCalculatedFees(fees);
      form.setValue("fee_amount", fees);
    }
  }, [watchedAmount, watchedTransactionType, form]);

  const handleSubmit = async (data: TransactionFormValues) => {
    try {
      const submitData: TransactionCreateData = {
        account_id: Number(data.account_id),
        type: data.transaction_type,
        amount: data.amount.toString(),
        description: data.description,
        reference: data.reference,
        beneficiary_account_id:
          data.transaction_type === "transfer" && data.beneficiary_account_id
            ? Number(data.beneficiary_account_id)
            : undefined,
      };

      await onSubmit(submitData);
      form.reset();
      onOpenChange(false);
    } catch (error) {
      console.error("Erreur lors de la soumission:", error);
    }
  };

  const isEditing = mode === "edit";
  const isTransfer = watchedTransactionType === "transfer";
  const showDestinationAccount = isTransfer;

  // Vérification de la validité de la transaction
  const isValidTransaction = (): boolean => {
    if (!selectedAccount || !watchedAmount) return true;

    if (["withdrawal", "transfer", "fee"].includes(watchedTransactionType)) {
      const totalAmount = watchedAmount + (calculatedFees ?? 0);
      return selectedAccount.balance >= totalAmount;
    }

    return true;
  };

  const getBalanceAfterTransaction = (): number => {
    if (!selectedAccount || !watchedAmount) return selectedAccount?.balance ?? 0;

    const totalAmount = watchedAmount + (calculatedFees ?? 0);

    switch (watchedTransactionType) {
      case "deposit":
      case "interest":
        return selectedAccount.balance + watchedAmount;
      case "withdrawal":
      case "transfer":
      case "fee":
        return selectedAccount.balance - totalAmount;
      case "adjustment":
        return selectedAccount.balance + watchedAmount; // Peut être positif ou négatif
      default:
        return selectedAccount.balance;
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-h-[90vh] max-w-2xl overflow-y-auto">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <ArrowUpDown className="h-5 w-5" />
            {isEditing ? "Modifier la transaction" : "Nouvelle transaction"}
          </DialogTitle>
          <DialogDescription>
            {isEditing ? "Modifiez les détails de la transaction." : "Créez une nouvelle transaction bancaire."}
          </DialogDescription>
        </DialogHeader>

        <Form {...form}>
          <form onSubmit={form.handleSubmit(handleSubmit)} className="space-y-6">
            {/* Sélection du compte */}
            <FormField
              control={form.control}
              name="account_id"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Compte *</FormLabel>
                  <Select onValueChange={field.onChange} defaultValue={field.value}>
                    <FormControl>
                      <SelectTrigger>
                        <SelectValue placeholder="Sélectionner un compte" />
                      </SelectTrigger>
                    </FormControl>
                    <SelectContent>
                      {accounts.map((account) => (
                        <SelectItem key={account.id} value={account.id}>
                          <div className="flex flex-col">
                            <span className="font-medium">{account.account_name}</span>
                            <div className="text-muted-foreground flex items-center gap-2 text-xs">
                              <span>{account.account_number}</span>
                              <span>•</span>
                              <span className="font-medium">{formatCurrency(account.balance)}</span>
                            </div>
                          </div>
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                  {selectedAccount && (
                    <div className="mt-2 flex items-center gap-2">
                      <Badge variant="outline" className="text-xs">
                        Solde actuel: {formatCurrency(selectedAccount.balance)}
                      </Badge>
                      {!isValidTransaction() && (
                        <Badge variant="destructive" className="text-xs">
                          Solde insuffisant
                        </Badge>
                      )}
                    </div>
                  )}
                  <FormMessage />
                </FormItem>
              )}
            />

            {/* Type de transaction */}
            <FormField
              control={form.control}
              name="transaction_type"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Type de transaction *</FormLabel>
                  <Select onValueChange={field.onChange} defaultValue={field.value}>
                    <FormControl>
                      <SelectTrigger>
                        <SelectValue placeholder="Type de transaction" />
                      </SelectTrigger>
                    </FormControl>
                    <SelectContent>
                      {transactionTypes.map((type) => (
                        <SelectItem key={type.value} value={type.value}>
                          <div className="flex items-center gap-2">
                            <span>{type.icon}</span>
                            <div className="flex flex-col">
                              <span className="font-medium">{type.label}</span>
                              <span className="text-muted-foreground text-xs">{type.description}</span>
                            </div>
                          </div>
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                  {selectedTransactionType && (
                    <Badge variant="secondary" className={`mt-2 text-xs ${selectedTransactionType.color}`}>
                      {selectedTransactionType.icon} {selectedTransactionType.label}
                    </Badge>
                  )}
                  <FormMessage />
                </FormItem>
              )}
            />

            {/* Montant et compte de destination */}
            <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
              <FormField
                control={form.control}
                name="amount"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Montant *</FormLabel>
                    <FormControl>
                      <Input
                        type="number"
                        min="0.01"
                        step="0.01"
                        placeholder="0.00"
                        {...field}
                        onChange={(e) => field.onChange(Number(e.target.value))}
                      />
                    </FormControl>
                    {Boolean(selectedAccount && watchedAmount) && (
                      <FormDescription>
                        <div className="flex items-center gap-1">
                          <Calculator className="h-3 w-3" />
                          <span>Solde après transaction: </span>
                          <span
                            className={`font-medium ${
                              getBalanceAfterTransaction() < 0 ? "text-red-600" : "text-green-600"
                            }`}
                          >
                            {formatCurrency(getBalanceAfterTransaction())}
                          </span>
                        </div>
                      </FormDescription>
                    )}
                    <FormMessage />
                  </FormItem>
                )}
              />

              {showDestinationAccount && (
                <FormField
                  control={form.control}
                  name="beneficiary_account_id"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>Compte de destination *</FormLabel>
                      <Select onValueChange={field.onChange} defaultValue={field.value}>
                        <FormControl>
                          <SelectTrigger>
                            <SelectValue placeholder="Compte destinataire" />
                          </SelectTrigger>
                        </FormControl>
                        <SelectContent>
                          {accounts
                            .filter((acc) => acc.id !== watchedAccountId)
                            .map((account) => (
                              <SelectItem key={account.id} value={account.id}>
                                <div className="flex flex-col">
                                  <span className="font-medium">{account.account_name}</span>
                                  <span className="text-muted-foreground text-xs">{account.account_number}</span>
                                </div>
                              </SelectItem>
                            ))}
                        </SelectContent>
                      </Select>
                      <FormMessage />
                    </FormItem>
                  )}
                />
              )}
            </div>

            {/* Description et référence */}
            <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
              <FormField
                control={form.control}
                name="description"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Description *</FormLabel>
                    <FormControl>
                      <Input placeholder="Description de la transaction" {...field} />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />

              <FormField
                control={form.control}
                name="reference"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Référence</FormLabel>
                    <FormControl>
                      <Input placeholder="Numéro de référence" {...field} />
                    </FormControl>
                    <FormDescription>Référence externe ou numéro de chèque</FormDescription>
                    <FormMessage />
                  </FormItem>
                )}
              />
            </div>

            {/* Frais */}
            {calculatedFees > 0 && (
              <FormField
                control={form.control}
                name="fee_amount"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Frais de transaction</FormLabel>
                    <FormControl>
                      <Input
                        type="number"
                        min="0"
                        step="0.01"
                        {...field}
                        onChange={(e) => field.onChange(Number(e.target.value))}
                      />
                    </FormControl>
                    <FormDescription>Frais calculés automatiquement: {formatCurrency(calculatedFees)}</FormDescription>
                    <FormMessage />
                  </FormItem>
                )}
              />
            )}

            {/* Notes */}
            <FormField
              control={form.control}
              name="notes"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Notes internes</FormLabel>
                  <FormControl>
                    <Textarea placeholder="Notes ou commentaires internes..." className="resize-none" {...field} />
                  </FormControl>
                  <FormDescription>Ces notes ne sont visibles que par le personnel</FormDescription>
                  <FormMessage />
                </FormItem>
              )}
            />

            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => onOpenChange(false)} disabled={loading}>
                Annuler
              </Button>
              <Button type="submit" disabled={loading || !isValidTransaction()}>
                {loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
                {isEditing ? "Modifier" : "Créer"} la transaction
              </Button>
            </DialogFooter>
          </form>
        </Form>
      </DialogContent>
    </Dialog>
  );
}
