"use client";

import { zodResolver } from "@hookform/resolvers/zod";
import {
  Calendar,
  ClipboardList,
  Loader2,
  Plus,
  Trash2,
  User,
  X,
} from "lucide-react";
import { useEffect, useState } from "react";
import { createPortal } from "react-dom";
import { useFieldArray, useForm } from "react-hook-form";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { calculateEquipmentRate, currency } from "@/lib/utils";
import { Customer } from "@/types/customer";
import { Equipment } from "@/types/equipment";
import { CreateRentalDTO, Rental } from "@/types/rental";
import { rentalSchema, RentalFormValues } from "@/validators/rental";

interface RentalFormModalProps {
  isOpen: boolean;
  onClose: () => void;
  onSubmit: (data: CreateRentalDTO) => Promise<void>;
  rentalToEdit?: Rental | null;
  customers: Customer[];
  equipmentList: Equipment[];
  isSaving?: boolean;
}

export function RentalFormModal({
  isOpen,
  onClose,
  onSubmit,
  rentalToEdit,
  customers,
  equipmentList,
  isSaving = false,
}: RentalFormModalProps) {
  const today = new Date().toISOString().split("T")[0];
  const in30Days = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000)
    .toISOString()
    .split("T")[0];

  const {
    register,
    handleSubmit,
    control,
    watch,
    setValue,
    reset,
    formState: { errors },
  } = useForm<RentalFormValues>({
    resolver: zodResolver(rentalSchema),
    defaultValues: {
      customerId: "",
      startDate: today,
      endDate: in30Days,
      freight: 0,
      discount: 0,
      depositAmount: 0,
      paymentMethod: "A_VISTA",
      installmentsCount: 1,
      operator: "",
      notes: "",
      status: "QUOTE",
      items: [],
    },
  });

  const { fields, append, remove } = useFieldArray({
    control,
    name: "items",
  });

  const { fields: installmentFields } = useFieldArray({
    control,
    name: "installments",
  });

  const startDateVal = watch("startDate");
  const endDateVal = watch("endDate");
  const freightVal = watch("freight") || 0;
  const discountVal = watch("discount") || 0;
  const depositAmountVal = watch("depositAmount") || 0;
  const paymentMethodVal = watch("paymentMethod") || "A_VISTA";
  const installmentsCountVal = watch("installmentsCount") || 1;
  const itemsVal = watch("items") || [];

  // Calculate days difference
  const calculateDays = (startStr: string, endStr: string) => {
    if (!startStr || !endStr) return 1;
    const start = new Date(startStr);
    const end = new Date(endStr);
    const diff = Math.ceil((end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24));
    return Math.max(diff, 1);
  };

  const daysCount = calculateDays(startDateVal, endDateVal);

  const calculateSubtotal = () => {
    return itemsVal.reduce((acc, item) => {
      const qty = Number(item?.quantity) || 0;
      const inputRate = Number(item?.dailyRate) || 0;
      const eq = equipmentList.find((e) => e.id === item?.equipmentId);

      if (!eq) {
        return acc + qty * inputRate * daysCount;
      }

      // Se a diária foi alterada manualmente pelo usuário no input em relação ao cadastro da máquina
      if (inputRate > 0 && Math.abs(inputRate - Number(eq.dailyRate)) > 0.01) {
        return acc + qty * inputRate * daysCount;
      }

      const calc = calculateEquipmentRate(daysCount, eq);
      return acc + qty * calc.totalItem;
    }, 0);
  };

  const subtotalVal = calculateSubtotal();
  const grandTotal = Math.max(subtotalVal + Number(freightVal) - Number(discountVal), 0);

  // Recalcular ou inicializar as parcelas automaticamente
  useEffect(() => {
    if (!isOpen) return;

    // Se já existem recebíveis do contrato sendo editado
    if (rentalToEdit?.receivables && rentalToEdit.receivables.length > 0) {
      const openRecs = rentalToEdit.receivables.filter(
        (r) => !r.description?.includes("Sinal de Depósito") && !r.description?.includes("Sinal / Entrada")
      );
      if (openRecs.length > 0 && openRecs.length === installmentsCountVal) {
        const insts = openRecs.map((r) => ({
          dueDate: r.dueDate.split("T")[0],
          amount: Number(r.amount),
        }));
        setValue("installments", insts);
        return;
      }
    }

    const count = Math.max(installmentsCountVal, 1);
    const remTotal = Math.max(grandTotal - Number(depositAmountVal), 0);
    const valPerInst = Number((remTotal / count).toFixed(2));

    const baseDate = startDateVal ? new Date(startDateVal) : new Date();

    const insts = [];
    for (let i = 0; i < count; i++) {
      const d = new Date(baseDate);
      d.setDate(d.getDate() + i * 30);
      const isoDate = d.toISOString().split("T")[0];
      const instAmt =
        i === count - 1
          ? Number((remTotal - valPerInst * (count - 1)).toFixed(2))
          : valPerInst;
      insts.push({
        dueDate: isoDate,
        amount: instAmt,
      });
    }
    setValue("installments", insts);
  }, [
    isOpen,
    installmentsCountVal,
    depositAmountVal,
    grandTotal,
    startDateVal,
    rentalToEdit,
    setValue,
  ]);

  useEffect(() => {
    if (rentalToEdit) {
      const openRecs = rentalToEdit.receivables
        ? rentalToEdit.receivables.filter(
            (r) => !r.description?.includes("Sinal de Depósito") && !r.description?.includes("Sinal / Entrada")
          )
        : [];
      const derivedCount = openRecs.length > 0 ? openRecs.length : (Number(rentalToEdit.installmentsCount) || 1);
      const derivedDeposit = Number(rentalToEdit.depositAmount) || 0;
      let derivedMethod = rentalToEdit.paymentMethod;
      if (!derivedMethod || derivedMethod === "A_VISTA") {
        if (derivedDeposit > 0 && derivedCount > 0) {
          derivedMethod = "ENTRADA_E_PARCELAS";
        } else if (derivedCount > 1) {
          derivedMethod = "PARCELADO";
        } else {
          derivedMethod = "A_VISTA";
        }
      }

      reset({
        customerId: rentalToEdit.customerId,
        startDate: rentalToEdit.startDate.split("T")[0],
        endDate: rentalToEdit.endDate.split("T")[0],
        freight: Number(rentalToEdit.freight) || 0,
        discount: Number(rentalToEdit.discount) || 0,
        depositAmount: derivedDeposit,
        paymentMethod: derivedMethod,
        installmentsCount: derivedCount,
        operator: rentalToEdit.operator || "",
        notes: rentalToEdit.notes || "",
        status: rentalToEdit.status,
        items: rentalToEdit.items
          ? rentalToEdit.items.map((i) => ({
              equipmentId: i.equipmentId,
              quantity: i.quantity,
              dailyRate: Number(i.dailyRate),
            }))
          : [],
        installments: openRecs.map((r) => ({
          dueDate: r.dueDate.split("T")[0],
          amount: Number(r.amount),
        })),
      });
    } else {
      const activeCustomers = customers.filter((c) => c.status === "ACTIVE");
      reset({
        customerId: activeCustomers[0]?.id || customers[0]?.id || "",
        startDate: today,
        endDate: in30Days,
        freight: 0,
        discount: 0,
        depositAmount: 0,
        paymentMethod: "A_VISTA",
        installmentsCount: 1,
        operator: "",
        notes: "",
        status: "QUOTE",
        items: equipmentList[0]
          ? [
              {
                equipmentId: equipmentList[0].id,
                quantity: 1,
                dailyRate: Number(equipmentList[0].dailyRate) || 0,
              },
            ]
          : [],
        installments: []
      });
    }
  }, [rentalToEdit, customers, equipmentList, reset, isOpen, today, in30Days]);

  const activeCustomers = customers.filter((c) => c.status === "ACTIVE" || c.id === rentalToEdit?.customerId);

  const handleEquipmentChange = (index: number, eqId: string) => {
    const selected = equipmentList.find((e) => e.id === eqId);
    if (selected) {
      setValue(`items.${index}.dailyRate`, Number(selected.dailyRate) || 0);
    }
  };

  const handleAddItem = () => {
    const defaultEq = equipmentList[0];
    append({
      equipmentId: defaultEq ? defaultEq.id : "",
      quantity: 1,
      dailyRate: defaultEq ? Number(defaultEq.dailyRate) || 0 : 0,
    });
  };

  const onFormSubmit = async (values: RentalFormValues) => {
    await onSubmit(values as CreateRentalDTO);
    onClose();
  };

  const [mounted, setMounted] = useState(false);

  useEffect(() => {
    setMounted(true);
  }, []);

  if (!isOpen || !mounted) return null;

  return createPortal(
    <div className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/60 p-4 backdrop-blur-xs transition-all">
      <Card className="w-full max-w-4xl max-h-[90vh] flex flex-col shadow-2xl overflow-hidden p-0">
        {/* Header Fixo no Topo */}
        <div className="flex items-center justify-between border-b px-6 py-4 bg-background shrink-0">
          <div>
            <h2 className="text-xl font-bold flex items-center gap-2">
              <ClipboardList className="h-5 w-5 text-primary" />
              {rentalToEdit ? "Editar Contrato de Locação" : "Novo Contrato de Locação"}
            </h2>
            <p className="text-sm text-muted-foreground">
              {rentalToEdit
                ? `Edite as condições e itens do contrato ${rentalToEdit.code}.`
                : "Selecione o cliente, equipamentos e período de locação."}
            </p>
          </div>
          <Button variant="ghost" size="icon" onClick={onClose}>
            <X className="h-5 w-5" />
          </Button>
        </div>

        {/* Formulário com Scroll Interno */}
        <form onSubmit={handleSubmit(onFormSubmit)} className="flex flex-col flex-1 overflow-hidden">
          <div className="flex-1 overflow-y-auto p-6 space-y-6">
            {/* Informações Básicas */}
            <div className="space-y-4">
              <h3 className="text-sm font-semibold uppercase tracking-wider text-muted-foreground">
                Cliente & Vigência
              </h3>

              <div className="grid gap-4 md:grid-cols-2">
                <div className="md:col-span-2">
                  <label className="mb-1 block text-sm font-medium">Cliente *</label>
                  <select
                    {...register("customerId")}
                    className="w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs focus:outline-hidden focus:ring-1 focus:ring-ring"
                  >
                    <option value="">Selecione um cliente...</option>
                    {activeCustomers.map((c) => (
                      <option key={c.id} value={c.id}>
                        {c.name} {c.document ? `(CNPJ: ${c.document})` : ""}
                      </option>
                    ))}
                  </select>
                  {errors.customerId && (
                    <p className="mt-1 text-xs text-destructive">{errors.customerId.message}</p>
                  )}
                </div>

                <div>
                  <label className="mb-1 block text-sm font-medium">Data Inicial *</label>
                  <Input type="date" {...register("startDate")} />
                  {errors.startDate && (
                    <p className="mt-1 text-xs text-destructive">{errors.startDate.message}</p>
                  )}
                </div>

                <div>
                  <label className="mb-1 block text-sm font-medium">Data Final *</label>
                  <Input type="date" {...register("endDate")} />
                  {errors.endDate && (
                    <p className="mt-1 text-xs text-destructive">{errors.endDate.message}</p>
                  )}
                </div>

                <div className="md:col-span-2">
                  <label className="mb-1 block text-sm font-medium">Status do Contrato</label>
                  <select
                    {...register("status")}
                    className="w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs focus:outline-hidden focus:ring-1 focus:ring-ring"
                  >
                    <option value="QUOTE">Orçamento (Proposta)</option>
                    <option value="RESERVED">Reserva Confirmada</option>
                    <option value="IN_PROGRESS">Em Andamento (Em Operação)</option>
                    <option value="FINISHED">Concluído (Devolvido)</option>
                    <option value="CANCELED">Cancelado</option>
                  </select>
                </div>
              </div>
            </div>

            <div className="rounded-lg border bg-muted/40 p-3 text-xs text-muted-foreground flex items-center justify-between">
              <span>
                Período Total da Locação: <strong>{daysCount} dias</strong>
              </span>
              <span>
                Vigência: <strong>{startDateVal}</strong> até <strong>{endDateVal}</strong>
              </span>
            </div>

            {/* Adição Dinâmica de Equipamentos */}
            <div className="space-y-4 pt-2 border-t">
              <div className="flex items-center justify-between">
                <h3 className="text-sm font-semibold uppercase tracking-wider text-muted-foreground">
                  Equipamentos do Contrato *
                </h3>
                <Button type="button" variant="secondary" size="sm" onClick={handleAddItem}>
                  <Plus className="mr-1 h-3.5 w-3.5" /> Adicionar Equipamento
                </Button>
              </div>

              {errors.items && (
                <p className="text-xs text-rose-500">{errors.items.message}</p>
              )}

              <div className="space-y-3">
                {fields.map((field, index) => {
                  const itemQty = watch(`items.${index}.quantity`) || 0;
                  const itemRate = watch(`items.${index}.dailyRate`) || 0;
                  const eqId = watch(`items.${index}.equipmentId`);
                  const eq = equipmentList.find((e) => e.id === eqId);

                  const calc = calculateEquipmentRate(daysCount, eq);
                  const isCustomRate = itemRate > 0 && eq && Math.abs(itemRate - Number(eq.dailyRate)) > 0.01;
                  const itemSubtotal = isCustomRate ? itemQty * itemRate * daysCount : itemQty * calc.totalItem;
                  const rateBadgeText = isCustomRate ? "Personalizada" : calc.rateApplied;

                  return (
                    <div
                      key={field.id}
                      className="grid gap-3 rounded-lg border bg-card p-3 md:grid-cols-12 items-center"
                    >
                      <div className="md:col-span-5">
                        <label className="mb-1 block text-xs font-medium">Equipamento</label>
                        <select
                          {...register(`items.${index}.equipmentId`)}
                          onChange={(e) => handleEquipmentChange(index, e.target.value)}
                          className="w-full rounded-md border border-input bg-background px-3 py-1.5 text-xs shadow-xs focus:outline-hidden focus:ring-1 focus:ring-ring"
                        >
                          <option value="">Selecione a máquina...</option>
                          {equipmentList.map((eqItem) => (
                            <option key={eqItem.id} value={eqItem.id}>
                              {eqItem.code} - {eqItem.brand} {eqItem.model} (Mensal: {currency(eqItem.monthlyRate)} | Diária: {currency(eqItem.dailyRate)})
                            </option>
                          ))}
                        </select>
                      </div>

                      <div className="md:col-span-2">
                        <label className="mb-1 block text-xs font-medium">Qtd</label>
                        <Input
                          type="number"
                          min="1"
                          {...register(`items.${index}.quantity`, { valueAsNumber: true })}
                          className="h-8 text-xs"
                        />
                      </div>

                      <div className="md:col-span-2">
                        <label className="mb-1 block text-xs font-medium">Diária (R$)</label>
                        <Input
                          type="number"
                          step="any"
                          {...register(`items.${index}.dailyRate`, { valueAsNumber: true })}
                          className="h-8 text-xs"
                        />
                      </div>

                      <div className="md:col-span-2 text-right">
                        <div className="flex items-center justify-end gap-1.5 mb-1">
                          <span className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground">
                            Subtotal ({daysCount}d)
                          </span>
                        </div>
                        <p className="text-xs font-bold text-primary">
                          {currency(itemSubtotal)}
                        </p>
                        <span className="inline-block text-[10px] text-muted-foreground bg-muted px-1.5 py-0.5 rounded-xs mt-0.5">
                          {rateBadgeText}
                        </span>
                      </div>

                      <div className="md:col-span-1 text-right">
                        {fields.length > 1 && (
                          <Button
                            type="button"
                            variant="ghost"
                            size="icon"
                            onClick={() => remove(index)}
                            className="h-8 w-8 text-rose-500 hover:bg-rose-500/10"
                          >
                            <Trash2 className="h-4 w-4" />
                          </Button>
                        )}
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>

            {/* Condições Financeiras & Pagamento */}
            <div className="space-y-4 pt-2 border-t">
              <h3 className="text-sm font-semibold uppercase tracking-wider text-muted-foreground">
                Condições de Pagamento & Sinal
              </h3>

              <div className="grid gap-4 md:grid-cols-3">
                <div>
                  <label className="mb-1 block text-sm font-medium">Sinal / Depósito de Entrada (R$)</label>
                  <Input
                    type="number"
                    step="0.01"
                    min="0"
                    {...register("depositAmount", { valueAsNumber: true })}
                    placeholder="0,00"
                  />
                  <p className="mt-1 text-[11px] text-muted-foreground">Sinal de entrada da proposta de locação</p>
                </div>

                <div>
                  <label className="mb-1 block text-sm font-medium">Forma de Pagamento</label>
                  <select
                    {...register("paymentMethod")}
                    className="w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs focus:outline-hidden focus:ring-1 focus:ring-ring"
                  >
                    <option value="A_VISTA">À vista</option>
                    <option value="ENTRADA_E_PARCELAS">Entrada + Parcelas</option>
                    <option value="PARCELADO">Parcelado (Mensal)</option>
                  </select>
                </div>

                <div>
                  <label className="mb-1 block text-sm font-medium">Nº de Parcelas</label>
                  <select
                    {...register("installmentsCount", { valueAsNumber: true })}
                    className="w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs focus:outline-hidden focus:ring-1 focus:ring-ring"
                  >
                    <option value={1}>1x (À vista / Parcela única)</option>
                    <option value={2}>2x Parcelas</option>
                    <option value={3}>3x Parcelas</option>
                    <option value={4}>4x Parcelas</option>
                    <option value={6}>6x Parcelas</option>
                    <option value={12}>12x Parcelas</option>
                  </select>
                </div>
              </div>

              {/* Tabela Interativa de Parcelas Customizáveis */}
              {installmentsCountVal > 1 && (
                <div className="mt-3 rounded-xl border bg-muted/20 p-4 space-y-3">
                  <div className="flex items-center justify-between border-b pb-2">
                    <h4 className="text-xs font-bold uppercase tracking-wider text-muted-foreground">
                      Detalhamento & Datas das {installmentsCountVal} Parcelas
                    </h4>
                    <span className="text-xs text-muted-foreground">
                      Saldo a Parcelar: <strong className="text-primary">{currency(Math.max(grandTotal - Number(depositAmountVal), 0))}</strong>
                    </span>
                  </div>

                  <div className="space-y-2 max-h-48 overflow-y-auto pr-1">
                    {installmentFields.map((field, idx) => (
                      <div key={field.id} className="grid grid-cols-12 gap-3 items-center text-xs bg-background p-2.5 rounded-lg border">
                        <div className="col-span-3 font-semibold text-foreground">
                          Parcela {idx + 1}/{installmentsCountVal}
                        </div>
                        <div className="col-span-4">
                          <label className="mb-0.5 block text-[10px] uppercase font-bold text-muted-foreground">Vencimento</label>
                          <Input
                            type="date"
                            {...register(`installments.${idx}.dueDate`)}
                            className="h-8 text-xs bg-background"
                          />
                        </div>
                        <div className="col-span-5">
                          <label className="mb-0.5 block text-[10px] uppercase font-bold text-muted-foreground">Valor (R$)</label>
                          <Input
                            type="number"
                            step="0.01"
                            {...register(`installments.${idx}.amount`, { valueAsNumber: true })}
                            className="h-8 text-xs font-semibold bg-background"
                          />
                        </div>
                      </div>
                    ))}
                  </div>
                </div>
              )}
            </div>

          {/* Frete, Desconto e Fechamento Financeiro */}
          <div className="space-y-4 border-t pt-4">
            <h3 className="text-sm font-semibold uppercase tracking-wider text-muted-foreground">
              Ajustes Financeiros
            </h3>

            <div className="grid gap-4 md:grid-cols-3">
              <div>
                <label className="mb-1 block text-sm font-medium">Frete / Mobilização (R$)</label>
                <Input
                  type="number"
                  step="any"
                  {...register("freight", { valueAsNumber: true })}
                  placeholder="0.00"
                />
              </div>

              <div>
                <label className="mb-1 block text-sm font-medium">Desconto Comercial (R$)</label>
                <Input
                  type="number"
                  step="any"
                  {...register("discount", { valueAsNumber: true })}
                  placeholder="0.00"
                />
              </div>

              <div>
                <label className="mb-1 block text-sm font-medium">Operador Responsável</label>
                <Input {...register("operator")} placeholder="Ex: João da Silva / Próprio" />
              </div>
            </div>

            {/* Resumo do Cálculo */}
            <div className="rounded-xl border bg-muted/30 p-4 space-y-2 text-sm">
              <div className="flex justify-between text-muted-foreground">
                <span>Subtotal Máquinas ({daysCount} dias):</span>
                <span>{currency(subtotalVal)}</span>
              </div>
              <div className="flex justify-between text-muted-foreground">
                <span>Frete (+) :</span>
                <span>{currency(Number(freightVal))}</span>
              </div>
              <div className="flex justify-between text-muted-foreground">
                <span>Desconto (-) :</span>
                <span>{currency(Number(discountVal))}</span>
              </div>
              <div className="flex justify-between border-t pt-2 font-bold text-base text-foreground">
                <span>Total do Contrato:</span>
                <span className="text-primary">{currency(grandTotal)}</span>
              </div>
            </div>
          </div>

          {/* Observações */}
          <div>
            <label className="mb-1 block text-sm font-medium">Observações e Condições</label>
            <textarea
              {...register("notes")}
              rows={3}
              className="w-full rounded-md border border-input bg-background p-3 text-sm shadow-xs focus:outline-hidden focus:ring-1 focus:ring-ring"
              placeholder="Condições de pagamento, local da entrega, responsabilidade por combustível..."
            />
          </div>
        </div>

        {/* Rodapé e Botões (Fixo) */}
          <div className="flex items-center justify-end gap-3 border-t px-6 py-4 bg-background shrink-0">
            <Button type="button" variant="secondary" onClick={onClose}>
              Cancelar
            </Button>
            <Button type="submit" disabled={isSaving}>
              {isSaving && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
              {rentalToEdit ? "Salvar Contrato" : "Gerar Contrato de Locação"}
            </Button>
          </div>
        </form>
      </Card>
    </div>,
    document.body
  );
}
