"use client";

import { useState, useSyncExternalStore } from "react";
import { Prohibit, X } from "@phosphor-icons/react";

import type { CameraComEfeitos, EstadoDosEfeitos } from "@/lib/live/cliente/efeitos/camera";
import { efeitosPossiveis, FILTROS, type Efeitos, type Filtro } from "@/lib/live/cliente/efeitos/preferencias";

/*
 * Os efeitos da câmera (como no Meet): o fundo desfocado, com a força no
 * controle deslizante, e os filtros que deixam a pele mais bonita. Abre na
 * prévia, antes de entrar, e dentro da sala, no botão de efeitos. Tudo
 * aplica na hora e fica guardado neste aparelho.
 */

const nada = () => () => undefined;

/* O estado da câmera (carregando o desfoque, aparelho sem suporte...) para a tela. */
export function useEstadoDosEfeitos(camera: CameraComEfeitos | null): EstadoDosEfeitos | null {
  return useSyncExternalStore(
    camera ? camera.assinar : nada,
    () => camera?.estado ?? null,
    () => null,
  );
}

/* A amostra de cor de cada filtro (o desenho da bolinha). */
const AMOSTRA: Record<Filtro, string> = {
  nenhum: "",
  natural: "linear-gradient(135deg, #f6c7a8, #e09a76)",
  pele: "linear-gradient(135deg, #fde3d3, #f2b99c)",
  iluminado: "radial-gradient(circle at 35% 30%, #fffbe6 0, #ffd36b 55%, #f5a524 100%)",
  quente: "linear-gradient(135deg, #ffb347, #ff6a2b)",
  rosado: "linear-gradient(135deg, #ffb6d0, #ff5d8f)",
};

export default function PainelDeEfeitos({
  efeitos,
  aoMudar,
  estado,
  aoFechar,
  variante,
}: {
  efeitos: Efeitos;
  aoMudar: (e: Efeitos) => void;
  estado: EstadoDosEfeitos | null;
  aoFechar: () => void;
  variante: "entrada" | "sala";
}) {
  const [suportado] = useState(() => efeitosPossiveis());
  const possivel = suportado && (estado?.possivel ?? true);
  const mudar = (parcial: Partial<Efeitos>) => aoMudar({ ...efeitos, ...parcial });
  const desfocado = efeitos.fundo === "desfoque";

  return (
    <div className={`lv-efeitos lv-efeitos-${variante}${variante === "sala" ? " lv-menu" : ""}`} role="dialog" aria-label="Efeitos da câmera">
      <div className="lv-efeitos-topo">
        <b>Efeitos</b>
        <button type="button" className="lv-efeitos-fechar" onClick={aoFechar} aria-label="Fechar os efeitos">
          <X />
        </button>
      </div>

      {!possivel ? (
        <p className="lv-efeitos-aviso">{estado?.aviso ?? "Este navegador não consegue aplicar efeitos na câmera. Use o Chrome ou o Edge atualizado. A câmera funciona normal."}</p>
      ) : (
        <>
          <section className="lv-efeitos-grupo">
            <h4>Fundo</h4>
            <div className="lv-efeitos-fundos">
              <button type="button" className={`lv-efeitos-fundo${desfocado ? "" : " on"}`} onClick={() => mudar({ fundo: "nenhum" })} aria-pressed={!desfocado}>
                <span className="lv-efeitos-ic">
                  <Prohibit />
                </span>
                Sem efeito
              </button>
              <button type="button" className={`lv-efeitos-fundo${desfocado ? " on" : ""}`} onClick={() => mudar({ fundo: "desfoque", desfoque: efeitos.desfoque || 60 })} aria-pressed={desfocado}>
                <span className="lv-efeitos-ic lv-efeitos-ic-desfoque" aria-hidden>
                  <i />
                </span>
                Desfocar o fundo
              </button>
            </div>
            {desfocado ? (
              <label className="lv-efeitos-faixa">
                <span>
                  Quanto desfocar <b>{Math.round(efeitos.desfoque)}%</b>
                </span>
                <input
                  type="range"
                  min={5}
                  max={100}
                  step={1}
                  value={Math.max(5, efeitos.desfoque)}
                  onChange={(e) => mudar({ desfoque: Number(e.target.value) })}
                  aria-label="Quanto desfocar o fundo"
                  style={{ "--lv-faixa": `${((Math.max(5, efeitos.desfoque) - 5) / 95) * 100}%` } as React.CSSProperties}
                />
              </label>
            ) : null}
            {desfocado && estado?.desfoque === "carregando" ? <p className="lv-efeitos-status">Preparando o desfoque…</p> : null}
            {desfocado && estado?.desfoque === "falhou" ? <p className="lv-efeitos-aviso">{estado.aviso}</p> : null}
          </section>

          <section className="lv-efeitos-grupo">
            <h4>Filtros</h4>
            <div className="lv-efeitos-filtros">
              {FILTROS.map((f) => (
                <button key={f.id} type="button" className={`lv-efeitos-filtro${efeitos.filtro === f.id ? " on" : ""}`} onClick={() => mudar({ filtro: f.id })} aria-pressed={efeitos.filtro === f.id}>
                  <span className="lv-efeitos-amostra" style={f.id === "nenhum" ? undefined : { background: AMOSTRA[f.id] }} aria-hidden>
                    {f.id === "nenhum" ? <Prohibit /> : null}
                  </span>
                  {f.nome}
                </button>
              ))}
            </div>
            {efeitos.filtro !== "nenhum" ? (
              <label className="lv-efeitos-faixa">
                <span>
                  Intensidade <b>{Math.round(efeitos.intensidade)}%</b>
                </span>
                <input
                  type="range"
                  min={0}
                  max={100}
                  step={1}
                  value={efeitos.intensidade}
                  onChange={(e) => mudar({ intensidade: Number(e.target.value) })}
                  aria-label="Intensidade do filtro"
                  style={{ "--lv-faixa": `${efeitos.intensidade}%` } as React.CSSProperties}
                />
              </label>
            ) : null}
          </section>

          <p className="lv-efeitos-nota">A sua escolha fica salva neste aparelho para as próximas vezes.</p>
        </>
      )}
    </div>
  );
}
