"use client";

import { useEffect, useState } from "react";
import { useLang } from "@/context/LanguageContext";
import {
  Alert,
  Button,
  Card,
  EmptyState,
  Input,
  PageHeader,
  LoadingArea,
  Select,
} from "@/components/ui";
import { api, useApi } from "@/lib/client";
import { fileToResizedDataUrl, formatDate } from "@/lib/utils";
import { IconCamera, IconCheck, IconKey, IconUser } from "@/components/icons";

interface Subject {
  id: number;
  name: string;
  nameBn: string;
}

interface MyStudent {
  student: {
    id: number;
    roll: string;
    name: string;
    nameBn: string | null;
    gender: string;
    dob: string | null;
    guardianName: string;
    guardianNameBn: string | null;
    guardianPhone: string;
    motherName: string | null;
    motherNameBn: string | null;
    address: string | null;
    photoUrl: string | null;
    className: string | null;
    classNameBn: string | null;
    optionalSubjects: Subject[];
  } | null;
}

interface PoolData {
  byClass: Record<number, Subject[]>;
}

interface StaffProfile {
  staff: {
    id: number;
    employeeCode: string;
    name: string;
    nameBn: string | null;
    designation: string;
    department: string | null;
    phone: string;
    email: string | null;
    address: string | null;
    joinDate: string | null;
    signatureUrl: string | null;
  } | null;
  username: string | null;
  lastLoginAt: string | null;
}

/** Member self-service profile: students/parents edit the student profile;
   teachers/staff edit their own contact info — everyone can change their
   own password. */
export default function MeProfilePage() {
  const { t } = useLang();
  const meApi = useApi<{ user: { role: string } | null }>("/api/auth/me");
  // upload policy from the central credential
  const { data: uploadPolicy } = useApi<{ imageMaxKb: number; imageMaxDim: number; docMaxKb: number }>(
    "/api/portal/upload-policy"
  );
  const isStaffView =
    meApi.data?.user?.role === "TEACHER" || meApi.data?.user?.role === "STAFF";

  if (meApi.loading) return <LoadingArea label={t.common.loading} />;
  return isStaffView ? <StaffProfileView /> : <StudentProfileView />;
}

/* ---------------- Teacher / staff profile ---------------- */

function StaffProfileView() {
  const { data: uploadPolicy } = useApi<{ imageMaxKb: number; imageMaxDim: number; docMaxKb: number }>(
    "/api/portal/upload-policy"
  );
  const { t, locale } = useLang();
  const staffApi = useApi<StaffProfile>("/api/me/staff");
  const [contact, setContact] = useState({ phone: "", email: "", address: "" });
  const [saving, setSaving] = useState(false);
  const [msg, setMsg] = useState<{ type: "success" | "error"; text: string } | null>(null);
  const s = staffApi.data?.staff ?? null;

  useEffect(() => {
    if (s) setContact({ phone: s.phone, email: s.email ?? "", address: s.address ?? "" });
  }, [s]);

  async function saveContact(e: React.FormEvent) {
    e.preventDefault();
    setSaving(true);
    setMsg(null);
    try {
      await api("/api/me/staff", {
        method: "PATCH",
        body: JSON.stringify(contact),
      });
      setMsg({ type: "success", text: t.me.profileUpdated });
      staffApi.reload();
    } catch (err) {
      const code = err instanceof Error ? err.message : "";
      setMsg({
        type: "error",
        text: code === "PHONE_REQUIRED" ? t.common.required : code === "INVALID_EMAIL" ? t.common.invalidEmail : t.common.tryAgain,
      });
    } finally {
      setSaving(false);
    }
  }

  // signature image — printed on documents the staff member signs
  const [sigBusy, setSigBusy] = useState(false);

  async function handleSignatureFile(file: File | undefined) {
    if (!file || !s) return;
    if (!/^image\/(jpeg|png|webp)$/.test(file.type) || file.size > (uploadPolicy?.imageMaxKb ?? 2048) * 1024) {
      setMsg({ type: 'error', text: t.me.signatureInvalid });
      return;
    }
    setSigBusy(true);
    setMsg(null);
    try {
      const dataUrl = await fileToResizedDataUrl(file, Math.min(uploadPolicy?.imageMaxDim ?? 400, 800));
      await api('/api/me/staff/signature', { method: 'POST', body: JSON.stringify({ signatureUrl: dataUrl }) });
      setMsg({ type: 'success', text: t.me.signatureSaved });
      staffApi.reload();
    } catch {
      setMsg({ type: 'error', text: t.common.tryAgain });
    } finally {
      setSigBusy(false);
    }
  }

  async function removeSignature() {
    setSigBusy(true);
    setMsg(null);
    try {
      await api('/api/me/staff/signature', { method: 'DELETE' });
      setMsg({ type: 'success', text: t.me.signatureRemoved });
      staffApi.reload();
    } catch {
      setMsg({ type: 'error', text: t.common.tryAgain });
    } finally {
      setSigBusy(false);
    }
  }

  return (
    <div>
      <PageHeader title={t.me.staffProfileTitle} subtitle={t.me.staffProfileSubtitle} />
      {msg && (
        <div className="mb-4">
          <Alert type={msg.type} onClose={() => setMsg(null)}>{msg.text}</Alert>
        </div>
      )}
      {staffApi.loading ? (
        <LoadingArea label={t.common.loading} />
      ) : !s ? (
        <div className="card">
          <EmptyState icon={<IconUser />} title={t.portal.myProfilePage.notLinked} />
        </div>
      ) : (
        <div className="row g-4">
          <div className="col-lg-4">
            <Card title={t.me.profile}>
              <div className="card-body">
                <dl className="mb-0 ems-fs-13">
                  <dt className="text-muted f-w-600">{t.common.name}</dt>
                  <dd className="mb-2">
                    {s.name}
                    {s.nameBn && <span className="text-muted"> ({s.nameBn})</span>}
                    <span className="ems-roll-badge ms-2">{s.employeeCode}</span>
                  </dd>
                  <dt className="text-muted f-w-600">{t.common.designation}</dt>
                  <dd className="mb-2">
                    {t.designations[s.designation as keyof typeof t.designations] ?? s.designation}
                  </dd>
                  {s.department && (
                    <>
                      <dt className="text-muted f-w-600">{t.common.department}</dt>
                      <dd className="mb-2">{s.department}</dd>
                    </>
                  )}
                  {s.joinDate && (
                    <>
                      <dt className="text-muted f-w-600">{t.me.joinedOn}</dt>
                      <dd className="mb-2">{formatDate(s.joinDate, locale)}</dd>
                    </>
                  )}
                  {staffApi.data?.username && (
                    <>
                      <dt className="text-muted f-w-600">{t.me.usernameLabel}</dt>
                      <dd className="mb-0"><code className="ems-invoice-badge">{staffApi.data.username}</code></dd>
                    </>
                  )}
                </dl>
              </div>
            </Card>
            <PasswordCard />
            <Card title={t.me.signatureTitle} icon={<IconUser className="svg-20" />} className="mt-4">
              <div className="d-flex align-items-center gap-3 flex-wrap">
                <div
                  className="d-flex align-items-center justify-content-center rounded bg-white"
                  style={{ width: 200, height: 90, border: "1px dashed #c3d4cf" }}
                >
                  {s.signatureUrl ? (
                    // eslint-disable-next-line @next/next/no-img-element
                    <img src={s.signatureUrl} alt={t.me.signatureTitle} style={{ maxHeight: 78, maxWidth: 184, objectFit: "contain" }} />
                  ) : (
                    <span className="ems-fs-12 text-muted">—</span>
                  )}
                </div>
                <div className="d-flex flex-column gap-2">
                  <label className="btn btn-sm btn-primary f-w-700 mb-0">
                    <input
                      type="file"
                      accept="image/png,image/jpeg,image/webp"
                      className="d-none"
                      value=""
                      onChange={(e) => handleSignatureFile(e.target.files?.[0])}
                    />
                    {s.signatureUrl ? t.me.signatureReplace : t.me.signatureUpload}
                  </label>
                  {s.signatureUrl && (
                    <Button size="sm" variant="secondary" onClick={removeSignature} loading={sigBusy}>
                      {t.me.signatureRemove}
                    </Button>
                  )}
                </div>
              </div>
              <p className="ems-fs-11 text-muted mt-2 mb-0">{t.me.signatureHint}</p>
            </Card>
          </div>
          <div className="col-lg-8">
            <Card title={t.me.contactInfo} icon={<IconUser className="svg-20" />}>
              <form className="theme-form" onSubmit={saveContact}>
                <div className="row">
                  <div className="col-md-6">
                    <Input
                      label={t.common.phone}
                      required
                      value={contact.phone}
                      onChange={(e) => setContact({ ...contact, phone: e.target.value })}
                    />
                  </div>
                  <div className="col-md-6">
                    <Input
                      label={t.common.email}
                      type="email"
                      value={contact.email}
                      onChange={(e) => setContact({ ...contact, email: e.target.value })}
                    />
                  </div>
                  <div className="col-md-12">
                    <Input
                      label={t.portal.myProfilePage.addressLabel}
                      value={contact.address}
                      onChange={(e) => setContact({ ...contact, address: e.target.value })}
                    />
                  </div>
                </div>
                <p className="ems-fs-12 text-muted">{t.me.contactHint}</p>
                <div className="d-flex justify-content-end">
                  <Button type="submit" loading={saving} disabled={!contact.phone.trim()}>
                    {t.common.save}
                  </Button>
                </div>
              </form>
            </Card>
          </div>
        </div>
      )}
    </div>
  );
}

/* ---------------- Password change (all member roles) ---------------- */

function PasswordCard() {
  const { t } = useLang();
  const [pwd, setPwd] = useState({ currentPassword: "", newPassword: "" });
  const [changingPwd, setChangingPwd] = useState(false);
  const [pwdMessage, setPwdMessage] = useState<{ type: "success" | "error"; text: string } | null>(null);

  async function changePassword(e: React.FormEvent) {
    e.preventDefault();
    setChangingPwd(true);
    setPwdMessage(null);
    try {
      await api("/api/me/password", {
        method: "PUT",
        body: JSON.stringify(pwd),
      });
      setPwd({ currentPassword: "", newPassword: "" });
      setPwdMessage({ type: "success", text: t.me.passwordChanged });
    } catch (err) {
      const code = err instanceof Error ? err.message : "";
      setPwdMessage({
        type: "error",
        text: code === "WRONG_PASSWORD" ? t.me.wrongPassword : code === "PASSWORD_TOO_SHORT" ? t.common.minPassword : t.common.tryAgain,
      });
    } finally {
      setChangingPwd(false);
    }
  }

  return (
    <Card className="mt-4" title={t.me.changePassword} icon={<IconKey className="svg-20" />}>
      <div className="card-body">
        {pwdMessage && (
          <div className="mb-3">
            <Alert type={pwdMessage.type} onClose={() => setPwdMessage(null)}>
              {pwdMessage.text}
            </Alert>
          </div>
        )}
        <form onSubmit={changePassword}>
          <Input
            label={t.me.currentPassword}
            type="password"
            required
            value={pwd.currentPassword}
            onChange={(e) => setPwd({ ...pwd, currentPassword: e.target.value })}
          />
          <Input
            label={t.me.newPasswordLabel}
            type="password"
            required
            value={pwd.newPassword}
            onChange={(e) => setPwd({ ...pwd, newPassword: e.target.value })}
          />
          <p className="ems-fs-12 text-muted mb-3">{t.common.minPassword}</p>
          <Button
            type="submit"
            loading={changingPwd}
            disabled={pwd.currentPassword.length === 0 || pwd.newPassword.length < 6}
          >
            <IconKey className="svg-16" />
            <span className="ms-1">{t.me.changePassword}</span>
          </Button>
        </form>
      </div>
    </Card>
  );
}

/* ---------------- Student / parent profile ---------------- */

function StudentProfileView() {
  const { data: uploadPolicy } = useApi<{ imageMaxKb: number; imageMaxDim: number; docMaxKb: number }>(
    "/api/portal/upload-policy"
  );
  const { t, locale } = useLang();
  const { data, loading, reload } = useApi<MyStudent>("/api/me/student");
  const { data: poolData } = useApi<PoolData>("/api/portal/optional-subjects");

  const [form, setForm] = useState({
    name: "", nameBn: "", gender: "MALE", dob: "", guardianName: "",
    guardianNameBn: "", guardianPhone: "", motherName: "", motherNameBn: "",
    address: "", photoUrl: "",
  });
  const [picked, setPicked] = useState<number[]>([]);
  const [saving, setSaving] = useState(false);
  const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null);

  const student = data?.student ?? null;

  useEffect(() => {
    if (!student) return;
    setForm({
      name: student.name,
      nameBn: student.nameBn ?? "",
      gender: student.gender,
      dob: student.dob ? student.dob.slice(0, 10) : "",
      guardianName: student.guardianName,
      guardianNameBn: student.guardianNameBn ?? "",
      guardianPhone: student.guardianPhone,
      motherName: student.motherName ?? "",
      motherNameBn: student.motherNameBn ?? "",
      address: student.address ?? "",
      photoUrl: student.photoUrl ?? "",
    });
    setPicked((student.optionalSubjects ?? []).map((s) => s.id));
  }, [student]);

  function onPhotoPick(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    if (!file) return;
    fileToResizedDataUrl(file, Math.min(uploadPolicy?.imageMaxDim ?? 256, 800))
      .then((dataUrl) => setForm((f) => ({ ...f, photoUrl: dataUrl })))
      .catch(() => setMessage({ type: "error", text: t.portal.studentsPage.photoInvalid }));
  }

  async function save(e: React.FormEvent) {
    e.preventDefault();
    if (!student) return;
    setSaving(true);
    setMessage(null);
    try {
      await api(`/api/portal/students/${student.id}`, {
        method: "PATCH",
        body: JSON.stringify({
          ...form,
          dob: form.dob || null,
          optionalSubjectIds: picked,
        }),
      });
      setMessage({ type: "success", text: t.portal.myProfilePage.saved });
      reload();
    } catch {
      setMessage({ type: "error", text: t.common.tryAgain });
    } finally {
      setSaving(false);
    }
  }

  // the pool that contains every picked subject (the student's class pool)
  const pool: Subject[] = (() => {
    if (!poolData?.byClass) return [];
    const pools = Object.values(poolData.byClass);
    return pools.find((p) => picked.every((id) => p.some((s) => s.id === id))) ?? pools[0] ?? [];
  })();

  return (
    <div>
      <PageHeader
        title={t.portal.myProfilePage.title}
        subtitle={t.portal.myProfilePage.subtitle}
      />

      {message && (
        <div className="mb-4">
          <Alert type={message.type} onClose={() => setMessage(null)}>{message.text}</Alert>
        </div>
      )}

      {loading ? (
        <LoadingArea label={t.common.loading} />
      ) : !student ? (
        <div className="card">
          <EmptyState icon={<IconUser />} title={t.portal.myProfilePage.notLinked} />
        </div>
      ) : (
        <form className="theme-form" onSubmit={save}>
          <div className="row g-4">
            <div className="col-lg-4">
              <Card>
                <div className="card-body d-flex flex-column align-items-center text-center gap-3">
                  <label className="col-form-label pt-0 f-w-600 align-self-start">
                    {t.portal.myProfilePage.photoLabel}
                  </label>
                  {form.photoUrl ? (
                    // eslint-disable-next-line @next/next/no-img-element
                    <img
                      src={form.photoUrl}
                      alt=""
                      style={{ width: 120, height: 140, objectFit: "cover" }}
                      className="rounded border"
                    />
                  ) : (
                    <div
                      className="rounded border d-flex align-items-center justify-content-center text-muted"
                      style={{ width: 120, height: 140 }}
                    >
                      <IconCamera className="svg-32" />
                    </div>
                  )}
                  <div className="d-flex gap-2">
                    <label className="btn btn-sm btn-outline-primary f-w-600 cursor-pointer mb-0">
                      {t.portal.studentsPage.choosePhoto}
                      <input type="file" accept="image/*" hidden onChange={onPhotoPick} />
                    </label>
                    {form.photoUrl && (
                      <button
                        type="button"
                        className="btn btn-sm btn-outline-danger f-w-600"
                        onClick={() => setForm((f) => ({ ...f, photoUrl: "" }))}
                      >
                        {t.portal.studentsPage.photoRemove}
                      </button>
                    )}
                  </div>
                  <div className="ems-fs-12 text-muted">
                    <p className="mb-1"><b>{t.portal.myProfilePage.roll}:</b> {student.roll}</p>
                    {student.className && (
                      <p className="mb-0">
                        <b>{t.portal.myProfilePage.classLabel}:</b>{" "}
                        {locale === "bn" ? student.classNameBn ?? student.className : student.className}
                      </p>
                    )}
                  </div>
                </div>
              </Card>

              <PasswordCard />
            </div>
            <div className="col-lg-8">
              <Card>
                <div className="card-body">
                  <h6 className="f-w-700 mb-3">{t.portal.myProfilePage.personalInfo}</h6>
                  <div className="row">
                    <div className="col-md-6">
                      <Input
                        label={t.common.name}
                        required
                        value={form.name}
                        onChange={(e) => setForm({ ...form, name: e.target.value })}
                      />
                    </div>
                    <div className="col-md-6">
                      <Input
                        label={t.portal.myProfilePage.nameBnLabel}
                        value={form.nameBn}
                        onChange={(e) => setForm({ ...form, nameBn: e.target.value })}
                      />
                    </div>
                    <div className="col-md-6">
                      <Select
                        label={t.portal.myProfilePage.gender}
                        value={form.gender}
                        onChange={(e) => setForm({ ...form, gender: e.target.value })}
                      >
                        <option value="MALE">{t.portal.admissionsPage.male}</option>
                        <option value="FEMALE">{t.portal.admissionsPage.female}</option>
                        <option value="OTHER">{t.portal.admissionsPage.other}</option>
                      </Select>
                    </div>
                    <div className="col-md-6">
                      <Input
                        label={t.portal.myProfilePage.dob}
                        type="date"
                        value={form.dob}
                        onChange={(e) => setForm({ ...form, dob: e.target.value })}
                      />
                    </div>
                    <div className="col-md-6">
                      <Input
                        label={t.portal.myProfilePage.guardianName}
                        required
                        value={form.guardianName}
                        onChange={(e) => setForm({ ...form, guardianName: e.target.value })}
                      />
                    </div>
                    <div className="col-md-6">
                      <Input
                        label={t.portal.admissionsPage.guardianNameBn}
                        value={form.guardianNameBn}
                        onChange={(e) => setForm({ ...form, guardianNameBn: e.target.value })}
                      />
                    </div>
                    <div className="col-md-6">
                      <Input
                        label={t.portal.myProfilePage.guardianPhone}
                        required
                        value={form.guardianPhone}
                        onChange={(e) => setForm({ ...form, guardianPhone: e.target.value })}
                      />
                    </div>
                    <div className="col-md-6">
                      <Input
                        label={t.portal.myProfilePage.motherName}
                        value={form.motherName}
                        onChange={(e) => setForm({ ...form, motherName: e.target.value })}
                      />
                    </div>
                    <div className="col-md-6">
                      <Input
                        label={t.portal.admissionsPage.motherNameBn}
                        value={form.motherNameBn}
                        onChange={(e) => setForm({ ...form, motherNameBn: e.target.value })}
                      />
                    </div>
                    <div className="col-md-6">
                      <Input
                        label={t.portal.myProfilePage.addressLabel}
                        value={form.address}
                        onChange={(e) => setForm({ ...form, address: e.target.value })}
                      />
                    </div>
                  </div>
                </div>
              </Card>
              <Card className="mt-4">
                <div className="card-body">
                  <h6 className="f-w-700 mb-1">{t.portal.myProfilePage.optionalSubjects}</h6>
                  <p className="mb-2 ems-fs-12 text-muted">
                    {t.portal.myProfilePage.optionalSubjectsHint}
                  </p>
                  <div className="d-flex flex-wrap gap-2">
                    {pool.map((sub) => {
                      const on = picked.includes(sub.id);
                      return (
                        <button
                          type="button"
                          key={sub.id}
                          className={`btn btn-sm f-w-600 ${on ? "btn-primary" : "btn-outline-secondary"}`}
                          onClick={() =>
                            setPicked((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>
                      );
                    })}
                    {pool.length === 0 && (
                      <span className="text-muted ems-fs-12">
                        {t.portal.studentsPage.optionalPoolEmpty}
                      </span>
                    )}
                  </div>
                </div>
              </Card>
              <div className="d-flex justify-content-end pt-4">
                <Button type="submit" loading={saving}>
                  {t.portal.myProfilePage.save}
                </Button>
              </div>
            </div>
          </div>
        </form>
      )}
    </div>
  );
}
