"use client";

import { useEffect, useMemo, useState } from "react";
import { useLang } from "@/context/LanguageContext";
import { Alert, Button, Card, EmptyState, PageLoader } from "@/components/ui";
import { api, useApi } from "@/lib/client";
import { IconAcademic, IconCheck, IconLayers } from "@/components/icons";

/* Control Panel: Group / Department-wise subject sets.
   - GROUP basis (school & college): Science → Higher Math, Biology, Chemistry…
   - DEPARTMENT basis (university): each department carries its course list.
   Both options are available — the admin picks whichever the institution
   needs. A student's group/department then identifies their academic
   profile and pre-selects their subjects in the subject-fee assignment. */

type Basis = "GROUP" | "DEPARTMENT";

interface SetRow {
  basis: Basis;
  itemId: number;
  itemName: string;
  itemNameBn: string;
  subjectItemId: number;
  subjectName: string;
  subjectNameBn: string;
}

export default function GroupSubjectsCard() {
  const { t, locale } = useLang();
  const g = t.portal.controlPanelPage;
  const setsApi = useApi<{ sets: SetRow[] }>("/api/portal/group-subjects");
  const academic = useApi<{ items: { id: number; category: string; name: string; nameBn: string }[] }>(
    "/api/portal/academic"
  );

  const [basis, setBasis] = useState<Basis>("GROUP");
  const [itemId, setItemId] = useState("");
  const [picked, setPicked] = useState<number[]>([]);
  const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null);
  const [saving, setSaving] = useState(false);

  const items = useMemo(
    () => (academic.data?.items ?? []).filter((i) => i.category === basis),
    [academic.data, basis]
  );
  const subjects = useMemo(
    () => (academic.data?.items ?? []).filter((i) => i.category === "SUBJECT"),
    [academic.data]
  );

  const sets = setsApi.data?.sets ?? [];
  const current: Record<string, SetRow[]> = {};
  for (const row of sets) {
    const key = `${row.basis}:${row.itemId}`;
    (current[key] ??= []).push(row);
  }

  // switching basis/item loads that item's saved subjects into the picker
  useEffect(() => {
    if (!itemId) {
      setPicked([]);
      return;
    }
    setPicked((current[`${basis}:${itemId}`] ?? []).map((r) => r.subjectItemId));
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [basis, itemId, setsApi.data]);

  function toggle(id: number) {
    setPicked((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]));
  }

  async function save() {
    if (!itemId) return;
    setSaving(true);
    setMessage(null);
    try {
      await api("/api/portal/group-subjects", {
        method: "PUT",
        body: JSON.stringify({ basis, itemId: Number(itemId), subjectIds: picked }),
      });
      setMessage({ type: "success", text: g.gsSaved });
      setsApi.reload();
    } catch {
      setMessage({ type: "error", text: t.common.tryAgain });
    } finally {
      setSaving(false);
    }
  }

  const name = (en: string, bn: string) => (locale === "bn" ? bn || en : en);

  return (
    <Card>
      <div className="card-header d-flex flex-wrap align-items-center justify-content-between gap-2">
        <div>
          <h5 className="mb-0 f-w-700">{g.gsTitle}</h5>
          <p className="mb-0 ems-fs-12 text-muted">{g.gsSubtitle}</p>
        </div>
        <IconLayers className="svg-20 text-muted" />
      </div>

      {message && (
        <div className="px-3 pt-3">
          <Alert type={message.type} onClose={() => setMessage(null)}>{message.text}</Alert>
        </div>
      )}

      <div className="card-body">
        {/* basis switch — both options, admin's choice */}
        <div className="d-flex flex-wrap align-items-center gap-3 mb-3">
          <div className="btn-group">
            <button
              type="button"
              className={`btn btn-sm f-w-600 ${basis === "GROUP" ? "btn-primary" : "btn-outline-secondary"}`}
              onClick={() => { setBasis("GROUP"); setItemId(""); }}
            >
              {g.gsGroupBasis}
            </button>
            <button
              type="button"
              className={`btn btn-sm f-w-600 ${basis === "DEPARTMENT" ? "btn-primary" : "btn-outline-secondary"}`}
              onClick={() => { setBasis("DEPARTMENT"); setItemId(""); }}
            >
              {g.gsDeptBasis}
            </button>
          </div>
          <span className="ems-fs-11 text-muted">
            {basis === "GROUP" ? g.gsGroupHint : g.gsDeptHint}
          </span>
        </div>

        {/* existing sets overview */}
        {setsApi.loading ? (
          <PageLoader text={t.common.loading} />
        ) : sets.length === 0 ? (
          <EmptyState icon={<IconLayers />} title={g.gsEmpty} subtitle={g.gsEmptyHint} />
        ) : (
          <div className="d-flex flex-wrap gap-2 mb-3">
            {Object.entries(current).map(([key, rows]) => {
              const [b, id] = key.split(":");
              const active = basis === b && itemId === id;
              return (
                <button
                  key={key}
                  type="button"
                  className={`btn btn-sm f-w-600 ${active ? "btn-primary" : "btn-soft-secondary"}`}
                  onClick={() => { setBasis(b as Basis); setItemId(id); }}
                >
                  {b === "GROUP" ? <IconLayers className="svg-12 me-1" /> : <IconAcademic className="svg-12 me-1" />}
                  {name(rows[0].itemName, rows[0].itemNameBn)}
                  <span className="badge badge-light ms-1">{rows.length}</span>
                </button>
              );
            })}
          </div>
        )}

        {/* editor */}
        <div className="row g-3">
          <div className="col-lg-4">
            <label className="col-form-label pt-0 f-w-600">
              {basis === "GROUP" ? g.gsPickGroup : g.gsPickDept}
            </label>
            <div className="d-flex flex-column gap-2 pt-1">
              {items.length === 0 && (
                <span className="text-muted ems-fs-12">{g.gsNoItems}</span>
              )}
              {items.map((it) => (
                <button
                  key={it.id}
                  type="button"
                  className={`ems-module-toggle w-100${itemId === String(it.id) ? " on" : ""}`}
                  onClick={() => setItemId(String(it.id))}
                >
                  <span className="dot" />
                  <span className="lbl">{name(it.name, it.nameBn)}</span>
                  <span className={`badge ${current[`${basis}:${it.id}`]?.length ? "badge-success" : "badge-secondary"}`}>
                    {current[`${basis}:${it.id}`]?.length ?? 0}
                  </span>
                </button>
              ))}
            </div>
          </div>
          <div className="col-lg-8">
            <label className="col-form-label pt-0 f-w-600">{g.gsSubjects}</label>
            <div className="d-flex flex-wrap gap-2 pt-1">
              {subjects.map((sub) => {
                const on = picked.includes(sub.id);
                return (
                  <button
                    key={sub.id}
                    type="button"
                    className={`btn btn-sm f-w-600 ${on ? "btn-primary" : "btn-outline-secondary"}`}
                    onClick={() => toggle(sub.id)}
                  >
                    {on && <IconCheck className="svg-12 me-1" />}
                    {name(sub.name, sub.nameBn)}
                  </button>
                );
              })}
              {subjects.length === 0 && <span className="text-muted ems-fs-12">{t.common.noData}</span>}
            </div>
            <p className="ems-fs-11 text-muted mb-0 mt-2">{g.gsUsageHint}</p>
            <div className="d-flex justify-content-end pt-3">
              <Button size="sm" onClick={save} loading={saving} disabled={!itemId}>
                {t.common.save}
              </Button>
            </div>
          </div>
        </div>
      </div>
    </Card>
  );
}
