"use client";

import { useEffect, useMemo, useState } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";
import { MoreHorizontal, Plus, Search, Eye, Edit, Trash2, ArrowLeft, ShieldCheck } from "lucide-react";

import {
  Paciente,
  listarPacientes,
  buscarPacientes,
  buscarPacientePorId,
  excluirPaciente,
  listarAutorizacoesUsuario,
  atualizarAutorizacoesUsuario,
  type AuthorizationRole,
} from "@/lib/api";
import { PatientRegistrationForm } from "@/components/forms/patient-registration-form";
import { getCurrentUser, atualizarPaciente } from "@/lib/api";
import {
  UpdateAuthorizationsDialog,
  type AuthorizationState,
} from "@/components/dialogs/update-authorizations-dialog";
import { useToast } from "@/hooks/use-toast";


function normalizePaciente(p: any): Paciente {
  return {
    id: String(p.id ?? p.uuid ?? p.paciente_id ?? ""),
    full_name: p.full_name ?? p.name ?? p.nome ?? "",
    social_name: p.social_name ?? p.nome_social ?? null,
    cpf: p.cpf ?? "",
    rg: p.rg ?? p.document_number ?? null,
    sex: p.sex ?? p.sexo ?? null,
    birth_date: p.birth_date ?? p.data_nascimento ?? null,
    phone_mobile: p.phone_mobile ?? p.telefone ?? "",
    email: p.email ?? "",
    cep: p.cep ?? "",
    street: p.street ?? p.logradouro ?? "",
    number: p.number ?? p.numero ?? "",
    complement: p.complement ?? p.complemento ?? "",
    neighborhood: p.neighborhood ?? p.bairro ?? "",
    city: p.city ?? p.cidade ?? "",
    state: p.state ?? p.estado ?? "",
    notes: p.notes ?? p.observacoes ?? null,
    user_id: p.user_id ?? p.usuario_id ?? p.userId ?? null,
  };
}


export default function PacientesPage() {
  const [patients, setPatients] = useState<Paciente[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const [search, setSearch] = useState("");
  const [showForm, setShowForm] = useState(false);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [viewingPatient, setViewingPatient] = useState<Paciente | null>(null);
  const [authDialogOpen, setAuthDialogOpen] = useState(false);
  const [authTargetPatient, setAuthTargetPatient] = useState<Paciente | null>(null);
  const [authInitialRoles, setAuthInitialRoles] = useState<AuthorizationState | null>(null);
  const [authorizationsLoading, setAuthorizationsLoading] = useState(false);
  const [authorizationsError, setAuthorizationsError] = useState<string | null>(null);
  const [authorizationsSubmitDisabled, setAuthorizationsSubmitDisabled] = useState(false);

  const { toast } = useToast();

  async function loadAll() {
    try {
      setLoading(true);
      const data = await listarPacientes({ page: 1, limit: 20 });
      
      if (Array.isArray(data)) {
        setPatients(data.map(normalizePaciente));
      } else {
        setPatients([]);
      }
      setError(null);
    } catch (e: any) {
      setPatients([]);
      setError(e?.message || "Erro ao carregar pacientes.");
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => {
    loadAll();
  }, []);

  const filtered = useMemo(() => {
    if (!search.trim()) return patients;
    const q = search.toLowerCase().trim();
    const qDigits = q.replace(/\D/g, "");
    
    return patients.filter((p) => {
      // Busca por nome
      const byName = (p.full_name || "").toLowerCase().includes(q);
      
      // Busca por CPF (remove formatação)
      const byCPF = qDigits.length >= 3 && (p.cpf || "").replace(/\D/g, "").includes(qDigits);
      
      // Busca por ID (UUID completo ou parcial)
      const byId = (p.id || "").toLowerCase().includes(q);
      
      // Busca por email
      const byEmail = (p.email || "").toLowerCase().includes(q);
      
      return byName || byCPF || byId || byEmail;
    });
  }, [patients, search]);

  function handleAdd() {
    setEditingId(null);
    setShowForm(true);
  }

  function handleEdit(id: string) {
    setEditingId(id);
    setShowForm(true);
  }

  function handleView(patient: Paciente) {
    setViewingPatient(patient);
  }

  async function handleOpenAuthorizations(patient: Paciente) {
    setAuthTargetPatient(patient);
    setAuthDialogOpen(true);
    setAuthorizationsLoading(!!patient.user_id);
    setAuthorizationsError(null);
    setAuthInitialRoles(null);
    setAuthorizationsSubmitDisabled(false);

    if (!patient.user_id) {
      setAuthorizationsError(
        "Este paciente ainda não possui um usuário vinculado. Cadastre ou vincule um usuário para gerenciar autorizações.",
      );
      setAuthInitialRoles({ paciente: true, medico: false });
      setAuthorizationsSubmitDisabled(true);
      return;
    }

    try {
      const roles = await listarAutorizacoesUsuario(patient.user_id);
      if (!roles.length) {
        setAuthInitialRoles({ paciente: true, medico: false });
      } else {
        setAuthInitialRoles({
          paciente: roles.includes("paciente"),
          medico: roles.includes("medico"),
        });
      }
    } catch (e: any) {
      setAuthorizationsError(e?.message || "Erro ao carregar autorizações.");
    } finally {
      setAuthorizationsLoading(false);
    }
  }

  function handleAuthDialogOpenChange(open: boolean) {
    if (!open) {
      setAuthDialogOpen(false);
      setAuthTargetPatient(null);
      setAuthInitialRoles(null);
      setAuthorizationsError(null);
      setAuthorizationsLoading(false);
      setAuthorizationsSubmitDisabled(false);
    }
  }

  async function handleConfirmAuthorizations(selection: AuthorizationState) {
    if (!authTargetPatient?.user_id) {
      toast({
        title: "Usuário não vinculado",
        description: "Não foi possível atualizar as autorizações porque o usuário não está vinculado.",
        variant: "destructive",
      });
      setAuthorizationsError(
        "Vincule este paciente a um usuário antes de ajustar as autorizações.",
      );
      setAuthorizationsSubmitDisabled(true);
      return;
    }

  console.log("[Auth] Confirm clicked", selection, "targetUserId=", authTargetPatient?.user_id);
  setAuthorizationsLoading(true);
    setAuthorizationsError(null);

  const selectedRoles: AuthorizationRole[] = [];
    if (selection.paciente) selectedRoles.push("paciente");
    if (selection.medico) selectedRoles.push("medico");

    try {
      console.log("[Auth] Updating roles to server:", selectedRoles);
      const result = await atualizarAutorizacoesUsuario(authTargetPatient.user_id, selectedRoles);
      console.log("[Auth] Update result:", result);
      toast({
        title: "Autorizações atualizadas",
        description: "As permissões deste paciente foram atualizadas com sucesso.",
      });
      setAuthDialogOpen(false);
      setAuthTargetPatient(null);
      setAuthInitialRoles(null);
      await loadAll();
    } catch (e: any) {
      toast({
        title: "Erro ao atualizar autorizações",
        description: e?.message || "Não foi possível atualizar as autorizações.",
        variant: "destructive",
      });
    } finally {
      setAuthorizationsLoading(false);
    }
  }

  async function handleDelete(id: string) {
    if (!confirm("Excluir este paciente?")) return;
    try {
      await excluirPaciente(id);
      setPatients((prev) => prev.filter((x) => String(x.id) !== String(id)));
    } catch (e: any) {
      alert(e?.message || "Não foi possível excluir.");
    }
  }

  async function handleSaved(p: Paciente) {
    // Normaliza e atualiza localmente
    let saved = normalizePaciente(p);
    // Vincula o registro de paciente ao usuário autenticado
    try {
      const user = await getCurrentUser();
  // Preparar payload apenas com campos de PacienteInput e user_id
  const { id: _id, user_id: _oldUserId, ...rest } = saved;
  const payload = { ...rest, user_id: user.id };
  const linked = await atualizarPaciente(saved.id, payload);
      saved = normalizePaciente(linked);
    } catch (e) {
      // Se falhar, mantém saved original
      console.warn("Falha ao vincular usuário ao paciente:", e);
    }
    // Atualiza lista com o registro vinculado
    setPatients((prev) => {
      const i = prev.findIndex((x) => String(x.id) === String(saved.id));
      if (i < 0) return [saved, ...prev];
      const clone = [...prev];
      clone[i] = saved;
      return clone;
    });
    setShowForm(false);
  }

  async function handleBuscarServidor() {
    const q = search.trim();
    if (!q) return loadAll();

    try {
      setLoading(true);
      setError(null);

      // Se parece com ID (UUID), busca diretamente
      if (q.includes('-') && q.length > 10) {
        const one = await buscarPacientePorId(q);
        setPatients(one ? [normalizePaciente(one)] : []);
        setError(one ? null : "Paciente não encontrado.");
        // Limpa o campo de busca para que o filtro não interfira
        setSearch("");
        return;
      }

      // Para outros termos, usa busca avançada
      const results = await buscarPacientes(q);
      setPatients(results.map(normalizePaciente));
      setError(results.length === 0 ? "Nenhum paciente encontrado." : null);
      // Limpa o campo de busca para que o filtro não interfira
      setSearch("");
      
    } catch (e: any) {
      setPatients([]);
      setError(e?.message || "Erro na busca.");
    } finally {
      setLoading(false);
    }
  }

  function handleBuscarClick() {
    void handleBuscarServidor();
  }

  if (loading) return <p>Carregando pacientes...</p>;
  if (error) return <p className="text-red-500">{error}</p>;

  if (showForm) {
    return (
      <div className="space-y-6 p-6 bg-background">
        <div className="flex items-center gap-4">
          <Button variant="ghost" onClick={() => setShowForm(false)}>
            <ArrowLeft className="h-4 w-4" />
          </Button>
          <h1 className="text-2xl font-bold">{editingId ? "Editar paciente" : "Novo paciente"}</h1>
        </div>

        <PatientRegistrationForm
          inline
          mode={editingId ? "edit" : "create"}
          patientId={editingId}
          onSaved={handleSaved}
          onClose={() => setShowForm(false)}
        />
      </div>
    );
  }

  console.log(
    '[Page] Rendering dialog, passing onConfirm. Typeof handleConfirmAuthorizations is:',
    typeof handleConfirmAuthorizations,
  );

  return (
    <div className="flex h-full flex-col space-y-6 p-6 bg-background">
      <div className="flex items-center justify-between gap-4 flex-wrap">
        <div>
          <h1 className="text-2xl font-bold">Pacientes</h1>
          <p className="text-muted-foreground">Gerencie os pacientes</p>
        </div>

        <div className="flex items-center gap-2">
          <div className="relative">
            <Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
            <Input
              className="pl-8 w-80"
              placeholder="Buscar por nome, CPF ou ID…"
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              onKeyDown={(e) => e.key === "Enter" && handleBuscarServidor()}
            />
          </div>
          <Button variant="secondary" onClick={handleBuscarClick} className="hover:bg-primary hover:text-white">Buscar</Button>
          <Button onClick={handleAdd}>
            <Plus className="mr-2 h-4 w-4" />
            Novo paciente
          </Button>
        </div>
      </div>

      <div className="border rounded-lg overflow-hidden">
        <Table>
          <TableHeader>
            <TableRow>
              <TableHead>Nome</TableHead>
              <TableHead>CPF</TableHead>
              <TableHead>Telefone</TableHead>
              <TableHead>Cidade</TableHead>
              <TableHead>Estado</TableHead>
              <TableHead className="w-[100px]">Ações</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {filtered.length > 0 ? (
              filtered.map((p) => (
                <TableRow key={p.id}>
                  <TableCell className="font-medium">{p.full_name || "(sem nome)"}</TableCell>
                  <TableCell>{p.cpf || "-"}</TableCell>
                  <TableCell>{p.phone_mobile || "-"}</TableCell>
                  <TableCell>{p.city || "-"}</TableCell>
                  <TableCell>{p.state || "-"}</TableCell>
                  <TableCell>
                    <DropdownMenu>
                      <DropdownMenuTrigger asChild>
                        <button className="h-8 w-8 p-0 flex items-center justify-center rounded-md hover:bg-accent">
                          <span className="sr-only">Abrir menu</span>
                          <MoreHorizontal className="h-4 w-4" />
                        </button>
                      </DropdownMenuTrigger>
                      <DropdownMenuContent align="end">
                        <DropdownMenuItem onClick={() => handleView(p)}>
                          <Eye className="mr-2 h-4 w-4" />
                          Ver
                        </DropdownMenuItem>
                        <DropdownMenuItem onClick={() => handleEdit(String(p.id))}>
                          <Edit className="mr-2 h-4 w-4" />
                          Editar
                        </DropdownMenuItem>
                        <DropdownMenuItem onClick={() => handleOpenAuthorizations(p)}>
                          <ShieldCheck className="mr-2 h-4 w-4" />
                          Atualizar autorizações
                        </DropdownMenuItem>
                        <DropdownMenuItem onClick={() => handleDelete(String(p.id))} className="text-destructive">
                          <Trash2 className="mr-2 h-4 w-4" />
                          Excluir
                        </DropdownMenuItem>
                      </DropdownMenuContent>
                    </DropdownMenu>
                  </TableCell>
                </TableRow>
              ))
            ) : (
              <TableRow>
                <TableCell colSpan={6} className="text-center text-muted-foreground">
                  Nenhum paciente encontrado
                </TableCell>
              </TableRow>
            )}
          </TableBody>
        </Table>
      </div>

      <div className="text-sm text-muted-foreground">Mostrando {filtered.length} de {patients.length}</div>

      <UpdateAuthorizationsDialog
        open={authDialogOpen}
        entityType="paciente"
        entityName={authTargetPatient?.full_name}
        initialRoles={authInitialRoles ?? undefined}
        loading={authorizationsLoading}
        error={authorizationsError}
        disableSubmit={authorizationsSubmitDisabled}
        onOpenChange={handleAuthDialogOpenChange}
        onConfirm={handleConfirmAuthorizations}
      />
    </div>
  );
}
