"use client";

import { useRolagemHorizontal } from "./gestos";
import { DicaEvento, useDica } from "./dica";
import { chaveDoDia, somaDias, type EventoAgenda } from "./tipos";

/**
 * O mes inteiro como grade de ocupacao: dias descendo na vertical, horas
 * atravessando na horizontal.
 *
 * O calendario comum responde "o que tem no dia 12". Esta grade responde
 * outra coisa: onde o mes esta cheio e onde esta vazio, de uma olhada. E a
 * visao de quem precisa encaixar um servico e quer achar o buraco.
 *
 * Prazo sem hora marcada — vencimento de conta, entrega de pedido — cai numa
 * coluna propria a esquerda. Espalhar essas coisas pelas horas seria inventar
 * um horario que ninguem definiu.
 */

const HORA_INICIO = 7;
const HORA_FIM = 20;

function horaDe(evento: EventoAgenda): number | null {
  const achado = String(evento.subtitulo || "").match(/^(\d{2}):(\d{2})/);
  if (!achado) return null;
  const h = Number(achado[1]);
  return h >= HORA_INICIO && h <= HORA_FIM ? h : null;
}

export default function GradeDoMes({
  ancora,
  porDia,
  hojeChave,
  aoAbrir,
  aoArrastar,
  aoCriar,
  diaAlvo,
  horaAlvo,
  arrastandoId,
}: {
  ancora: Date;
  porDia: Map<string, EventoAgenda[]>;
  hojeChave: string;
  aoAbrir: (evento: EventoAgenda) => void;
  aoArrastar: (e: React.PointerEvent, evento: EventoAgenda) => void;
  aoCriar?: (dia: string, hora: number | null) => void;
  diaAlvo: string | null;
  horaAlvo: number | null;
  arrastandoId?: string | null;
}) {
  const primeiro = new Date(ancora.getFullYear(), ancora.getMonth(), 1);
  const totalDias = new Date(ancora.getFullYear(), ancora.getMonth() + 1, 0).getDate();
  const dias = Array.from({ length: totalDias }, (_, i) => somaDias(primeiro, i));
  const horas = Array.from({ length: HORA_FIM - HORA_INICIO + 1 }, (_, i) => HORA_INICIO + i);

  const { ref: scrollRef, temMaisPraDireita, podeRolar } = useRolagemHorizontal<HTMLDivElement>(dias.length);
  const { dicaProps, camada, fecharDica } = useDica();

  return (
    <div className="relative overflow-hidden rounded-[14px] border border-[var(--ag-border)] bg-[var(--ag-surface)] shadow-[var(--ag-sombra-1)]">
      <div
        ref={scrollRef}
        className={`overflow-x-auto [&::-webkit-scrollbar]:h-[6px] [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-[var(--ag-border-strong)] [&::-webkit-scrollbar-track]:bg-transparent ${
          podeRolar ? "cursor-[ew-resize]" : ""
        }`}
      >
        <div className="min-w-[900px]">
          {/* Cabecalho das horas */}
          <div className="sticky top-0 z-10 flex border-b border-[var(--ag-line-v)] bg-[var(--ag-surface)]">
            <span className="w-[92px] shrink-0 px-3 py-2 text-[10px] font-semibold uppercase tracking-[0.03em] text-[var(--ag-text-4)]">
              Dia
            </span>
            <span className="w-[86px] shrink-0 border-l border-[var(--ag-line-v)] px-2 py-2 text-[10px] font-semibold uppercase tracking-[0.03em] text-[var(--ag-text-4)]">
              Sem hora
            </span>
            {horas.map((h) => (
              <span
                key={h}
                className="flex-1 border-l border-[var(--ag-line-v)] px-1 py-2 text-center text-[10px] font-medium tabular-nums text-[var(--ag-text-4)]"
              >
                {String(h).padStart(2, "0")}
              </span>
            ))}
          </div>

          {dias.map((dia) => {
            const chave = chaveDoDia(dia);
            const doDia = porDia.get(chave) ?? [];
            const ehHoje = chave === hojeChave;
            const fimDeSemana = [0, 6].includes(dia.getDay());
            const semHora = doDia.filter((e) => horaDe(e) === null);

            return (
              <div
                key={chave}
                className="flex border-b border-[var(--ag-line-h)] last:border-0"
                style={{ background: ehHoje ? "rgba(108,60,240,0.045)" : fimDeSemana ? "var(--ag-surface-2)" : undefined }}
              >
                <span className="flex w-[92px] shrink-0 items-center gap-1.5 px-3 py-1.5">
                  <span
                    className="text-[13px] tabular-nums"
                    style={{ color: ehHoje ? "#6C3CF0" : "var(--ag-text)", fontWeight: ehHoje ? 700 : 650 }}
                  >
                    {String(dia.getDate()).padStart(2, "0")}
                  </span>
                  <span className="text-[10px] font-semibold uppercase text-[var(--ag-text-4)]">
                    {dia.toLocaleDateString("pt-BR", { weekday: "short" }).replace(".", "")}
                  </span>
                </span>

                {/* Coluna dos prazos sem hora */}
                <span
                  data-dia={chave}
                  onClick={
                    aoCriar
                      ? (ev) => {
                          if ((ev.target as HTMLElement).closest("button")) return;
                          aoCriar(chave, null);
                        }
                      : undefined
                  }
                  className={`flex w-[86px] shrink-0 flex-wrap content-start gap-0.5 border-l border-[var(--ag-line-h)] p-1 ${
                    aoCriar ? "cursor-pointer hover:bg-[rgba(108,60,240,0.045)]" : ""
                  } ${
                    diaAlvo === chave && horaAlvo === null ? "bg-[rgba(108,60,240,0.08)] ring-1 ring-inset ring-[#6C3CF0]" : ""
                  }`}
                >
                  {semHora.map((e) => (
                    <button
                      key={`${e.tipo}-${e.origem_id}`}
                      type="button"
                      onClick={() => aoAbrir(e)}
                      {...dicaProps(<DicaEvento evento={e} />)}
                      onPointerDown={(ev) => {
                        fecharDica();
                        aoArrastar(ev, e);
                      }}
                      className={`h-4 w-4 rounded-md transition-transform hover:scale-125 ${
                        arrastandoId === e.origem_id ? "opacity-40" : ""
                      }`}
                      style={{ background: e.categoria_cor }}
                    />
                  ))}
                </span>

                {horas.map((h) => {
                  const naHora = doDia.filter((e) => horaDe(e) === h);
                  const alvo = diaAlvo === chave && horaAlvo === h;
                  return (
                    <span
                      key={h}
                      data-dia={chave}
                      data-hora={h}
                      onClick={
                        aoCriar
                          ? (ev) => {
                              if ((ev.target as HTMLElement).closest("button")) return;
                              aoCriar(chave, h);
                            }
                          : undefined
                      }
                      role={aoCriar ? "button" : undefined}
                      aria-label={
                        aoCriar
                          ? `Criar compromisso dia ${dia.getDate()} às ${String(h).padStart(2, "0")}:00`
                          : undefined
                      }
                      className={`flex min-h-[34px] flex-1 flex-col justify-center gap-0.5 border-l border-[var(--ag-line-h)] p-0.5 ${
                        aoCriar ? "cursor-pointer hover:bg-[rgba(108,60,240,0.06)]" : ""
                      } ${alvo ? "bg-[rgba(108,60,240,0.08)] ring-1 ring-inset ring-[#6C3CF0]" : ""}`}
                    >
                      {naHora.map((e) => (
                        <button
                          key={`${e.tipo}-${e.origem_id}`}
                          type="button"
                          onClick={() => aoAbrir(e)}
                          {...dicaProps(<DicaEvento evento={e} />)}
                          onPointerDown={(ev) => {
                            fecharDica();
                            aoArrastar(ev, e);
                          }}
                          className={`h-4 w-full touch-none rounded-md transition-transform hover:scale-y-150 ${
                            arrastandoId === e.origem_id ? "opacity-40" : ""
                          }`}
                          style={{ background: e.categoria_cor }}
                        />
                      ))}
                    </span>
                  );
                })}
              </div>
            );
          })}
        </div>
      </div>

      {temMaisPraDireita && (
        <div
          aria-hidden
          className="pointer-events-none absolute bottom-0 right-0 top-0 z-20 w-10 bg-gradient-to-l from-[var(--ag-surface)] to-transparent"
        />
      )}

      {camada}
    </div>
  );
}
