"use client";

import { useEffect, useState } from "react";
import Link from "next/link";
import { useLang } from "@/context/LanguageContext";
import { bn, en } from "@/lib/i18n";
import { Alert, Button, Card, Input, PageHeader, PageLoader } from "@/components/ui";
import { api, useApi } from "@/lib/client";
import { ACADEMIC_CATEGORIES, PORTAL_MODULES } from "@/lib/constants";
import { bdSessionLabel, classTemplateFor, templateItemName } from "@/lib/class-templates";
import { IconCheck, IconSettings } from "@/components/icons";
import NotifySettingsCard from "@/components/NotifySettingsCard";
import CollectionAccountsCard from "@/components/CollectionAccountsCard";
import GroupSubjectsCard from "@/components/GroupSubjectsCard";
import AttendanceMachinesCard from "@/components/AttendanceMachinesCard";

interface Me {
  user: { institution: { type: string } | null } | null;
}

interface ControlData {
  academicLabels: Record<string, string>;
  enabledModules: string[] | null;
  subjectFeeEnabled?: boolean;
  admissionFeeEnabled?: boolean;
  admissionFeeAmount?: number;
  trackingEnabled?: boolean;
}

interface PoolData {
  classes: { id: number; name: string; nameBn: string }[];
  subjects: { id: number; name: string; nameBn: string }[];
  byClass: Record<number, { id: number; name: string; nameBn: string }[]>;
}

const MODULE_LABEL_KEYS: Record<string, string> = {
  fees: "feesPage",
  accounts: "accountsPage",
  schedule: "schedulePage",
  lessonPlans: "lessonPlanPage",
  omr: "omrPage",
  hr: "hrPage",
  library: "libraryPage",
  hostel: "hostelPage",
  inventory: "inventoryPage",
  transport: "transportPage",
  notices: "noticesPage",
  events: "eventsPage",
  committees: "committeesPage",
  complaints: "complaintsPage",
  messages: "messagesPage",
  communication: "communicationPage",
  certificates: "certificatesPage",
  promotions: "promotionsPage",
  campus: "campusAcademicPage",
  support: "supportPage",
};

/** rename examples shown as placeholders per category */
const RENAME_EXAMPLES: Record<string, { en: string; bn: string }> = {
  CLASS: { en: "Course", bn: "কোর্স" },
  SECTION: { en: "Batch", bn: "ব্যাচ" },
  SESSION: { en: "Semester", bn: "সেমিস্টার" },
  SUBJECT: { en: "Module", bn: "মডিউল" },
  SHIFT: { en: "Time", bn: "শিফট" },
  GROUP: { en: "Track", bn: "গ্রুপ" },
  DEPARTMENT: { en: "Faculty", bn: "ফ্যাকাল্টি" },
  ROOM: { en: "Hall", bn: "হল" },
};

/** default terms from each dictionary, so the rename inputs always show
    what is being renamed regardless of the UI language */
const EN_TERMS = en.categories;
const BN_TERMS = bn.categories;

export default function ControlPanelPage() {
  const { t, rawT, locale } = useLang();
  const a = t.portal.controlPanelPage;
  const { data: me } = useApi<Me>("/api/auth/me");
  const { data, loading, reload } = useApi<ControlData>("/api/portal/control-panel");
  const { data: poolData, reload: poolReload } = useApi<PoolData>("/api/portal/optional-subjects");
  const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null);

  // optional-subject management: step 1 pick class, step 2 mark subjects
  const [optClassId, setOptClassId] = useState("");
  const [optPicked, setOptPicked] = useState<number[]>([]);
  const [optSaving, setOptSaving] = useState(false);

  function pickOptClass(classId: string) {
    setOptClassId(classId);
    setOptPicked(((poolData?.byClass ?? {})[Number(classId)] ?? []).map((s) => s.id));
  }

  async function saveOptPool(e: React.FormEvent) {
    e.preventDefault();
    if (!optClassId) return;
    setOptSaving(true);
    setMessage(null);
    try {
      await api("/api/portal/optional-subjects", {
        method: "PUT",
        body: JSON.stringify({ classItemId: Number(optClassId), subjectIds: optPicked }),
      });
      setMessage({ type: "success", text: t.portal.studentsPage.optionalPoolSaved });
      poolReload();
    } catch {
      setMessage({ type: "error", text: t.common.tryAgain });
    } finally {
      setOptSaving(false);
    }
  }

  const [subjectFee, setSubjectFee] = useState(false);
  const [savingSubjectFee, setSavingSubjectFee] = useState(false);

  // admission application fee switch + amount (saved together)
  const [admissionFee, setAdmissionFee] = useState(false);
  const [admissionFeeAmount, setAdmissionFeeAmount] = useState("");
  const [savingAdmissionFee, setSavingAdmissionFee] = useState(false);

  // public application-tracking page switch
  const [tracking, setTracking] = useState(false);
  const [savingTracking, setSavingTracking] = useState(false);

  const [labels, setLabels] = useState<Record<string, string>>({});
  const [modules, setModules] = useState<string[] | null>(null);
  const [savingModules, setSavingModules] = useState(false);
  const [savingLabels, setSavingLabels] = useState(false);
  const [applying, setApplying] = useState(false);
  const [style, setStyle] = useState<"word" | "digit">("word");

  useEffect(() => {
    const saved = window.localStorage.getItem("ems-class-style");
    if (saved === "digit" || saved === "word") setStyle(saved);
  }, []);

  function pickStyle(next: "word" | "digit") {
    setStyle(next);
    window.localStorage.setItem("ems-class-style", next);
  }

  useEffect(() => {
    if (data) {
      setLabels(data.academicLabels ?? {});
      setModules(data.enabledModules ?? null);
      setSubjectFee(!!(data as { subjectFeeEnabled?: boolean }).subjectFeeEnabled);
      setAdmissionFee(!!data.admissionFeeEnabled);
      setAdmissionFeeAmount(data.admissionFeeAmount ? String(data.admissionFeeAmount) : "");
      setTracking(!!data.trackingEnabled);
    }
  }, [data]);

  async function toggleTracking() {
    const next = !tracking;
    setTracking(next);
    setSavingTracking(true);
    setMessage(null);
    try {
      await api("/api/portal/control-panel", {
        method: "PUT",
        body: JSON.stringify({ trackingEnabled: next }),
      });
      setMessage({ type: "success", text: next ? a.tkOn : a.tkOff });
    } catch {
      setTracking(!next);
      setMessage({ type: "error", text: t.common.tryAgain });
    } finally {
      setSavingTracking(false);
    }
  }

  async function saveAdmissionFee() {
    const amount = Number(admissionFeeAmount);
    if (admissionFee && !(amount > 0)) {
      setMessage({ type: "error", text: a.afAmountInvalid });
      return;
    }
    setSavingAdmissionFee(true);
    setMessage(null);
    try {
      await api("/api/portal/control-panel", {
        method: "PUT",
        body: JSON.stringify({
          admissionFeeEnabled: admissionFee,
          admissionFeeAmount: admissionFee ? amount : 0,
        }),
      });
      setMessage({ type: "success", text: a.afSaved });
    } catch {
      setMessage({ type: "error", text: t.common.tryAgain });
    } finally {
      setSavingAdmissionFee(false);
    }
  }

  async function saveModules(next: string[]) {
    // all-on is stored as null so newly added modules light up automatically
    const normalized = next.length >= PORTAL_MODULES.length ? null : next;
    setModules(normalized);
    setSavingModules(true);
    setMessage(null);
    try {
      await api("/api/portal/control-panel", {
        method: "PUT",
        body: JSON.stringify({ enabledModules: normalized }),
      });
      setMessage({ type: "success", text: t.portal.controlPanelPage.modulesSaved });
    } catch {
      setMessage({ type: "error", text: t.common.tryAgain });
    } finally {
      setSavingModules(false);
    }
  }

  async function toggleSubjectFee() {
    const next = !subjectFee;
    setSubjectFee(next);
    setSavingSubjectFee(true);
    setMessage(null);
    try {
      await api("/api/portal/control-panel", {
        method: "PUT",
        body: JSON.stringify({ subjectFeeEnabled: next }),
      });
      setMessage({ type: "success", text: next ? t.portal.controlPanelPage.subjectFeeOn : t.portal.controlPanelPage.subjectFeeOff });
    } catch {
      setSubjectFee(!next);
      setMessage({ type: "error", text: t.common.tryAgain });
    } finally {
      setSavingSubjectFee(false);
    }
  }

  async function saveLabels(e: React.FormEvent) {
    e.preventDefault();
    setSavingLabels(true);
    setMessage(null);
    try {
      await api("/api/portal/control-panel", {
        method: "PUT",
        body: JSON.stringify({ academicLabels: labels }),
      });
      setMessage({ type: "success", text: t.portal.controlPanelPage.renameSaved });
    } catch {
      setMessage({ type: "error", text: t.common.tryAgain });
    } finally {
      setSavingLabels(false);
    }
  }

  async function applyTemplate() {
    setApplying(true);
    setMessage(null);
    try {
      const body = await api<{ applied?: unknown[] }>("/api/portal/academic/apply-template", {
        method: "POST",
        body: JSON.stringify({ style }),
      });
      setMessage({
        type: "success",
        text: `${t.portal.controlPanelPage.classesApplied} (${body.applied?.length ?? 0})`,
      });
    } catch {
      setMessage({ type: "error", text: t.common.tryAgain });
    } finally {
      setApplying(false);
    }
  }

  const session = bdSessionLabel();
  const template = me?.user?.institution ? classTemplateFor(me.user.institution.type, style) : [];

  return (
    <div>
      <PageHeader
        title={t.portal.controlPanelPage.title}
        subtitle={t.portal.controlPanelPage.subtitle}
      />

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

      {loading ? (
        <PageLoader text={t.common.loading} />
      ) : (
        <div className="row g-4">
          {/* Modules */}
          <div className="col-lg-7">
            <Card className="h-100">
              <div className="card-header d-flex align-items-center justify-content-between">
                <div>
                  <h5 className="mb-0 f-w-700">{t.portal.controlPanelPage.modulesTitle}</h5>
                  <p className="mb-0 ems-fs-12 text-muted">{t.portal.controlPanelPage.modulesSubtitle}</p>
                </div>
                <IconSettings className="svg-20 text-muted" />
              </div>
              <div className="card-body">
                <div className="d-flex align-items-center justify-content-between mb-3">
                  <span className="ems-fs-12 text-muted">{t.portal.controlPanelPage.coreNote}</span>
                  <Button
                    size="sm"
                    variant="secondary"
                    disabled={savingModules || modules === null}
                    onClick={() => saveModules([])}
                  >
                    {t.portal.controlPanelPage.modulesAllOn}
                  </Button>
                </div>
                <div className="row g-2">
                  {PORTAL_MODULES.filter((m) => m.key !== "campus" || me?.user?.institution?.type === "COLLEGE_AND_UNIVERSITY").map((m) => {
                    const on = modules === null || modules.includes(m.key);
                    const label =
                      (t.portal as unknown as Record<string, { title?: string }>)[
                        MODULE_LABEL_KEYS[m.key]
                      ]?.title ?? m.key;
                    return (
                      <div className="col-md-6" key={m.key}>
                        <button
                          type="button"
                          className={`ems-module-toggle w-100${on ? " on" : ""}`}
                          onClick={() =>
                            saveModules(
                              on
                                ? (modules ?? PORTAL_MODULES.map((x) => x.key)).filter((k) => k !== m.key)
                                : [
                                    ...(modules ??
                                      PORTAL_MODULES.filter((x) => x.key !== m.key).map((x) => x.key)),
                                    m.key,
                                  ]
                            )
                          }
                        >
                          <span className="dot" />
                          <span className="lbl">{label}</span>
                          <span className={`badge ${on ? "badge-success" : "badge-secondary"}`}>
                            {on ? t.common.active : t.common.inactive}
                          </span>
                        </button>
                      </div>
                    );
                  })}
                </div>
              </div>
            </Card>
          </div>

          {/* Optional subjects management (two steps) */}
          <div className="col-12">
            <Card>
              <div className="card-header">
                <h5 className="mb-0 f-w-700">{t.portal.controlPanelPage.optTitle}</h5>
                <p className="mb-0 ems-fs-12 text-muted">{t.portal.controlPanelPage.optSubtitle}</p>
              </div>
              <form className="card-body" onSubmit={saveOptPool}>
                <div className="row g-3">
                  <div className="col-lg-4">
                    <label className="col-form-label pt-0 f-w-600">
                      {t.portal.controlPanelPage.optStep1}
                    </label>
                    <div className="d-flex flex-column gap-2 pt-1">
                      {(poolData?.classes ?? []).map((c) => {
                        const has = ((poolData?.byClass ?? {})[c.id] ?? []).length > 0;
                        const selected = optClassId === String(c.id);
                        return (
                          <button
                            type="button"
                            key={c.id}
                            className={`ems-module-toggle w-100${selected ? " on" : ""}`}
                            onClick={() => pickOptClass(String(c.id))}
                          >
                            <span className="dot" />
                            <span className="lbl">{locale === "bn" ? c.nameBn : c.name}</span>
                            <span className={`badge ${has ? "badge-success" : "badge-secondary"}`}>
                              {has ? t.portal.controlPanelPage.optManaged : t.common.inactive}
                            </span>
                          </button>
                        );
                      })}
                      {poolData && poolData.classes.length === 0 && (
                        <span className="text-muted ems-fs-12">{t.common.noData}</span>
                      )}
                    </div>
                  </div>
                  <div className="col-lg-8">
                    <label className="col-form-label pt-0 f-w-600">
                      {t.portal.controlPanelPage.optStep2}
                    </label>
                    <div className="d-flex flex-wrap gap-2 pt-1">
                      {(poolData?.subjects ?? []).map((sub) => {
                        const on = optPicked.includes(sub.id);
                        return (
                          <button
                            type="button"
                            key={sub.id}
                            className={`btn btn-sm f-w-600 ${on ? "btn-primary" : "btn-outline-secondary"}`}
                            onClick={() =>
                              setOptPicked((prev) =>
                                on ? prev.filter((x) => x !== sub.id) : [...prev, sub.id]
                              )
                            }
                          >
                            {on && <IconCheck className="svg-12 me-1" />}
                            {locale === "bn" ? sub.nameBn : sub.name}
                          </button>
                        );
                      })}
                      {optClassId === "" ? (
                        <span className="text-muted ems-fs-12 align-self-center">
                          {t.portal.controlPanelPage.optPickClass}
                        </span>
                      ) : (poolData?.subjects ?? []).length === 0 ? (
                        <span className="text-muted ems-fs-12">{t.common.noData}</span>
                      ) : null}
                    </div>
                    <p className="mb-0 ems-fs-11 text-muted mt-2">
                      {t.portal.controlPanelPage.optStep2Hint}
                    </p>
                    <div className="d-flex justify-content-end pt-3">
                      <Button type="submit" disabled={!optClassId} loading={optSaving}>
                        {t.portal.studentsPage.optionalPoolSave}
                      </Button>
                    </div>
                  </div>
                </div>
              </form>
            </Card>
          </div>

          {/* Subject-based monthly fees feature switch */}
          <div className="col-lg-7">
            <Card className="h-100">
              <div className="card-header">
                <h5 className="mb-0 f-w-700">{t.portal.controlPanelPage.subjectFeeTitle}</h5>
                <p className="mb-0 ems-fs-12 text-muted">{t.portal.controlPanelPage.subjectFeeSubtitle}</p>
              </div>
              <div className="card-body">
                <button
                  type="button"
                  className={`ems-module-toggle w-100${subjectFee ? " on" : ""}`}
                  onClick={toggleSubjectFee}
                  disabled={savingSubjectFee}
                >
                  <span className="dot" />
                  <span className="lbl">{t.portal.controlPanelPage.subjectFeeToggle}</span>
                  <span className={`badge ${subjectFee ? "badge-success" : "badge-secondary"}`}>
                    {subjectFee ? t.common.active : t.common.inactive}
                  </span>
                </button>
                <p className="ems-fs-11 text-muted mb-0 mt-3">
                  {t.portal.controlPanelPage.subjectFeeHint}
                </p>
              </div>
            </Card>
          </div>

          {/* Renaming */}
          <div className="col-lg-5">
            <Card className="h-100">
              <div className="card-header">
                <h5 className="mb-0 f-w-700">{t.portal.controlPanelPage.renameTitle}</h5>
                <p className="mb-0 ems-fs-12 text-muted">{t.portal.controlPanelPage.renameSubtitle}</p>
              </div>
              <form className="card-body" onSubmit={saveLabels}>
                <div className="row g-3">
                  {ACADEMIC_CATEGORIES.map((cat) => (
                    <div className="col-md-6" key={cat}>
                      <Input
                        label={EN_TERMS[cat as keyof typeof EN_TERMS]}
                        value={labels[cat] ?? ""}
                        placeholder={`${t.portal.controlPanelPage.renamePlaceholder} ${RENAME_EXAMPLES[cat]?.en}`}
                        onChange={(e) => setLabels({ ...labels, [cat]: e.target.value })}
                      />
                      <Input
                        label={BN_TERMS[cat as keyof typeof BN_TERMS]}
                        value={labels[`${cat}_BN`] ?? ""}
                        placeholder={`${t.portal.controlPanelPage.renamePlaceholder} ${RENAME_EXAMPLES[cat]?.bn}`}
                        onChange={(e) => setLabels({ ...labels, [`${cat}_BN`]: e.target.value })}
                      />
                    </div>
                  ))}
                </div>
                <div className="d-flex justify-content-end pt-3">
                  <Button type="submit" loading={savingLabels}>
                    {t.common.save}
                  </Button>
                </div>
              </form>
            </Card>
          </div>

          {/* Admission application fee (admin decides whether new applications cost) */}
          <div className="col-12">
            <Card>
              <div className="card-header">
                <h5 className="mb-0 f-w-700">{a.afTitle}</h5>
                <p className="mb-0 ems-fs-12 text-muted">{a.afSubtitle}</p>
              </div>
              <form
                className="card-body"
                onSubmit={(e) => {
                  e.preventDefault();
                  saveAdmissionFee();
                }}
              >
                <div className="row g-3 align-items-center">
                  <div className="col-md-5">
                    <button
                      type="button"
                      className={`ems-module-toggle w-100${admissionFee ? " on" : ""}`}
                      onClick={() => setAdmissionFee(!admissionFee)}
                      disabled={savingAdmissionFee}
                    >
                      <span className="dot" />
                      <span className="lbl">{a.afToggle}</span>
                      <span className={`badge ${admissionFee ? "badge-success" : "badge-secondary"}`}>
                        {admissionFee ? t.common.active : t.common.inactive}
                      </span>
                    </button>
                  </div>
                  <div className="col-md-4">
                    <Input
                      label={a.afAmountLabel}
                      type="number"
                      min="0"
                      step="1"
                      value={admissionFeeAmount}
                      onChange={(e) => setAdmissionFeeAmount(e.target.value)}
                      disabled={!admissionFee}
                    />
                  </div>
                  <div className="col-md-3">
                    <Button type="submit" className="w-100" loading={savingAdmissionFee}>
                      {t.common.save}
                    </Button>
                  </div>
                </div>
                <p className="ems-fs-11 text-muted mb-0 mt-3">{a.afHint}</p>
              </form>
            </Card>
          </div>

          {/* Public application-tracking page switch */}
          <div className="col-12">
            <Card>
              <div className="card-header">
                <h5 className="mb-0 f-w-700">{a.tkTitle}</h5>
                <p className="mb-0 ems-fs-12 text-muted">{a.tkSubtitle}</p>
              </div>
              <div className="card-body">
                <button
                  type="button"
                  className={`ems-module-toggle w-100${tracking ? " on" : ""}`}
                  onClick={toggleTracking}
                  disabled={savingTracking}
                >
                  <span className="dot" />
                  <span className="lbl">{a.tkToggle}</span>
                  <span className={`badge ${tracking ? "badge-success" : "badge-secondary"}`}>
                    {tracking ? t.common.active : t.common.inactive}
                  </span>
                </button>
                <p className="ems-fs-11 text-muted mb-0 mt-3">{a.tkHint}</p>
              </div>
            </Card>
          </div>

          {/* Standard classes */}
          <div className="col-12">
            <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">{t.portal.controlPanelPage.classesTitle}</h5>
                  <p className="mb-0 ems-fs-12 text-muted">{t.portal.controlPanelPage.classesSubtitle}</p>
                </div>
                <div className="d-flex gap-2">
                  <Link href="/portal/academic" className="btn btn-sm btn-soft-secondary f-w-600">
                    {t.portal.controlPanelPage.classesManage}
                  </Link>
                  <Button size="sm" onClick={applyTemplate} loading={applying}>
                    <IconCheck className="svg-14" />
                    <span className="ms-1">{t.portal.controlPanelPage.classesApply}</span>
                  </Button>
                </div>
              </div>
              <div className="card-body">
                <div className="d-flex flex-wrap align-items-center gap-3 mb-3">
                  <span className="ems-fs-12 f-w-700 text-muted">
                    {t.portal.controlPanelPage.classStyleLabel}:
                  </span>
                  <div className="btn-group">
                    <button
                      type="button"
                      className={`btn btn-sm f-w-600 ${style === "word" ? "btn-primary" : "btn-outline-secondary"}`}
                      onClick={() => pickStyle("word")}
                    >
                      {t.portal.controlPanelPage.classStyleWord}
                    </button>
                    <button
                      type="button"
                      className={`btn btn-sm f-w-600 ${style === "digit" ? "btn-primary" : "btn-outline-secondary"}`}
                      onClick={() => pickStyle("digit")}
                    >
                      {t.portal.controlPanelPage.classStyleDigit}
                    </button>
                  </div>
                </div>
                <div className="d-flex flex-wrap gap-2">
                  {template.map((item, i) => (
                    <span className="badge badge-soft-teal" key={i}>
                      {templateItemName(item, session, locale === "bn")}
                    </span>
                  ))}
                </div>
                <p className="mb-0 ems-fs-12 text-muted mt-3">
                  {t.portal.controlPanelPage.classesHint}
                </p>
              </div>
            </Card>
          </div>

          {/* Email/SMS (OTP) delivery credentials */}
          <div className="col-12">
            <NotifySettingsCard scope="INSTITUTION" />
          </div>

          {/* where students pay — receiving accounts */}
          <div className="col-12">
            <CollectionAccountsCard />
          </div>

          {/* group / department-wise subject sets */}
          <div className="col-12">
            <GroupSubjectsCard />
          </div>

          {/* attendance machines (ZKTeco & universal) */}
          <div className="col-12">
            <AttendanceMachinesCard />
          </div>
        </div>
      )}
    </div>
  );
}
