"use client";

import { useEffect, useState } from "react";
import { toast } from "sonner";
import { X, Loader2 } from "lucide-react";

import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/shared/components/ui/dialog";
import { Button } from "@/shared/components/ui/button";
import { Input } from "@/shared/components/ui/input";
import { Label } from "@/shared/components/ui/label";
import { Checkbox } from "@/shared/components/ui/checkbox";
import { Badge } from "@/shared/components/ui/badge";
import { formatPhone } from "@/shared/utils/format-phone";
import { formatCep } from "@/shared/utils/format-cep";
import { getTagsPaginatedAction } from "../actions/get-tags-paginated-action";
import { createContactAction } from "../actions/create-contact-action";
import { updateContactAction } from "../actions/update-contact-action";

export interface ContactFormInitialValues {
  id: string;
  email: string;
  name: string | null;
  lastName?: string | null;
  phone: string | null;
  bairro?: string | null;
  cidade?: string | null;
  uf?: string | null;
  idioma?: string | null;
  empresa?: string | null;
  cep?: string | null;
  codigoEstabelecimento?: string | null;
  nomeEstabelecimento?: string | null;
  cdate?: string | null;
  tags: string[];
  listIds: string[];
}

interface ContactFormModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  lists: { id: string; name: string }[];
  initialContact?: ContactFormInitialValues;
  onSaved: () => void;
}

interface TagOption {
  id: string;
  name: string;
}

export function ContactFormModal({ open, onOpenChange, lists, initialContact, onSaved }: ContactFormModalProps) {
  const isEdit = !!initialContact;

  const [email, setEmail] = useState("");
  const [name, setName] = useState("");
  const [lastName, setLastName] = useState("");
  const [phone, setPhone] = useState("");
  const [bairro, setBairro] = useState("");
  const [cidade, setCidade] = useState("");
  const [uf, setUf] = useState("");
  const [idioma, setIdioma] = useState("");
  const [empresa, setEmpresa] = useState("");
  const [cep, setCep] = useState("");
  const [codigoEstabelecimento, setCodigoEstabelecimento] = useState("");
  const [nomeEstabelecimento, setNomeEstabelecimento] = useState("");
  const [cdate, setCdate] = useState("");
  const [tags, setTags] = useState<string[]>([]);
  const [tagInput, setTagInput] = useState("");
  const [availableTags, setAvailableTags] = useState<TagOption[]>([]);
  const [listIds, setListIds] = useState<string[]>([]);
  const [isSaving, setIsSaving] = useState(false);
  const [isLoadingCep, setIsLoadingCep] = useState(false);

  useEffect(() => {
    if (!open) return;
    setEmail(initialContact?.email ?? "");
    setName(initialContact?.name ?? "");
    setLastName(initialContact?.lastName ?? "");
    setPhone(formatPhone(initialContact?.phone));
    setBairro(initialContact?.bairro ?? "");
    setCidade(initialContact?.cidade ?? "");
    setUf(initialContact?.uf ?? "");
    setIdioma(initialContact?.idioma ?? "");
    setEmpresa(initialContact?.empresa ?? "");
    setCep(formatCep(initialContact?.cep));
    setCodigoEstabelecimento(initialContact?.codigoEstabelecimento ?? "");
    setNomeEstabelecimento(initialContact?.nomeEstabelecimento ?? "");
    setCdate(initialContact?.cdate ?? "");
    setTags(initialContact?.tags ?? []);
    setListIds(initialContact?.listIds ?? []);
    setTagInput("");

    getTagsPaginatedAction(undefined, 100)
      .then((data) => setAvailableTags(data.items ?? []))
      .catch(() => {});
  }, [open, initialContact]);

  async function handleCepChange(value: string) {
    const formatted = formatCep(value);
    setCep(formatted);

    const cleanDigits = formatted.replace(/\D/g, "");
    if (cleanDigits.length === 8) {
      setIsLoadingCep(true);
      try {
        const res = await fetch(`https://viacep.com.br/ws/${cleanDigits}/json/`);
        if (res.ok) {
          const data = await res.json();
          if (data.erro) {
            toast.error("CEP não encontrado.");
          } else {
            if (data.bairro) setBairro(data.bairro);
            if (data.localidade) setCidade(data.localidade);
            if (data.uf) setUf(data.uf);
            toast.success("Endereço localizado via CEP!");
          }
        }
      } catch {
        toast.error("Não foi possível buscar o CEP.");
      } finally {
        setIsLoadingCep(false);
      }
    }
  }

  function addTag(tagName?: string) {
    const value = (tagName ?? tagInput).trim();
    if (value && !tags.includes(value)) {
      setTags((prev) => [...prev, value]);
    }
    if (!tagName) setTagInput("");
  }

  function removeTag(tagName: string) {
    setTags((prev) => prev.filter((t) => t !== tagName));
  }

  function toggleList(listId: string) {
    setListIds((prev) => (prev.includes(listId) ? prev.filter((id) => id !== listId) : [...prev, listId]));
  }

  async function handleSubmit() {
    setIsSaving(true);
    try {
      const payload = {
        name: name || null,
        lastName: lastName || null,
        phone: phone || null,
        bairro: bairro || null,
        cidade: cidade || null,
        uf: uf || null,
        idioma: idioma || null,
        empresa: empresa || null,
        cep: cep || null,
        codigoEstabelecimento: codigoEstabelecimento || null,
        nomeEstabelecimento: nomeEstabelecimento || null,
        cdate: cdate || null,
        tags,
      };

      if (isEdit) {
        await updateContactAction(initialContact.id, payload);
        toast.success("Contato atualizado.");
      } else {
        await createContactAction({ email, ...payload, listIds });
        toast.success("Contato criado.");
      }
      onOpenChange(false);
      onSaved();
    } catch (err) {
      toast.error(err instanceof Error && err.message ? err.message : "Não foi possível salvar o contato.");
    } finally {
      setIsSaving(false);
    }
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-5xl lg:max-w-6xl max-h-[90vh] overflow-y-auto">
        <DialogHeader>
          <DialogTitle className="text-lg font-bold text-zinc-900">
            {isEdit ? "Editar Contato" : "Adicionar um Contato"}
          </DialogTitle>
        </DialogHeader>

        <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-4 py-3 text-xs sm:text-sm">
          {/* Linha 1: 4 Inputs na mesma linha */}
          <div className="space-y-1.5">
            <Label htmlFor="contact-email" className="font-semibold text-zinc-700">
              E-mail <span className="text-rose-500 font-bold ml-0.5">*</span>
            </Label>
            <Input
              id="contact-email"
              type="email"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              disabled={isEdit}
              placeholder="exemplo@dominio.com"
              className="h-10 text-xs sm:text-sm"
            />
          </div>

          <div className="space-y-1.5">
            <Label htmlFor="contact-name" className="font-semibold text-zinc-700">Nome</Label>
            <Input
              id="contact-name"
              value={name}
              onChange={(e) => setName(e.target.value)}
              placeholder="Nome"
              className="h-10 text-xs sm:text-sm"
            />
          </div>

          <div className="space-y-1.5">
            <Label htmlFor="contact-lastname" className="font-semibold text-zinc-700">Sobrenome</Label>
            <Input
              id="contact-lastname"
              value={lastName}
              onChange={(e) => setLastName(e.target.value)}
              placeholder="Sobrenome"
              className="h-10 text-xs sm:text-sm"
            />
          </div>

          <div className="space-y-1.5">
            <Label htmlFor="contact-phone" className="font-semibold text-zinc-700">Telefone</Label>
            <Input
              id="contact-phone"
              value={phone}
              onChange={(e) => setPhone(formatPhone(e.target.value))}
              placeholder="(11) 99999-9999"
              maxLength={15}
              className="h-10 text-xs sm:text-sm"
            />
          </div>

          {/* Linha 2: 4 Inputs na mesma linha (Bairro, Cidade, UF, CEP) */}
          <div className="space-y-1.5">
            <Label htmlFor="contact-bairro" className="font-semibold text-zinc-700">Bairro</Label>
            <Input
              id="contact-bairro"
              value={bairro}
              onChange={(e) => setBairro(e.target.value)}
              placeholder="Bairro"
              className="h-10 text-xs sm:text-sm"
            />
          </div>

          <div className="space-y-1.5">
            <Label htmlFor="contact-cidade" className="font-semibold text-zinc-700">Cidade</Label>
            <Input
              id="contact-cidade"
              value={cidade}
              onChange={(e) => setCidade(e.target.value)}
              placeholder="Cidade"
              className="h-10 text-xs sm:text-sm"
            />
          </div>

          <div className="space-y-1.5">
            <Label htmlFor="contact-uf" className="font-semibold text-zinc-700">UF</Label>
            <Input
              id="contact-uf"
              value={uf}
              onChange={(e) => setUf(e.target.value.toUpperCase())}
              placeholder="SP"
              maxLength={2}
              className="h-10 text-xs sm:text-sm uppercase"
            />
          </div>

          <div className="space-y-1.5">
            <Label htmlFor="contact-cep" className="font-semibold text-zinc-700 flex items-center justify-between">
              <span>CEP</span>
              {isLoadingCep && (
                <span className="text-[11px] text-[#635BFF] flex items-center gap-1 font-normal animate-pulse">
                  <Loader2 className="w-3 h-3 animate-spin" /> Buscando...
                </span>
              )}
            </Label>
            <Input
              id="contact-cep"
              value={cep}
              onChange={(e) => handleCepChange(e.target.value)}
              placeholder="00000-000"
              maxLength={9}
              className="h-10 text-xs sm:text-sm"
            />
          </div>

          {/* Linha 3: 4 Inputs na mesma linha */}
          <div className="space-y-1.5">
            <Label htmlFor="contact-idioma" className="font-semibold text-zinc-700">Idioma de preferência</Label>
            <Input
              id="contact-idioma"
              value={idioma}
              onChange={(e) => setIdioma(e.target.value)}
              placeholder="Idioma"
              className="h-10 text-xs sm:text-sm"
            />
          </div>

          <div className="space-y-1.5">
            <Label htmlFor="contact-empresa" className="font-semibold text-zinc-700">Empresa</Label>
            <Input
              id="contact-empresa"
              value={empresa}
              onChange={(e) => setEmpresa(e.target.value)}
              placeholder="Empresa"
              className="h-10 text-xs sm:text-sm"
            />
          </div>

          <div className="space-y-1.5">
            <Label htmlFor="contact-cod-estab" className="font-semibold text-zinc-700">Cód. Estabelecimento</Label>
            <Input
              id="contact-cod-estab"
              value={codigoEstabelecimento}
              onChange={(e) => setCodigoEstabelecimento(e.target.value)}
              placeholder="Código"
              className="h-10 text-xs sm:text-sm"
            />
          </div>

          <div className="space-y-1.5">
            <Label htmlFor="contact-nome-estab" className="font-semibold text-zinc-700">Nome Estabelecimento</Label>
            <Input
              id="contact-nome-estab"
              value={nomeEstabelecimento}
              onChange={(e) => setNomeEstabelecimento(e.target.value)}
              placeholder="Nome do Estabelecimento"
              className="h-10 text-xs sm:text-sm"
            />
          </div>

          {/* Linha 4: CDATE + Tags */}
          <div className="space-y-1.5">
            <Label htmlFor="contact-cdate" className="font-semibold text-zinc-700">CDATE</Label>
            <Input
              id="contact-cdate"
              value={cdate}
              onChange={(e) => setCdate(e.target.value)}
              placeholder="Data / Código"
              className="h-10 text-xs sm:text-sm"
            />
          </div>

          <div className="space-y-1.5 md:col-span-3">
            <Label htmlFor="contact-tags" className="font-semibold text-zinc-700">Tags</Label>
            {tags.length > 0 && (
              <div className="flex flex-wrap gap-1.5 pb-1">
                {tags.map((t) => (
                  <Badge key={t} variant="secondary" className="gap-1 text-xs">
                    {t}
                    <button type="button" onClick={() => removeTag(t)} className="hover:text-zinc-900">
                      <X className="w-3 h-3" />
                    </button>
                  </Badge>
                ))}
              </div>
            )}
            <Input
              id="contact-tags"
              value={tagInput}
              onChange={(e) => setTagInput(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === "Enter" || e.key === ",") {
                  e.preventDefault();
                  addTag();
                }
              }}
              onBlur={() => addTag()}
              placeholder="Digite e pressione Enter"
              className="h-10 text-xs sm:text-sm"
            />
            {availableTags.length > 0 && (
              <div className="pt-1 space-y-1">
                <span className="text-[11px] font-semibold text-zinc-500">Tags criadas disponíveis:</span>
                <div className="flex flex-wrap gap-1 max-h-20 overflow-y-auto">
                  {availableTags.map((t) => {
                    const isSelected = tags.includes(t.name);
                    return (
                      <button
                        key={t.id}
                        type="button"
                        onClick={() => (isSelected ? removeTag(t.name) : addTag(t.name))}
                        className={`text-[11px] px-2 py-0.5 rounded-md font-medium transition-colors cursor-pointer ${
                          isSelected
                            ? "bg-[#635BFF] text-white"
                            : "bg-zinc-100 text-zinc-700 hover:bg-zinc-200"
                        }`}
                      >
                        {isSelected ? `✓ ${t.name}` : `+ ${t.name}`}
                      </button>
                    );
                  })}
                </div>
              </div>
            )}
          </div>

          {!isEdit && lists.length > 0 && (
            <div className="space-y-1.5 md:col-span-4">
              <Label className="font-semibold text-zinc-700">Adicionar às listas</Label>
              <div className="max-h-32 overflow-y-auto space-y-1.5 border border-zinc-200 rounded-lg p-2.5">
                {lists.map((list) => (
                  <label key={list.id} className="flex items-center gap-2 text-xs text-zinc-700 cursor-pointer">
                    <Checkbox checked={listIds.includes(list.id)} onCheckedChange={() => toggleList(list.id)} />
                    {list.name}
                  </label>
                ))}
              </div>
            </div>
          )}
        </div>

        <DialogFooter className="gap-2 pt-2">
          <Button variant="outline" onClick={() => onOpenChange(false)} className="h-9 px-4 rounded-lg">
            Cancelar
          </Button>
          <Button onClick={handleSubmit} disabled={isSaving || !email} className="h-9 px-5 rounded-lg bg-[#635BFF] hover:bg-[#5249E0] text-white font-semibold">
            {isSaving ? "Salvando..." : "Salvar"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
