import { useEffect, useMemo, useRef, useState, type ChangeEventHandler } from "react";
import { Image as ImageIcon, Loader2, Upload, UserCircle2 } from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { useAuthAccess } from "@/contexts/AuthAccessContext";
import {
  authMeService,
  type MeuParceiroPerfilData,
} from "@/services/fechamento/authMe";
import { fechamentoUploadsService } from "@/services/fechamento/uploads";

const MAX_FILE_SIZE = 5 * 1024 * 1024;
const ALLOWED_IMAGE_TYPES = new Set(["image/jpeg", "image/png", "image/webp"]);

type PerfilForm = {
  nome: string;
  email: string;
  whatsapp: string;
  tipoPessoa: "fisica" | "juridica";
  cpf: string;
  cnpj: string;
  logoUrl: string;
};

const FORM_INICIAL: PerfilForm = {
  nome: "",
  email: "",
  whatsapp: "",
  tipoPessoa: "juridica",
  cpf: "",
  cnpj: "",
  logoUrl: "",
};

function onlyDigits(value: string): string {
  return value.replace(/\D/g, "");
}

function formatCpf(value: string): string {
  const digits = onlyDigits(value).slice(0, 11);
  const p1 = digits.slice(0, 3);
  const p2 = digits.slice(3, 6);
  const p3 = digits.slice(6, 9);
  const p4 = digits.slice(9, 11);
  if (digits.length <= 3) return p1;
  if (digits.length <= 6) return `${p1}.${p2}`;
  if (digits.length <= 9) return `${p1}.${p2}.${p3}`;
  return `${p1}.${p2}.${p3}-${p4}`;
}

function formatCnpj(value: string): string {
  const digits = onlyDigits(value).slice(0, 14);
  const p1 = digits.slice(0, 2);
  const p2 = digits.slice(2, 5);
  const p3 = digits.slice(5, 8);
  const p4 = digits.slice(8, 12);
  const p5 = digits.slice(12, 14);
  if (digits.length <= 2) return p1;
  if (digits.length <= 5) return `${p1}.${p2}`;
  if (digits.length <= 8) return `${p1}.${p2}.${p3}`;
  if (digits.length <= 12) return `${p1}.${p2}.${p3}/${p4}`;
  return `${p1}.${p2}.${p3}/${p4}-${p5}`;
}

function formatWhatsapp(value: string): string {
  const digits = onlyDigits(value).slice(0, 11);
  const ddd = digits.slice(0, 2);
  const part1 = digits.slice(2, 7);
  const part2 = digits.slice(7, 11);
  if (digits.length <= 2) return ddd;
  if (digits.length <= 7) return `${ddd} ${part1}`;
  return `${ddd} ${part1}-${part2}`;
}

function normalizeOptionalText(value: string): string | null {
  const normalized = value.trim();
  return normalized.length > 0 ? normalized : null;
}

function validateLogoFile(file: File): string | null {
  if (!ALLOWED_IMAGE_TYPES.has(file.type)) {
    return "Arquivo inválido. Use JPG, PNG ou WEBP.";
  }
  if (file.size > MAX_FILE_SIZE) {
    return "Arquivo excede 5MB. Escolha uma imagem menor.";
  }
  return null;
}

function mapPerfilToForm(perfil: MeuParceiroPerfilData): PerfilForm {
  return {
    nome: perfil.nome ?? "",
    email: perfil.email ?? "",
    whatsapp: onlyDigits(perfil.whatsapp ?? ""),
    tipoPessoa: perfil.tipoPessoa,
    cpf: onlyDigits(perfil.cpf ?? ""),
    cnpj: onlyDigits(perfil.cnpj ?? ""),
    logoUrl: perfil.logoUrl ?? "",
  };
}

export default function MeuPerfil() {
  const { me } = useAuthAccess();
  const logoFileInputRef = useRef<HTMLInputElement | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [uploadingLogo, setUploadingLogo] = useState(false);
  const [perfil, setPerfil] = useState<MeuParceiroPerfilData | null>(null);
  const [form, setForm] = useState<PerfilForm>(FORM_INICIAL);
  const [selectedLogoFile, setSelectedLogoFile] = useState<File | null>(null);
  const [logoPreviewUrl, setLogoPreviewUrl] = useState<string | null>(null);

  const semVinculo = !me?.parceiroId;
  const tipoPessoa = form.tipoPessoa;
  const isPessoaFisica = tipoPessoa === "fisica";
  const logoDisplayUrl = logoPreviewUrl ?? normalizeOptionalText(form.logoUrl);

  const logoStatusLabel = useMemo(() => {
    if (uploadingLogo) return "Enviando foto...";
    if (selectedLogoFile) return `Arquivo selecionado: ${selectedLogoFile.name}`;
    return "Nenhum arquivo novo selecionado.";
  }, [selectedLogoFile, uploadingLogo]);

  useEffect(() => {
    return () => {
      if (logoPreviewUrl) {
        URL.revokeObjectURL(logoPreviewUrl);
      }
    };
  }, [logoPreviewUrl]);

  useEffect(() => {
    if (semVinculo) {
      setLoading(false);
      return;
    }
    if (!me?.email) {
      setLoading(false);
      toast.error("Não foi possível identificar o e-mail do usuário logado.");
      return;
    }

    let cancelled = false;
    const carregarPerfil = async () => {
      try {
        setLoading(true);
        const data = await authMeService.getMeuParceiroPerfil(me.email);
        if (cancelled) return;
        setPerfil(data);
        setForm(mapPerfilToForm(data));
      } catch (error) {
        if (cancelled) return;
        const message = error instanceof Error ? error.message : "Erro ao carregar perfil.";
        toast.error(message);
      } finally {
        if (!cancelled) {
          setLoading(false);
        }
      }
    };
    void carregarPerfil();
    return () => {
      cancelled = true;
    };
  }, [me?.email, semVinculo]);

  const handleLogoFileChange: ChangeEventHandler<HTMLInputElement> = (event) => {
    const file = event.target.files?.[0];
    if (!file) return;
    const validationMessage = validateLogoFile(file);
    if (validationMessage) {
      toast.error(validationMessage);
      event.currentTarget.value = "";
      return;
    }
    if (logoPreviewUrl) {
      URL.revokeObjectURL(logoPreviewUrl);
    }
    setSelectedLogoFile(file);
    setLogoPreviewUrl(URL.createObjectURL(file));
  };

  const clearLogoSelection = () => {
    if (logoPreviewUrl) {
      URL.revokeObjectURL(logoPreviewUrl);
    }
    setSelectedLogoFile(null);
    setLogoPreviewUrl(null);
    if (logoFileInputRef.current) {
      logoFileInputRef.current.value = "";
    }
    setForm((prev) => ({ ...prev, logoUrl: "" }));
  };

  const validateForm = (): boolean => {
    if (!form.nome.trim()) {
      toast.error("Nome é obrigatório.");
      return false;
    }
    if (!form.email.trim()) {
      toast.error("E-mail é obrigatório.");
      return false;
    }
    if (isPessoaFisica && onlyDigits(form.cpf).length !== 11) {
      toast.error("CPF deve conter 11 dígitos.");
      return false;
    }
    if (!isPessoaFisica && onlyDigits(form.cnpj).length !== 14) {
      toast.error("CNPJ deve conter 14 dígitos.");
      return false;
    }
    return true;
  };

  const uploadLogoIfNeeded = async (): Promise<string | null> => {
    if (!selectedLogoFile) {
      return normalizeOptionalText(form.logoUrl);
    }
    setUploadingLogo(true);
    try {
      const signed = await fechamentoUploadsService.presignUploadParceiroLogo({
        fileName: selectedLogoFile.name,
        contentType: selectedLogoFile.type as "image/jpeg" | "image/png" | "image/webp",
      });
      await fechamentoUploadsService.uploadFileToSignedUrl(signed.uploadUrl, selectedLogoFile);
      return signed.publicUrl;
    } finally {
      setUploadingLogo(false);
    }
  };

  const handleSalvar = async () => {
    if (!me?.email || !perfil) return;
    if (!validateForm()) return;
    try {
      setSaving(true);
      const logoUrl = await uploadLogoIfNeeded();
      const atualizado = await authMeService.patchMeuParceiroPerfil(me.email, {
        nome: form.nome.trim(),
        email: form.email.trim(),
        whatsapp: normalizeOptionalText(formatWhatsapp(form.whatsapp)),
        logoUrl,
        cpf: isPessoaFisica ? onlyDigits(form.cpf) : null,
        cnpj: !isPessoaFisica ? onlyDigits(form.cnpj) : null,
      });
      setPerfil(atualizado);
      setForm(mapPerfilToForm(atualizado));
      if (logoPreviewUrl) {
        URL.revokeObjectURL(logoPreviewUrl);
      }
      setLogoPreviewUrl(null);
      setSelectedLogoFile(null);
      toast.success("Perfil atualizado com sucesso.");
    } catch (error) {
      const message = error instanceof Error ? error.message : "Erro ao atualizar perfil.";
      toast.error(message);
    } finally {
      setSaving(false);
    }
  };

  if (loading) {
    return (
      <div className="flex h-full items-center justify-center p-6">
        <div className="inline-flex items-center gap-2 text-sm text-muted-foreground">
          <Loader2 className="h-4 w-4 animate-spin" />
          Carregando perfil...
        </div>
      </div>
    );
  }

  if (semVinculo) {
    return (
      <div className="p-3 md:p-6">
        <Card className="mx-auto max-w-2xl">
          <CardHeader>
            <CardTitle>Usuário não vinculado</CardTitle>
            <CardDescription>
              Este usuário não está vinculado a um parceiro. Para editar o perfil, é necessário vínculo com parceiro.
            </CardDescription>
          </CardHeader>
        </Card>
      </div>
    );
  }

  if (!perfil) {
    return (
      <div className="p-3 md:p-6">
        <Card className="mx-auto max-w-2xl">
          <CardHeader>
            <CardTitle>Não foi possível carregar o perfil</CardTitle>
            <CardDescription>Tente atualizar a página novamente.</CardDescription>
          </CardHeader>
        </Card>
      </div>
    );
  }

  return (
    <div className="flex h-full flex-col bg-background pb-16 md:pb-0">
      <div className="border-b border-border p-3 md:p-6">
        <h1 className="flex items-center gap-2 text-xl font-bold text-foreground md:text-3xl">
          <UserCircle2 className="h-5 w-5 md:h-6 md:w-6" />
          Meu Perfil
        </h1>
        <p className="mt-1 text-sm text-muted-foreground">Atualize seus dados de contato e identificação.</p>
      </div>

      <div className="flex-1 overflow-auto p-3 md:p-6">
        <Card className="mx-auto max-w-4xl">
          <CardHeader>
            <CardTitle>Dados do parceiro vinculado</CardTitle>
            <CardDescription>Você pode editar apenas os campos permitidos para autoatendimento.</CardDescription>
          </CardHeader>
          <CardContent className="space-y-6">
            <div className="flex flex-col items-center gap-3 py-1">
              <button
                type="button"
                className="group relative h-24 w-24 overflow-hidden rounded-full border shadow-sm transition hover:brightness-95"
                onClick={() => logoFileInputRef.current?.click()}
                title="Clique para alterar a foto"
              >
                {logoDisplayUrl ? (
                  <img src={logoDisplayUrl} alt="Foto de perfil" className="h-full w-full object-cover" />
                ) : (
                  <div className="flex h-full w-full items-center justify-center text-muted-foreground">
                    <ImageIcon className="h-7 w-7" />
                  </div>
                )}
                <div className="absolute inset-0 flex items-center justify-center bg-black/45 text-white opacity-0 transition-opacity group-hover:opacity-100">
                  <span className="inline-flex items-center gap-1 text-xs font-medium">
                    <Upload className="h-3.5 w-3.5" />
                    Alterar foto
                  </span>
                </div>
              </button>
              <input
                ref={logoFileInputRef}
                type="file"
                accept=".jpg,.jpeg,.png,.webp,image/jpeg,image/png,image/webp"
                onChange={handleLogoFileChange}
                className="hidden"
              />
              <p className="text-center text-xs text-muted-foreground">{logoStatusLabel}</p>
              <Button type="button" variant="outline" size="sm" onClick={clearLogoSelection} disabled={uploadingLogo}>
                Remover foto
              </Button>
            </div>

            <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
              <div className="md:col-span-2">
                <Label htmlFor="perfil-nome">Nome</Label>
                <Input
                  id="perfil-nome"
                  value={form.nome}
                  onChange={(e) => setForm((prev) => ({ ...prev, nome: e.target.value }))}
                />
              </div>

              <div>
                <Label htmlFor="perfil-email">E-mail</Label>
                <Input
                  id="perfil-email"
                  type="email"
                  value={form.email}
                  onChange={(e) => setForm((prev) => ({ ...prev, email: e.target.value }))}
                />
              </div>

              <div>
                <Label htmlFor="perfil-whatsapp">WhatsApp</Label>
                <Input
                  id="perfil-whatsapp"
                  value={formatWhatsapp(form.whatsapp)}
                  onChange={(e) => setForm((prev) => ({ ...prev, whatsapp: onlyDigits(e.target.value).slice(0, 11) }))}
                  placeholder="11 99999-9999"
                />
              </div>

              <div>
                <Label>Tipo de Pessoa</Label>
                <Select
                  value={form.tipoPessoa}
                  onValueChange={(value) =>
                    setForm((prev) => ({
                      ...prev,
                      tipoPessoa: value as "fisica" | "juridica",
                      cpf: value === "fisica" ? prev.cpf : "",
                      cnpj: value === "juridica" ? prev.cnpj : "",
                    }))
                  }
                >
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="juridica">Jurídica</SelectItem>
                    <SelectItem value="fisica">Física</SelectItem>
                  </SelectContent>
                </Select>
              </div>

              {isPessoaFisica ? (
                <div>
                  <Label htmlFor="perfil-cpf">CPF</Label>
                  <Input
                    id="perfil-cpf"
                    value={formatCpf(form.cpf)}
                    onChange={(e) => setForm((prev) => ({ ...prev, cpf: onlyDigits(e.target.value).slice(0, 11) }))}
                    placeholder="000.000.000-00"
                  />
                </div>
              ) : (
                <div>
                  <Label htmlFor="perfil-cnpj">CNPJ</Label>
                  <Input
                    id="perfil-cnpj"
                    value={formatCnpj(form.cnpj)}
                    onChange={(e) => setForm((prev) => ({ ...prev, cnpj: onlyDigits(e.target.value).slice(0, 14) }))}
                    placeholder="00.000.000/0000-00"
                  />
                </div>
              )}
            </div>

            <div className="flex justify-end">
              <Button onClick={() => void handleSalvar()} disabled={saving || uploadingLogo}>
                {saving ? (
                  <>
                    <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                    Salvando...
                  </>
                ) : (
                  "Salvar alterações"
                )}
              </Button>
            </div>
          </CardContent>
        </Card>
      </div>
    </div>
  );
}

