"use client";

import { useMemo, useState } from "react";
import { useLang } from "@/context/LanguageContext";
import {
  Alert,
  Button,
  Card,
  DatePicker,
  EmptyState,
  Input,
  Modal,
  PageHeader,
  PageLoader,
  Pagination,
  Select,
  StatCard,
  StatusBadge,
  usePagination,
} from "@/components/ui";
import { api, useApi } from "@/lib/client";
import { formatBDT, formatDate } from "@/lib/utils";
import { BOOK_CATEGORIES, LIBRARY_FINE_PER_DAY, LIBRARY_ISSUE_DAYS } from "@/lib/constants";
import { emsConfirm } from "@/components/ConfirmDialog";
import {
  IconAlertTriangle,
  IconBook,
  IconBook as BookIcon,
  IconCheck,
  IconEdit,
  IconPlus,
  IconTrash,
} from "@/components/icons";

interface BookRow {
  id: number;
  title: string;
  titleBn: string | null;
  author: string;
  publisher: string | null;
  isbn: string | null;
  category: string | null;
  shelf: string | null;
  totalCopies: number;
  availableCopies: number;
  price: number;
  activeIssues: number;
}

interface LibraryData {
  stats: {
    titles: number;
    totalCopies: number;
    available: number;
    issued: number;
    overdue: number;
    fines: number;
  };
  books: BookRow[];
}

interface IssueRow {
  id: number;
  bookTitle: string;
  memberType: string;
  memberName: string;
  memberRef: string;
  issueDate: string;
  dueDate: string;
  returnDate: string | null;
  fine: number;
  status: string;
  overdueDays: number;
}

interface StudentMini {
  id: number;
  roll: string;
  name: string;
}

interface StaffMini {
  id: number;
  employeeCode: string;
  name: string;
  status: string;
}

type Tab = "books" | "issue" | "history";
type IssueFilter = "ALL" | "ISSUED" | "RETURNED";

const emptyBook = {
  title: "",
  titleBn: "",
  author: "",
  publisher: "",
  isbn: "",
  category: "TEXTBOOK",
  shelf: "",
  totalCopies: "1",
  price: "0",
};

export default function PortalLibraryPage() {
  const { t, locale } = useLang();
  const [tab, setTab] = useState<Tab>("books");
  const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null);

  const { data, loading, reload } = useApi<LibraryData>("/api/portal/library");
  const { data: issuesData, loading: issuesLoading, reload: issuesReload } = useApi<{ issues: IssueRow[] }>(
    "/api/portal/library/issues"
  );
  const { data: studentsData } = useApi<{ students: StudentMini[] }>("/api/portal/students");
  const { data: hrData } = useApi<{ staff: StaffMini[] }>("/api/portal/hr");

  // Book form
  const [formOpen, setFormOpen] = useState(false);
  const [editing, setEditing] = useState<BookRow | null>(null);
  const [form, setForm] = useState(emptyBook);
  const [saving, setSaving] = useState(false);
  const [search, setSearch] = useState("");

  // Issue form
  const today = new Date().toISOString().slice(0, 10);
  const [issueForm, setIssueForm] = useState({
    bookId: "",
    memberType: "STUDENT",
    memberId: "",
    issueDate: today,
    loanDays: String(LIBRARY_ISSUE_DAYS),
  });
  const [issueSaving, setIssueSaving] = useState(false);

  // History filter
  const [filter, setFilter] = useState<IssueFilter>("ALL");
  const [bookCategory, setBookCategory] = useState("");
  const [bookAvail, setBookAvail] = useState("");
  const [issueQ, setIssueQ] = useState("");
  const [issueMemberType, setIssueMemberType] = useState("");

  const books = useMemo(() => {
    if (!data) return [];
    const q = search.trim().toLowerCase();
    return data.books.filter(
      (b) =>
        (!q || b.title.toLowerCase().includes(q) || b.author.toLowerCase().includes(q) || (b.isbn ?? "").toLowerCase().includes(q)) &&
        (!bookCategory || b.category === bookCategory) &&
        (!bookAvail || (bookAvail === "AVAILABLE" ? b.availableCopies > 0 : b.availableCopies === 0)),
    );
  }, [data, search, bookCategory, bookAvail]);

  const issues = useMemo(() => {
    if (!issuesData) return [];
    const q = issueQ.trim().toLowerCase();
    return issuesData.issues.filter(
      (i) =>
        (filter === "ALL" || (filter === "RETURNED" ? i.status === "RETURNED" : i.status !== "RETURNED")) &&
        (!q || i.bookTitle.toLowerCase().includes(q) || i.memberName.toLowerCase().includes(q) || i.memberRef.toLowerCase().includes(q)) &&
        (!issueMemberType || i.memberType === issueMemberType),
    );
  }, [issuesData, filter, issueQ, issueMemberType]);

  const booksPager = usePagination(books, 10);
  const issuesPager = usePagination(issues, 10);

  const memberOptions =
    issueForm.memberType === "STUDENT"
      ? (studentsData?.students ?? []).map((s) => ({ id: s.id, label: `${s.roll} — ${s.name}` }))
      : (hrData?.staff ?? [])
          .filter((s) => s.status === "ACTIVE")
          .map((s) => ({ id: s.id, label: `${s.employeeCode} — ${s.name}` }));

  function notify(type: "success" | "error", text: string) {
    setMessage({ type, text });
    window.scrollTo({ top: 0, behavior: "smooth" });
  }

  function openCreate() {
    setEditing(null);
    setForm(emptyBook);
    setFormOpen(true);
  }

  function openEdit(b: BookRow) {
    setEditing(b);
    setForm({
      title: b.title,
      titleBn: b.titleBn ?? "",
      author: b.author,
      publisher: b.publisher ?? "",
      isbn: b.isbn ?? "",
      category: b.category && BOOK_CATEGORIES.includes(b.category as never) ? b.category : "OTHER",
      shelf: b.shelf ?? "",
      totalCopies: String(b.totalCopies),
      price: String(b.price),
    });
    setFormOpen(true);
  }

  async function saveBook() {
    setSaving(true);
    try {
      if (editing) {
        await api(`/api/portal/library/${editing.id}`, {
          method: "PUT",
          body: JSON.stringify(form),
        });
        notify("success", t.portal.libraryPage.bookUpdated);
      } else {
        await api("/api/portal/library", { method: "POST", body: JSON.stringify(form) });
        notify("success", t.portal.libraryPage.bookCreated);
      }
      setFormOpen(false);
      reload();
    } catch (e) {
      const err = e instanceof Error ? e.message : "";
      notify("error", err === "COPIES_IN_USE" ? t.portal.libraryPage.noCopiesAvailable : t.common.tryAgain);
    } finally {
      setSaving(false);
    }
  }

  async function removeBook(b: BookRow) {
    if (!(await emsConfirm({ message: t.common.confirmDelete, danger: true }))) return;
    try {
      await api(`/api/portal/library/${b.id}`, { method: "DELETE" });
      notify("success", t.common.deletedSuccessfully);
      reload();
    } catch (e) {
      const err = e instanceof Error ? e.message : "";
      notify("error", err === "IN_USE" ? t.portal.libraryPage.bookInUse : t.common.tryAgain);
    }
  }

  async function issueBook() {
    setIssueSaving(true);
    try {
      await api("/api/portal/library/issues", {
        method: "POST",
        body: JSON.stringify({
          bookId: issueForm.bookId,
          memberType: issueForm.memberType,
          studentId: issueForm.memberType === "STUDENT" ? issueForm.memberId : null,
          staffId: issueForm.memberType === "STAFF" ? issueForm.memberId : null,
          issueDate: issueForm.issueDate,
          loanDays: issueForm.loanDays,
        }),
      });
      setIssueForm({ ...issueForm, bookId: "", memberId: "" });
      issuesReload();
      reload();
      notify("success", t.portal.libraryPage.issueCreated);
    } catch (e) {
      const err = e instanceof Error ? e.message : "";
      notify("error", err === "NO_COPIES" ? t.portal.libraryPage.noCopiesAvailable : t.common.tryAgain);
    } finally {
      setIssueSaving(false);
    }
  }

  async function returnBook(i: IssueRow) {
    if (!(await emsConfirm({ message: t.portal.libraryPage.returnConfirm, danger: false }))) return;
    try {
      const res = await api<{ fine: number }>(`/api/portal/library/issues/${i.id}`, { method: "PUT" });
      issuesReload();
      reload();
      notify(
        "success",
        `${t.status.RETURNED} — ${t.portal.libraryPage.fineLabel}: ${formatBDT(res.fine, locale)}`
      );
    } catch {
      notify("error", t.common.tryAgain);
    }
  }

  if (loading) return <PageLoader text={t.common.loading} />;
  const s = data?.stats;

  return (
    <div>
      <PageHeader
        title={t.portal.libraryPage.title}
        subtitle={t.portal.libraryPage.subtitle}
        action={
          <span className="badge badge-secondary px-3 py-2">{t.portal.libraryPage.fineRateNote}</span>
        }
      />

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

      {/* Stats */}
      <div className="row g-3 mb-4">
        <div className="col-xl-2 col-sm-4 col-6">
          <StatCard label={t.portal.libraryPage.totalTitles} value={String(s?.titles ?? 0)} icon={<IconBook />} accent="teal" />
        </div>
        <div className="col-xl-2 col-sm-4 col-6">
          <StatCard label={t.portal.libraryPage.totalCopiesLabel} value={String(s?.totalCopies ?? 0)} icon={<BookIcon />} accent="blue" />
        </div>
        <div className="col-xl-2 col-sm-4 col-6">
          <StatCard label={t.portal.libraryPage.availableNow} value={String(s?.available ?? 0)} icon={<IconCheck />} accent="sky" />
        </div>
        <div className="col-xl-2 col-sm-4 col-6">
          <StatCard label={t.portal.libraryPage.issuedNow} value={String(s?.issued ?? 0)} icon={<IconBook />} accent="purple" />
        </div>
        <div className="col-xl-2 col-sm-4 col-6">
          <StatCard label={t.portal.libraryPage.overdueNow} value={String(s?.overdue ?? 0)} icon={<IconAlertTriangle />} accent="red" />
        </div>
        <div className="col-xl-2 col-sm-4 col-6">
          <StatCard label={t.portal.libraryPage.finesCollected} value={formatBDT(s?.fines ?? 0, locale)} icon={<IconAlertTriangle />} accent="orange" />
        </div>
      </div>

      {/* Tabs */}
      <ul className="nav nav-tabs mb-4" role="tablist">
        {(["books", "issue", "history"] as Tab[]).map((key) => {
          const labels: Record<Tab, string> = {
            books: t.portal.libraryPage.tabBooks,
            issue: t.portal.libraryPage.tabIssue,
            history: t.portal.libraryPage.tabHistory,
          };
          return (
            <li className="nav-item" key={key}>
              <button
                className={`nav-link ${tab === key ? "active" : ""}`}
                onClick={() => setTab(key)}
                type="button"
              >
                {labels[key]}
              </button>
            </li>
          );
        })}
      </ul>

      {/* ---------- Books tab ---------- */}
      {tab === "books" && (
        !data || data.books.length === 0 ? (
          <div className="card">
            <EmptyState
              icon={<IconBook />}
              title={t.portal.libraryPage.noBooks}
              action={
                <Button onClick={openCreate}>
                  <IconPlus className="svg-16" />
                  <span className="ms-1">{t.portal.libraryPage.newBook}</span>
                </Button>
              }
            />
          </div>
        ) : (
          <div className="card">
            <div className="card-header d-flex flex-wrap align-items-center gap-2">
              <div className="d-flex flex-wrap align-items-center gap-2">
                <div className="has-search" style={{ maxWidth: 260 }}>
                  <span className="fa fa-search form-control-feedback" />
                  <input
                    className="form-control"
                    placeholder={t.common.search}
                    value={search}
                    onChange={(e) => setSearch(e.target.value)}
                  />
                </div>
                <div style={{ maxWidth: 170 }}>
                  <Select wrapperClassName="form-group mb-0" value={bookCategory} onChange={(e) => setBookCategory(e.target.value)}>
                    <option value="">{t.portal.libraryPage.allCategories}</option>
                    {[...new Set(data.books.map((b) => b.category).filter((c): c is string => Boolean(c)))].map((c) => (
                      <option key={c} value={c}>{t.bookCategories[c as keyof typeof t.bookCategories] ?? c}</option>
                    ))}
                  </Select>
                </div>
                <div style={{ maxWidth: 160 }}>
                  <Select wrapperClassName="form-group mb-0" value={bookAvail} onChange={(e) => setBookAvail(e.target.value)}>
                    <option value="">{t.portal.libraryPage.availAll}</option>
                    <option value="AVAILABLE">{t.portal.libraryPage.availAvailable}</option>
                    <option value="OUT">{t.portal.libraryPage.availOut}</option>
                  </Select>
                </div>
              </div>
              <Button onClick={openCreate} className="ms-auto">
                <IconPlus className="svg-16" />
                <span className="ms-1">{t.portal.libraryPage.newBook}</span>
              </Button>
            </div>
            <div className="table-responsive">
              <table className="table table-hover align-middle mb-0">
                <thead className="ems-table-head">
                  <tr>
                    <th>{t.portal.libraryPage.bookTitle}</th>
                    <th>{t.portal.libraryPage.author}</th>
                    <th>{t.common.category}</th>
                    <th>{t.portal.libraryPage.copies}</th>
                    <th>{t.common.actions}</th>
                  </tr>
                </thead>
                <tbody>
                  {booksPager.paged.map((b) => (
                    <tr key={b.id}>
                      <td>
                        <p className="mb-0 f-w-700">{b.title}</p>
                        <p className="mb-0 ems-fs-11 text-muted">
                          {b.titleBn ?? b.author}
                          {b.shelf ? ` · ${t.portal.libraryPage.shelf}: ${b.shelf}` : ""}
                        </p>
                      </td>
                      <td className="ems-fs-13">{b.author}</td>
                      <td>
                        <span className="ems-type-pill">
                          {b.category ? t.bookCategories[b.category as keyof typeof t.bookCategories] ?? b.category : "—"}
                        </span>
                      </td>
                      <td>
                        <span className={`badge ${b.availableCopies === 0 ? "badge-danger" : "badge-success"} me-1`}>
                          {b.availableCopies}/{b.totalCopies}
                        </span>
                        <span className="ems-fs-11 text-muted">{t.portal.libraryPage.availableCount}</span>
                      </td>
                      <td>
                        <button className="btn btn-soft-secondary btn-sm me-1" onClick={() => openEdit(b)} type="button">
                          <IconEdit className="svg-16" />
                        </button>
                        <button className="btn btn-soft-danger btn-sm" onClick={() => removeBook(b)} type="button">
                          <IconTrash className="svg-16" />
                        </button>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
            <Pagination {...booksPager} onPageChange={booksPager.setPage} onSizeChange={booksPager.setSize} />
          </div>
        )
      )}

      {/* ---------- Issue tab ---------- */}
      {tab === "issue" && (
        <div className="row">
          <div className="col-xl-6">
            <Card title={t.portal.libraryPage.issueBookTitle} icon={<IconBook className="svg-18" />}>
              <Select
                label={t.portal.libraryPage.selectBook}
                value={issueForm.bookId}
                onChange={(e) => setIssueForm({ ...issueForm, bookId: e.target.value })}
              >
                <option value="">— {t.common.filter} —</option>
                {(data?.books ?? []).map((b) => (
                  <option key={b.id} value={b.id} disabled={b.availableCopies < 1}>
                    {b.title} ({b.availableCopies}/{b.totalCopies})
                  </option>
                ))}
              </Select>
              <Select
                label={t.portal.libraryPage.memberType}
                value={issueForm.memberType}
                onChange={(e) => setIssueForm({ ...issueForm, memberType: e.target.value, memberId: "" })}
              >
                <option value="STUDENT">{t.memberTypes.STUDENT}</option>
                <option value="STAFF">{t.memberTypes.STAFF}</option>
              </Select>
              <Select
                label={t.portal.libraryPage.selectMember}
                value={issueForm.memberId}
                onChange={(e) => setIssueForm({ ...issueForm, memberId: e.target.value })}
              >
                <option value="">— {t.common.filter} —</option>
                {memberOptions.map((m) => (
                  <option key={m.id} value={m.id}>
                    {m.label}
                  </option>
                ))}
              </Select>
              <div className="row">
                <div className="col-md-6">
                  <DatePicker
                    label={t.portal.libraryPage.issueDate}
                    value={issueForm.issueDate}
                    onChange={(e) => setIssueForm({ ...issueForm, issueDate: e.target.value })}
                  />
                </div>
                <div className="col-md-6">
                  <Input
                    label={t.portal.libraryPage.loanDays}
                    type="number"
                    min="1"
                    max="60"
                    value={issueForm.loanDays}
                    onChange={(e) => setIssueForm({ ...issueForm, loanDays: e.target.value })}
                  />
                </div>
              </div>
              <Button
                onClick={issueBook}
                loading={issueSaving}
                disabled={!issueForm.bookId || !issueForm.memberId}
              >
                <IconBook className="svg-16" />
                <span className="ms-1">{t.portal.libraryPage.issueBookTitle}</span>
              </Button>
            </Card>
          </div>
        </div>
      )}

      {/* ---------- History tab ---------- */}
      {tab === "history" && (
        <div className="card">
          <div className="card-header d-flex flex-wrap align-items-center gap-2">
            <div className="has-search" style={{ maxWidth: 240 }}>
              <span className="fa fa-search form-control-feedback" />
              <input
                className="form-control"
                placeholder={t.common.search}
                value={issueQ}
                onChange={(e) => setIssueQ(e.target.value)}
              />
            </div>
            <div style={{ maxWidth: 160 }}>
              <Select wrapperClassName="form-group mb-0" value={issueMemberType} onChange={(e) => setIssueMemberType(e.target.value)}>
                <option value="">{t.portal.libraryPage.allMemberTypes}</option>
                <option value="STUDENT">{t.memberTypes.STUDENT}</option>
                <option value="STAFF">{t.memberTypes.STAFF}</option>
              </Select>
            </div>
            {(["ALL", "ISSUED", "RETURNED"] as IssueFilter[]).map((f) => {
              const labels: Record<IssueFilter, string> = {
                ALL: t.portal.libraryPage.allIssues,
                ISSUED: t.portal.libraryPage.activeIssues,
                RETURNED: t.portal.libraryPage.returnedIssues,
              };
              return (
                <button
                  key={f}
                  type="button"
                  className={`btn btn-sm ${filter === f ? "btn-primary" : "btn-soft-secondary"}`}
                  onClick={() => setFilter(f)}
                >
                  {labels[f]}
                </button>
              );
            })}
          </div>
          {issuesLoading ? (
            <div className="card-body text-center py-4">
              <span className="spinner-border text-primary" role="status" />
            </div>
          ) : issues.length === 0 ? (
            <EmptyState icon={<IconBook />} title={t.portal.libraryPage.noIssues} />
          ) : (
            <>
            <div className="table-responsive">
              <table className="table table-hover align-middle mb-0">
                <thead className="ems-table-head">
                  <tr>
                    <th>{t.portal.libraryPage.bookTitle}</th>
                    <th>{t.portal.libraryPage.memberType}</th>
                    <th>{t.portal.libraryPage.issueDate}</th>
                    <th>{t.portal.libraryPage.dueDateLabel}</th>
                    <th>{t.portal.libraryPage.fineLabel}</th>
                    <th>{t.common.status}</th>
                    <th className="text-end">{t.common.actions}</th>
                  </tr>
                </thead>
                <tbody>
                  {issuesPager.paged.map((i) => (
                    <tr key={i.id}>
                      <td className="f-w-600">{i.bookTitle}</td>
                      <td>
                        <p className="mb-0 ems-fs-13 f-w-600">{i.memberName}</p>
                        <p className="mb-0 ems-fs-11 text-muted">
                          {t.memberTypes[i.memberType as keyof typeof t.memberTypes]} · {i.memberRef}
                        </p>
                      </td>
                      <td className="ems-fs-13">{formatDate(i.issueDate, locale)}</td>
                      <td className="ems-fs-13">{formatDate(i.dueDate, locale)}</td>
                      <td className={i.fine > 0 || i.overdueDays > 0 ? "text-danger f-w-700" : ""}>
                        {i.status === "RETURNED"
                          ? formatBDT(i.fine, locale)
                          : i.overdueDays > 0
                            ? `~${formatBDT(i.overdueDays * LIBRARY_FINE_PER_DAY, locale)}`
                            : "—"}
                      </td>
                      <td>
                        <StatusBadge status={i.status} label={t.status[i.status as keyof typeof t.status]} />
                      </td>
                      <td className="text-end">
                        {i.status !== "RETURNED" ? (
                          <Button size="sm" variant="success" onClick={() => returnBook(i)}>
                            <IconCheck className="svg-14" />
                            <span className="ms-1">{t.portal.libraryPage.returnBook}</span>
                          </Button>
                        ) : (
                          <span className="ems-fs-12 text-muted">{formatDate(i.returnDate, locale)}</span>
                        )}
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
            <Pagination {...issuesPager} onPageChange={issuesPager.setPage} onSizeChange={issuesPager.setSize} />
            </>
          )}
        </div>
      )}

      {/* Book create/edit modal */}
      <Modal
        open={formOpen}
        onClose={() => setFormOpen(false)}
        title={editing ? t.portal.libraryPage.editBook : t.portal.libraryPage.newBook}
        wide
      >
        <div className="row">
          <div className="col-md-6">
            <Input label={t.portal.libraryPage.bookTitle} value={form.title} onChange={(e) => setForm({ ...form, title: e.target.value })} />
          </div>
          <div className="col-md-6">
            <Input label={t.portal.libraryPage.bookTitleBn} value={form.titleBn} onChange={(e) => setForm({ ...form, titleBn: e.target.value })} />
          </div>
          <div className="col-md-6">
            <Input label={t.portal.libraryPage.author} value={form.author} onChange={(e) => setForm({ ...form, author: e.target.value })} />
          </div>
          <div className="col-md-6">
            <Input label={t.portal.libraryPage.publisher} value={form.publisher} onChange={(e) => setForm({ ...form, publisher: e.target.value })} />
          </div>
          <div className="col-md-6">
            <Input label={t.portal.libraryPage.isbn} value={form.isbn} onChange={(e) => setForm({ ...form, isbn: e.target.value })} />
          </div>
          <div className="col-md-6">
            <Select label={t.common.category} value={form.category} onChange={(e) => setForm({ ...form, category: e.target.value })}>
              {BOOK_CATEGORIES.map((c) => (
                <option key={c} value={c}>
                  {t.bookCategories[c]}
                </option>
              ))}
            </Select>
          </div>
          <div className="col-md-4">
            <Input label={t.portal.libraryPage.shelf} value={form.shelf} onChange={(e) => setForm({ ...form, shelf: e.target.value })} placeholder="A-1" />
          </div>
          <div className="col-md-4">
            <Input label={t.portal.libraryPage.copies} type="number" min="1" value={form.totalCopies} onChange={(e) => setForm({ ...form, totalCopies: e.target.value })} />
          </div>
          <div className="col-md-4">
            <Input label={t.portal.libraryPage.price} type="number" min="0" value={form.price} onChange={(e) => setForm({ ...form, price: e.target.value })} />
          </div>
        </div>
        <div className="d-flex justify-content-end gap-2">
          <Button variant="secondary" onClick={() => setFormOpen(false)}>
            {t.common.cancel}
          </Button>
          <Button onClick={saveBook} loading={saving} disabled={!form.title.trim() || !form.author.trim()}>
            {t.common.save}
          </Button>
        </div>
      </Modal>
    </div>
  );
}
