"use client";

import { useEffect, useState } from "react";
import Link from "next/link";
import dynamic from "next/dynamic";
import { getSupabaseClient } from "@/lib/supabase";
import { CalendarClock, Check, ExternalLink, Loader2, MapPin, Pencil, Trash2, X } from "lucide-react";
import { doTexto, type CategoriaAgenda, type EventoAgenda } from "./tipos";
import FormularioCompromisso, { COMPROMISSO_VAZIO, type Compromisso } from "./painel-compromisso";

const MapaDoDia = dynamic(() => import("./mapa"), { ssr: false });

const MOEDA = new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL" });

type Detalhe = {
  id: string;
  title: string;
  description: string | null;
  event_date: string;
  start_time: string | null;
  end_time: string | null;
  status: string;
  recurrence: string;
  recurrence_until: string | null;
  lembrete_minutos: number | null;
  responsible_user_id: string | null;
  location_address: string | null;
  location_lat: number | null;
  location_lng: number | null;
  client_id: string | null;
  category_id: string;
  color: string | null;
};

const REPETICAO: Record<string, string> = {
  none: "Não repete",
  daily: "Todo dia",
  weekly: "Toda semana",
  monthly: "Todo mês",
};

/**
 * Painel de compromisso, em sidebar que desliza da direita.
 *
 * Um painel so, com tres cabecas: ver, editar e criar. Antes, editar fechava
 * esta sidebar e abria um modal por cima — dois componentes disputando a
 * mesma acao, com uma troca visual desconexa no meio. Agora "Editar" e "Novo
 * compromisso" so trocam o que aparece dentro do mesmo painel: o cabecalho e
 * a moldura continuam ali, só o conteudo muda.
 *
 * O painel fica por cima da pagina, e nao ao lado: empurrar o conteudo faria
 * a agenda inteira se reorganizar a cada clique, e a linha do tempo perderia
 * a posicao que a pessoa estava lendo.
 *
 * O mapa mora aqui, e nao no rodape da tela. Cada compromisso tem o seu — o
 * mapa unico embaixo mostrava sempre o mesmo lugar independente do que fosse
 * clicado.
 */
export default function PainelDetalhe({
  evento,
  criarEm,
  clientes,
  categorias,
  aoFechar,
  aoConcluir,
  aoApagar,
  aoAtualizou,
  podeEditar,
}: {
  evento: EventoAgenda | null;
  criarEm: { data: string; hora: number | null } | null;
  clientes: { id: string; nome: string }[];
  categorias: CategoriaAgenda[];
  aoFechar: () => void;
  aoConcluir: (evento: EventoAgenda) => void;
  aoApagar: (id: string) => void;
  aoAtualizou: () => void;
  podeEditar: boolean;
}) {
  const aberto = Boolean(evento) || Boolean(criarEm);
  const [entrou, setEntrou] = useState(false);
  const [modo, setModo] = useState<"ver" | "form">("ver");
  const [detalhe, setDetalhe] = useState<Detalhe | null>(null);
  const [cliente, setCliente] = useState<string | null>(null);
  const [carregando, setCarregando] = useState(false);

  /* Dois quadros entre montar e animar: aplicar a classe final no mesmo
     quadro em que o elemento nasce faz o navegador pular a transicao. */
  useEffect(() => {
    if (!aberto) {
      setEntrou(false);
      return;
    }
    const t = requestAnimationFrame(() => requestAnimationFrame(() => setEntrou(true)));
    return () => cancelAnimationFrame(t);
  }, [aberto]);

  useEffect(() => {
    if (!aberto) return;
    const aoTeclar = (e: KeyboardEvent) => e.key === "Escape" && aoFechar();
    window.addEventListener("keydown", aoTeclar);
    const antes = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => {
      window.removeEventListener("keydown", aoTeclar);
      document.body.style.overflow = antes;
    };
  }, [aberto, aoFechar]);

  /* Criar comeca direto no formulario; abrir um evento sempre comeca vendo —
     editar e a excecao, e agora e um clique a mais dentro do mesmo painel. */
  useEffect(() => {
    setModo(criarEm ? "form" : "ver");
  }, [evento, criarEm]);

  useEffect(() => {
    if (!evento || evento.tipo !== "compromisso") {
      setDetalhe(null);
      setCliente(null);
      return;
    }
    let ativo = true;
    setCarregando(true);
    (async () => {
      try {
        const supabase = getSupabaseClient();
        const { data } = await supabase
          .from("agenda_events")
          .select(
            "id,title,description,event_date,start_time,end_time,status,recurrence,recurrence_until,lembrete_minutos,responsible_user_id,location_address,location_lat,location_lng,client_id,category_id,color"
          )
          .eq("id", evento.origem_id)
          .maybeSingle();
        if (!ativo) return;
        setDetalhe((data as Detalhe) ?? null);
        if (data?.client_id) {
          const { data: c } = await supabase
            .from("clients")
            .select("name,company_name")
            .eq("id", data.client_id)
            .maybeSingle();
          if (ativo) setCliente(c ? String(c.company_name || c.name) : null);
        } else {
          setCliente(null);
        }
      } finally {
        if (ativo) setCarregando(false);
      }
    })();
    return () => {
      ativo = false;
    };
  }, [evento]);

  if (!aberto) return null;

  const ehCompromisso = evento?.tipo === "compromisso";
  const cor = evento?.categoria_cor ?? "#4425A7";
  const temMapa = Boolean(detalhe?.location_lat && detalhe?.location_lng);
  const categoriaPadrao = categorias.find((c) => !c.is_system)?.id ?? "";

  const inicialForm: Compromisso | null = criarEm
    ? COMPROMISSO_VAZIO(criarEm.data, categoriaPadrao, criarEm.hora)
    : detalhe
      ? {
          id: detalhe.id,
          title: detalhe.title,
          description: detalhe.description,
          event_date: detalhe.event_date,
          start_time: detalhe.start_time ? String(detalhe.start_time).slice(0, 5) : "",
          end_time: detalhe.end_time ? String(detalhe.end_time).slice(0, 5) : "",
          client_id: detalhe.client_id,
          status: detalhe.status,
          recurrence: detalhe.recurrence,
          recurrence_until: detalhe.recurrence_until,
          lembrete_minutos: detalhe.lembrete_minutos,
          responsible_user_id: detalhe.responsible_user_id,
          location_address: detalhe.location_address,
          location_lat: detalhe.location_lat,
          location_lng: detalhe.location_lng,
          category_id: detalhe.category_id,
          color: detalhe.color,
        }
      : null;

  const Linha = ({ rotulo, valor }: { rotulo: string; valor: React.ReactNode }) =>
    valor ? (
      <div className="border-b border-[var(--ks-color-border-subtle)] py-2.5 last:border-0">
        <p className="text-[11px] font-black uppercase tracking-wide text-[var(--ks-color-text-muted)]">
          {rotulo}
        </p>
        <p className="mt-0.5 text-sm text-[var(--ks-color-text-primary)]">{valor}</p>
      </div>
    ) : null;

  const horario = detalhe?.start_time
    ? `${String(detalhe.start_time).slice(0, 5)}${
        detalhe.end_time ? ` às ${String(detalhe.end_time).slice(0, 5)}` : ""
      }`
    : null;

  return (
    <div className="fixed inset-0 z-[70]">
      {/* Fundo desfocado, igual ao menu do celular. */}
      <button
        type="button"
        aria-label="Fechar"
        onClick={aoFechar}
        className={`absolute inset-0 bg-slate-900/40 backdrop-blur-sm transition-opacity duration-300 ${
          entrou ? "opacity-100" : "opacity-0"
        }`}
      />

      <aside
        role="dialog"
        aria-modal="true"
        aria-label={modo === "form" ? "Formulário de compromisso" : "Detalhes do compromisso"}
        className={`absolute inset-y-0 right-0 flex w-full max-w-[420px] flex-col bg-[var(--ks-color-bg-body)] shadow-2xl transition-transform duration-300 ease-out ${
          entrou ? "translate-x-0" : "translate-x-full"
        }`}
      >
        {modo === "form" ? (
          <header className="flex items-center justify-between gap-3 border-b border-[var(--ks-color-border-subtle)] p-4">
            <h2 className="text-lg font-black text-[var(--ks-color-text-primary)]">
              {criarEm ? "Novo compromisso" : "Editar compromisso"}
            </h2>
            <button
              type="button"
              onClick={aoFechar}
              aria-label="Fechar"
              className="flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl text-[var(--ks-color-text-muted)] hover:bg-[var(--ks-color-bg-soft)]"
            >
              <X className="h-4 w-4" />
            </button>
          </header>
        ) : (
          <header className="flex items-start gap-3 border-b border-[var(--ks-color-border-subtle)] p-4">
            <span
              aria-hidden
              className="mt-1 h-10 w-1.5 shrink-0 rounded-full"
              style={{ background: cor }}
            />
            <div className="min-w-0 flex-1">
              <span
                className="inline-block rounded-full px-2 py-0.5 text-[10px] font-black uppercase tracking-wide"
                style={{ background: `${cor}1F`, color: cor }}
              >
                {evento?.categoria_nome}
              </span>
              <h2 className="mt-1 text-lg font-black leading-tight text-[var(--ks-color-text-primary)]">
                {evento?.titulo}
              </h2>
            </div>
            <button
              type="button"
              onClick={aoFechar}
              aria-label="Fechar"
              className="flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl text-[var(--ks-color-text-muted)] hover:bg-[var(--ks-color-bg-soft)]"
            >
              <X className="h-4 w-4" />
            </button>
          </header>
        )}

        {modo === "form" && inicialForm ? (
          <FormularioCompromisso
            /* A data e a hora entram na chave: com o painel ja aberto, clicar
               noutra celula da grade so troca as props, e o formulario manteria
               os campos da celula anterior. */
            key={inicialForm.id ?? `novo-${criarEm?.data}-${criarEm?.hora ?? "s"}`}
            inicial={inicialForm}
            clientes={clientes}
            categorias={categorias.filter((c) => !c.is_system)}
            aoApagar={evento ? () => aoApagar(evento.origem_id) : undefined}
            aoSalvou={aoAtualizou}
            aoCancelar={() => (criarEm ? aoFechar() : setModo("ver"))}
          />
        ) : modo === "form" ? (
          <div className="flex flex-1 items-center justify-center p-4">
            <Loader2 className="h-5 w-5 animate-spin text-[var(--ks-color-text-muted)]" />
          </div>
        ) : (
          evento && (
            <>
              <div className="min-h-0 flex-1 overflow-y-auto p-4">
                {carregando && (
                  <p className="flex items-center gap-2 py-4 text-sm text-[var(--ks-color-text-muted)]">
                    <Loader2 className="h-4 w-4 animate-spin" /> Carregando…
                  </p>
                )}

                {/* Quando e o que mais importa ao abrir: em destaque, antes de
                    qualquer outro dado. */}
                <div className="mb-1 rounded-2xl p-3.5" style={{ background: `${cor}14` }}>
                  <p
                    className="flex items-center gap-1.5 text-[11px] font-black uppercase tracking-wide"
                    style={{ color: cor }}
                  >
                    <CalendarClock className="h-3.5 w-3.5" /> Quando
                  </p>
                  <p className="mt-1 text-lg font-black capitalize leading-tight text-[var(--ks-color-text-primary)]">
                    {doTexto(evento.data).toLocaleDateString("pt-BR", {
                      weekday: "long",
                      day: "2-digit",
                      month: "long",
                    })}
                  </p>
                  {horario && (
                    <p className="mt-0.5 text-2xl font-black tabular-nums text-[var(--ks-color-text-primary)]">
                      {horario}
                    </p>
                  )}
                </div>

                <Linha rotulo="Cliente" valor={cliente || (ehCompromisso ? null : evento.subtitulo)} />
                {evento.valor ? <Linha rotulo="Valor" valor={MOEDA.format(Number(evento.valor))} /> : null}
                <Linha rotulo="Situação" valor={detalhe?.status ?? evento.situacao} />
                {detalhe && detalhe.recurrence !== "none" ? (
                  <Linha
                    rotulo="Repetição"
                    valor={`${REPETICAO[detalhe.recurrence] ?? detalhe.recurrence}${
                      detalhe.recurrence_until
                        ? ` até ${doTexto(detalhe.recurrence_until).toLocaleDateString("pt-BR")}`
                        : ""
                    }`}
                  />
                ) : null}
                <Linha rotulo="Observação" valor={detalhe?.description} />
                <Linha rotulo="Endereço" valor={detalhe?.location_address} />

                {temMapa && (
                  <div className="mt-3">
                    <MapaDoDia
                      pontos={[
                        {
                          id: evento.origem_id,
                          titulo: evento.titulo,
                          hora: detalhe?.start_time ? String(detalhe.start_time).slice(0, 5) : null,
                          lat: Number(detalhe!.location_lat),
                          lng: Number(detalhe!.location_lng),
                          ordem: 1,
                        },
                      ]}
                    />
                    <a
                      href={`https://www.google.com/maps/dir/?api=1&destination=${detalhe!.location_lat},${detalhe!.location_lng}`}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="mt-2 flex min-h-[44px] items-center justify-center gap-2 rounded-xl border border-[var(--ks-color-border-subtle)] text-xs font-bold text-[var(--ks-color-text-primary)] hover:bg-[var(--ks-color-bg-soft)]"
                    >
                      <MapPin className="h-3.5 w-3.5" /> Traçar rota até aqui
                    </a>
                  </div>
                )}

                {!ehCompromisso && (
                  <Link
                    href={evento.rota}
                    className="mt-3 flex min-h-[48px] items-center justify-center gap-2 rounded-2xl bg-[var(--ks-color-primary)] px-4 text-sm font-black text-white hover:opacity-90"
                  >
                    <ExternalLink className="h-4 w-4" /> Abrir o registro
                  </Link>
                )}
              </div>

              {ehCompromisso && podeEditar && (
                <footer
                  /* Folga a esquerda no celular: o balao flutuante do sistema mora
                     no canto de baixo e cobria o botao de apagar. */
                  className="flex gap-2 border-t border-[var(--ks-color-border-subtle)] p-4 pl-16 sm:pl-4"
                >
                  <button
                    type="button"
                    onClick={() => aoApagar(evento.origem_id)}
                    aria-label="Apagar"
                    className="flex min-h-[48px] w-12 items-center justify-center rounded-2xl border border-rose-200 text-rose-600 hover:bg-rose-50 dark:border-rose-500/30 dark:hover:bg-rose-500/10"
                  >
                    <Trash2 className="h-4 w-4" />
                  </button>
                  <button
                    type="button"
                    onClick={() => aoConcluir(evento)}
                    disabled={carregando}
                    className="flex min-h-[48px] flex-1 items-center justify-center gap-2 rounded-2xl border border-emerald-200 text-sm font-bold text-emerald-700 hover:bg-emerald-50 disabled:opacity-50 dark:border-emerald-500/30 dark:text-emerald-300 dark:hover:bg-emerald-500/10"
                  >
                    <Check className="h-4 w-4" /> Concluir
                  </button>
                  <button
                    type="button"
                    onClick={() => setModo("form")}
                    disabled={carregando || !detalhe}
                    className="flex min-h-[48px] flex-1 items-center justify-center gap-2 rounded-2xl bg-[var(--ks-color-primary)] text-sm font-black text-white hover:opacity-90 disabled:opacity-50"
                  >
                    <Pencil className="h-4 w-4" /> Editar
                  </button>
                </footer>
              )}
            </>
          )
        )}
      </aside>
    </div>
  );
}
