"use client";

import { useEffect, useState } from "react";
import { useLang } from "@/context/LanguageContext";
import { Alert, Button, Modal, PageLoader } from "@/components/ui";
import { api, useApi } from "@/lib/client";
import { IconCheck } from "@/components/icons";
import {
  AUDIENCE_MEMBER_KEYS,
  MENU_CATALOG,
  emptyHidden,
  type MenuAudience,
} from "@/lib/menu-access";

/* ------------------------------------------------------------------ */
/* Subscription menu access editor — shared by the portal credentials  */
/* panel (this institution) and the central institutions page (any     */
/* institution, SUPER_ADMIN). `endpoint` serves                        */
/*   GET  → { hidden: Record<audience, string[]> }                     */
/*   PUT  ← { hidden: Record<audience, string[]> }                     */
/* ------------------------------------------------------------------ */

export function MenuAccessEditor({
  open,
  onClose,
  endpoint,
  titleSuffix,
}: {
  open: boolean;
  onClose: () => void;
  endpoint: string | null;
  /** institution name for the central variant's modal title */
  titleSuffix?: string;
}) {
  const { t } = useLang();
  const [aud, setAud] = useState<MenuAudience>("INSTITUTION");
  const [hidden, setHidden] = useState<Record<MenuAudience, string[]>>(emptyHidden());
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState(false);
  const saved = useApi<{ hidden: Record<string, string[]> }>(open ? endpoint : null);

  useEffect(() => {
    if (!saved.data) return;
    const next = emptyHidden();
    for (const key of Object.keys(next) as MenuAudience[]) {
      next[key] = Array.isArray(saved.data.hidden?.[key]) ? saved.data.hidden[key] : [];
    }
    setHidden(next);
  }, [saved.data]);

  const audiences: { id: MenuAudience; label: string }[] = [
    { id: "INSTITUTION", label: t.portal.credentials.menuAudInstitution },
    { id: "TEACHER", label: t.portal.credentials.menuAudTeacher },
    { id: "STUDENT", label: t.portal.credentials.menuAudStudent },
    { id: "PARENT", label: t.portal.credentials.menuAudParent },
    { id: "STAFF", label: t.portal.credentials.menuAudStaff },
  ];

  const items = (a: MenuAudience) =>
    a === "INSTITUTION"
      ? MENU_CATALOG.INSTITUTION
      : MENU_CATALOG[a].filter((m) => AUDIENCE_MEMBER_KEYS[a].includes(m.key));

  function toggleKey(a: MenuAudience, key: string) {
    setHidden((prev) => {
      const set = new Set(prev[a]);
      if (set.has(key)) set.delete(key);
      else set.add(key);
      return { ...prev, [a]: [...set] };
    });
  }

  function setAll(a: MenuAudience, hide: boolean) {
    setHidden((prev) => ({ ...prev, [a]: hide ? items(a).map((m) => m.key) : [] }));
  }

  async function save() {
    if (!endpoint) return;
    setSaving(true);
    setError(false);
    try {
      await api(endpoint, {
        method: "PUT",
        body: JSON.stringify({ hidden }),
      });
      saved.reload();
      onClose();
    } catch {
      setError(true);
    } finally {
      setSaving(false);
    }
  }

  return (
    <Modal
      open={open}
      onClose={onClose}
      title={
        titleSuffix
          ? `${t.portal.credentials.menuAccessTitle} — ${titleSuffix}`
          : t.portal.credentials.menuAccessTitle
      }
      wide
    >
      <p className="ems-fs-12 text-muted">{t.portal.credentials.menuAccessHint}</p>
      {saved.loading && !saved.data ? (
        <PageLoader text={t.common.loading} />
      ) : (
        <>
          <ul className="nav nav-tabs mb-3">
            {audiences.map((a) => {
              const count = hidden[a.id].length;
              return (
                <li className="nav-item" key={a.id}>
                  <button
                    type="button"
                    className={`nav-link ${aud === a.id ? "active" : ""}`}
                    onClick={() => setAud(a.id)}
                    style={{ fontSize: 13 }}
                  >
                    {a.label}
                    {count > 0 && <span className="badge badge-secondary ms-2">{count}</span>}
                  </button>
                </li>
              );
            })}
          </ul>

          <div className="d-flex justify-content-between align-items-center mb-2">
            <span className="ems-fs-12 text-muted f-w-600">
              {t.portal.credentials.menuHiddenCount.replace("{n}", String(hidden[aud].length))}
            </span>
            <div className="d-flex gap-2">
              <Button size="sm" variant="secondary" onClick={() => setAll(aud, false)}>
                {t.portal.credentials.menuSelectAll}
              </Button>
              <Button size="sm" variant="secondary" onClick={() => setAll(aud, true)}>
                {t.portal.credentials.menuClearAll}
              </Button>
            </div>
          </div>

          <div className="row g-2 mb-3" style={{ maxHeight: 330, overflowY: "auto" }}>
            {items(aud).map((m) => {
              const checked = !hidden[aud].includes(m.key);
              return (
                <div className="col-md-4 col-6" key={m.key}>
                  <label
                    className="d-flex align-items-center gap-2 ems-fs-12 p-2 rounded"
                    style={{
                      border: "1px solid #e6edef",
                      cursor: "pointer",
                      background: checked ? "#fff" : "rgba(113,113,113,0.05)",
                    }}
                  >
                    <input
                      type="checkbox"
                      className="form-check-input mt-0"
                      checked={checked}
                      onChange={() => toggleKey(aud, m.key)}
                    />
                    <span
                      className="text-truncate"
                      style={{
                        textDecoration: checked ? "none" : "line-through",
                        color: checked ? undefined : "#717171",
                      }}
                    >
                      {m.label(t as unknown as Record<string, unknown>)}
                    </span>
                  </label>
                </div>
              );
            })}
          </div>

          {error && (
            <Alert type="error">
              {t.portal.credentials.menuAccessSaveError}
            </Alert>
          )}
          <div className="d-flex justify-content-end gap-2">
            <Button variant="secondary" onClick={onClose}>
              {t.common.cancel}
            </Button>
            <Button loading={saving} onClick={save}>
              <IconCheck className="svg-16" />
              <span className="ms-1">{t.common.save}</span>
            </Button>
          </div>
        </>
      )}
    </Modal>
  );
}
