"use client";

import { useEffect, useMemo, useRef, useState } from "react";
import { ChevronDown, ChevronLeft, ChevronRight } from "lucide-react";
import { chaveDoDia, inicioDaSemana, somaDias } from "./tipos";

/**
 * Calendario proprio para pular direto a uma data.
 *
 * O input date nativo resolvia a navegacao, mas cada navegador desenha o seu:
 * fonte, cores e semana comecando no domingo, sem relacao nenhuma com o resto
 * da agenda. Este usa os mesmos tokens das outras pecas e comeca na segunda,
 * igual a grade da semana logo abaixo.
 *
 * Marca tres coisas diferentes de proposito: o dia selecionado (fundo cheio),
 * hoje (anel) e os dias de fora do mes (apagados). Sem essa separacao, abrir o
 * seletor num mes distante nao dava nenhuma referencia de onde a pessoa esta.
 */

const DIAS_CURTOS = ["S", "T", "Q", "Q", "S", "S", "D"];

export default function SeletorData({
  valor,
  aoEscolher,
  rotulo,
}: {
  valor: Date;
  aoEscolher: (d: Date) => void;
  rotulo: string;
}) {
  const [aberto, setAberto] = useState(false);
  const [mes, setMes] = useState(() => new Date(valor.getFullYear(), valor.getMonth(), 1));
  const caixa = useRef<HTMLDivElement>(null);

  /* Reabrir sempre mostra o mes da data atual da agenda: manter o mes de uma
     consulta anterior faria o seletor abrir longe de onde a pessoa esta. */
  useEffect(() => {
    if (aberto) setMes(new Date(valor.getFullYear(), valor.getMonth(), 1));
  }, [aberto, valor]);

  useEffect(() => {
    if (!aberto) return;
    const clique = (e: MouseEvent) => {
      if (!caixa.current?.contains(e.target as Node)) setAberto(false);
    };
    const tecla = (e: KeyboardEvent) => {
      if (e.key === "Escape") setAberto(false);
    };
    document.addEventListener("mousedown", clique);
    document.addEventListener("keydown", tecla);
    return () => {
      document.removeEventListener("mousedown", clique);
      document.removeEventListener("keydown", tecla);
    };
  }, [aberto]);

  const dias = useMemo(() => {
    const inicio = inicioDaSemana(mes);
    return Array.from({ length: 42 }, (_, i) => somaDias(inicio, i));
  }, [mes]);

  const hojeChave = chaveDoDia(new Date());
  const escolhidoChave = chaveDoDia(valor);

  const escolher = (d: Date) => {
    aoEscolher(d);
    setAberto(false);
  };

  return (
    <div ref={caixa} className="relative">
      <button
        type="button"
        onClick={() => setAberto((v) => !v)}
        aria-expanded={aberto}
        aria-haspopup="dialog"
        title="Escolher uma data"
        className={`ml-2 flex h-9 items-center gap-1.5 rounded-[9px] px-2 transition-colors ${
          aberto ? "bg-[var(--ag-accent-soft)]" : "hover:bg-[var(--ag-surface-2)]"
        }`}
      >
        <span
          className="truncate text-[14px] font-semibold capitalize"
          style={{ color: aberto ? "var(--ag-accent-text)" : "var(--ag-text)" }}
        >
          {rotulo}
        </span>
        <ChevronDown
          className={`h-3.5 w-3.5 shrink-0 transition-transform ${aberto ? "rotate-180" : ""}`}
          style={{ color: aberto ? "var(--ag-accent-text)" : "var(--ag-text-5)" }}
        />
      </button>

      {aberto && (
        <div
          role="dialog"
          aria-label="Escolher uma data"
          className="absolute left-0 top-[calc(100%+8px)] z-[70] w-[268px] rounded-[14px] border border-[var(--ag-border)] bg-[var(--ag-surface)] p-3 shadow-[var(--ag-sombra-alta)]"
        >
          <div className="flex items-center justify-between">
            <button
              type="button"
              onClick={() => setMes(new Date(mes.getFullYear(), mes.getMonth() - 1, 1))}
              aria-label="Mês anterior"
              className="flex h-7 w-7 items-center justify-center rounded-[7px] text-[var(--ag-text-3)] transition-colors hover:bg-[var(--ag-surface-2)]"
            >
              <ChevronLeft className="h-4 w-4" />
            </button>
            <span className="text-[13px] font-semibold capitalize text-[var(--ag-text)]">
              {mes.toLocaleDateString("pt-BR", { month: "long", year: "numeric" })}
            </span>
            <button
              type="button"
              onClick={() => setMes(new Date(mes.getFullYear(), mes.getMonth() + 1, 1))}
              aria-label="Próximo mês"
              className="flex h-7 w-7 items-center justify-center rounded-[7px] text-[var(--ag-text-3)] transition-colors hover:bg-[var(--ag-surface-2)]"
            >
              <ChevronRight className="h-4 w-4" />
            </button>
          </div>

          <div className="mt-2.5 grid grid-cols-7 gap-[2px]">
            {DIAS_CURTOS.map((d, i) => (
              <span
                key={`${d}-${i}`}
                className="flex h-7 items-center justify-center text-[10.5px] font-semibold uppercase text-[var(--ag-text-5)]"
              >
                {d}
              </span>
            ))}

            {dias.map((d) => {
              const chave = chaveDoDia(d);
              const doMes = d.getMonth() === mes.getMonth();
              const escolhido = chave === escolhidoChave;
              const ehHoje = chave === hojeChave;
              return (
                <button
                  key={chave}
                  type="button"
                  onClick={() => escolher(d)}
                  aria-current={escolhido ? "date" : undefined}
                  className={`flex h-[30px] items-center justify-center rounded-[8px] text-[12.5px] tabular-nums transition-colors ${
                    escolhido
                      ? "bg-[#6C3CF0] font-semibold text-white"
                      : ehHoje
                        ? "font-semibold text-[#6C3CF0] ring-1 ring-inset ring-[rgba(108,60,240,0.35)] hover:bg-[var(--ag-accent-soft)]"
                        : doMes
                          ? "font-medium text-[var(--ag-text-2)] hover:bg-[var(--ag-surface-2)]"
                          : "font-normal text-[var(--ag-text-5)] hover:bg-[var(--ag-surface-2)]"
                  }`}
                >
                  {d.getDate()}
                </button>
              );
            })}
          </div>

          <div className="mt-2.5 flex items-center justify-between border-t border-[var(--ag-line-h)] pt-2.5">
            <button
              type="button"
              onClick={() => escolher(new Date())}
              className="rounded-[7px] px-2 py-1 text-[11.5px] font-semibold text-[#6C3CF0] transition-colors hover:bg-[var(--ag-accent-soft)]"
            >
              Ir para hoje
            </button>
            <button
              type="button"
              onClick={() => setAberto(false)}
              className="rounded-[7px] px-2 py-1 text-[11.5px] font-medium text-[var(--ag-text-3)] transition-colors hover:bg-[var(--ag-surface-2)]"
            >
              Fechar
            </button>
          </div>
        </div>
      )}
    </div>
  );
}
