"use client";

import { useRef, useState } from "react";
import { useLang } from "@/context/LanguageContext";
import {
  Alert,
  Button,
  EmptyState,
  Modal,
  PageHeader,
  Pagination,
  Select,
  StatCard,
  StatusBadge,
  Textarea,
  Input,
  usePagination,
} from "@/components/ui";
import { api, useApi } from "@/lib/client";
import { formatDate } from "@/lib/utils";
import { emsConfirm } from "@/components/ConfirmDialog";
import {
  IconCheckCircle,
  IconClock,
  IconDownload,
  IconEye,
  IconLifeBuoy,
  IconPaperclip,
  IconPlus,
  IconSend,
  IconX,
} from "@/components/icons";

interface Ticket {
  id: number;
  subject: string;
  message: string;
  status: string;
  createdAt: string;
  updatedAt: string;
  replyCount: number;
  attachmentCount: number;
  lastReplyBy: string | null;
  lastActivityAt: string;
}

interface TicketMessage {
  id: number;
  senderRole: string;
  senderName: string;
  message: string;
  isSolution: boolean;
  createdAt: string;
}

interface TicketAttachment {
  id: number;
  fileName: string;
  mimeType: string;
  fileSize: number;
}

interface TicketDetail extends Ticket {
  messages: TicketMessage[];
  attachments: TicketAttachment[];
}

interface PendingFile {
  fileName: string;
  mimeType: string;
  fileSize: number;
  data: string;
}

const TICKET_STATUSES = ["OPEN", "IN_PROGRESS", "RESOLVED", "CLOSED"];
const MAX_FILES = 5;
const DEFAULT_MAX_FILE_SIZE = 2 * 1024 * 1024;

function fileKB(bytes: number): string {
  return bytes >= 1024 * 1024 ? `${(bytes / (1024 * 1024)).toFixed(1)} MB` : `${Math.max(1, Math.round(bytes / 1024))} KB`;
}

const emptyForm = { subject: "", message: "" };

export default function PortalSupportPage() {
  const { t, locale } = useLang();
  const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null);
  const [busy, setBusy] = useState(false);

  const ticketsData = useApi<{ tickets: Ticket[] }>("/api/portal/support");
  // PDF / document size limit — managed in the central credential
  const policyData = useApi<{ imageMaxKb: number; imageMaxDim: number; docMaxKb: number }>(
    "/api/portal/upload-policy"
  );
  const maxFileSize = (policyData.data?.docMaxKb ?? 0) * 1024 || DEFAULT_MAX_FILE_SIZE;
  const tickets = ticketsData.data?.tickets ?? [];
  const count = (s: string) => tickets.filter((x) => x.status === s).length;

  const [filterStatus, setFilterStatus] = useState("");
  const filtered = filterStatus ? tickets.filter((x) => x.status === filterStatus) : tickets;
  const pager = usePagination(filtered, 10);

  // create modal
  const [createOpen, setCreateOpen] = useState(false);
  const [form, setForm] = useState(emptyForm);
  const [files, setFiles] = useState<PendingFile[]>([]);
  const fileRef = useRef<HTMLInputElement>(null);

  // detail modal
  const [detailOpen, setDetailOpen] = useState(false);
  const [detail, setDetail] = useState<TicketDetail | null>(null);
  const [reply, setReply] = useState("");

  function notify(type: "success" | "error", text: string) {
    setMessage({ type, text });
    window.scrollTo({ top: 0, behavior: "smooth" });
  }

  function handleFiles(list: FileList | null) {
    if (!list) return;
    const incoming = Array.from(list);
    const next = [...files];
    for (const f of incoming) {
      if (next.length >= MAX_FILES) {
        notify("error", t.portal.supportPage.tooManyFiles);
        break;
      }
      if (f.size > maxFileSize) {
        notify("error", t.portal.supportPage.fileTooLarge);
        continue;
      }
      const reader = new FileReader();
      reader.onload = () => {
        setFiles((cur) => [
          ...cur,
          { fileName: f.name, mimeType: f.type || "application/octet-stream", fileSize: f.size, data: String(reader.result) },
        ]);
      };
      reader.readAsDataURL(f);
    }
    if (fileRef.current) fileRef.current.value = "";
  }

  async function submitTicket(ev: React.FormEvent) {
    ev.preventDefault();
    setBusy(true);
    try {
      await api("/api/portal/support", {
        method: "POST",
        body: JSON.stringify({ ...form, attachments: files }),
      });
      setCreateOpen(false);
      setForm(emptyForm);
      setFiles([]);
      notify("success", t.portal.supportPage.ticketCreated);
      ticketsData.reload();
    } catch (err) {
      const code = err instanceof Error ? err.message : "";
      notify(
        "error",
        code === "FILE_TOO_LARGE"
          ? t.portal.supportPage.fileTooLarge
          : code === "TOO_MANY_FILES"
            ? t.portal.supportPage.tooManyFiles
            : t.common.tryAgain,
      );
    } finally {
      setBusy(false);
    }
  }

  async function openDetail(id: number) {
    try {
      const res = await fetch(`/api/portal/support/${id}`, { credentials: "include" });
      if (!res.ok) throw new Error();
      const data = (await res.json()) as { ticket: TicketDetail };
      setDetail(data.ticket);
      setReply("");
      setDetailOpen(true);
    } catch {
      notify("error", t.common.tryAgain);
    }
  }

  async function reloadDetail(id: number) {
    const res = await fetch(`/api/portal/support/${id}`, { credentials: "include" });
    if (res.ok) {
      const data = (await res.json()) as { ticket: TicketDetail };
      setDetail(data.ticket);
    }
    ticketsData.reload();
  }

  async function sendReply() {
    if (!detail || !reply.trim()) return;
    setBusy(true);
    try {
      await api(`/api/portal/support/${detail.id}/messages`, {
        method: "POST",
        body: JSON.stringify({ message: reply }),
      });
      setReply("");
      notify("success", t.portal.supportPage.replySent);
      await reloadDetail(detail.id);
    } catch (err) {
      const code = err instanceof Error ? err.message : "";
      notify("error", code === "TICKET_CLOSED" ? t.portal.supportPage.ticketClosedError : t.common.tryAgain);
    } finally {
      setBusy(false);
    }
  }

  async function closeTicket() {
    if (!detail) return;
    if (!(await emsConfirm({ message: t.portal.supportPage.closeConfirm, danger: false }))) return;
    try {
      await api(`/api/portal/support/${detail.id}`, { method: "PATCH" });
      notify("success", t.portal.supportPage.ticketClosed);
      setDetailOpen(false);
      ticketsData.reload();
    } catch (err) {
      const code = err instanceof Error ? err.message : "";
      notify("error", code === "TICKET_CLOSED" ? t.portal.supportPage.ticketClosedError : t.common.tryAgain);
    }
  }

  return (
    <div>
      <PageHeader
        title={t.portal.supportPage.title}
        subtitle={t.portal.supportPage.subtitle}
        action={
          <Button onClick={() => setCreateOpen(true)}>
            <IconPlus className="svg-16" />
            <span className="ms-1">{t.portal.supportPage.newTicket}</span>
          </Button>
        }
      />

      {message && (
        <div className="mb-4">
          <Alert type={message.type} onClose={() => setMessage(null)}>{message.text}</Alert>
        </div>
      )}

      {/* Status monitoring */}
      <div className="row g-3 mb-4">
        <div className="col-xl-3 col-sm-6">
          <StatCard label={t.status.OPEN} value={String(count("OPEN"))} icon={<IconLifeBuoy />} accent="orange" />
        </div>
        <div className="col-xl-3 col-sm-6">
          <StatCard label={t.status.IN_PROGRESS} value={String(count("IN_PROGRESS"))} icon={<IconClock />} accent="blue" />
        </div>
        <div className="col-xl-3 col-sm-6">
          <StatCard label={t.status.RESOLVED} value={String(count("RESOLVED"))} icon={<IconCheckCircle />} accent="teal" />
        </div>
        <div className="col-xl-3 col-sm-6">
          <StatCard label={t.status.CLOSED} value={String(count("CLOSED"))} icon={<IconCheckCircle />} accent="purple" />
        </div>
      </div>

      <div className="card">
        <div className="card-header d-flex flex-wrap align-items-center justify-content-between gap-2">
          <div style={{ maxWidth: 240 }}>
            <Select wrapperClassName="form-group mb-0" value={filterStatus} onChange={(e) => setFilterStatus(e.target.value)}>
              <option value="">{t.portal.supportPage.allStatuses}</option>
              {TICKET_STATUSES.map((s) => (
                <option key={s} value={s}>{t.status[s as keyof typeof t.status]}</option>
              ))}
            </Select>
          </div>
          <Button onClick={() => setCreateOpen(true)}>
            <IconPlus className="svg-16" />
            <span className="ms-1">{t.portal.supportPage.newTicket}</span>
          </Button>
        </div>

        {ticketsData.loading && !ticketsData.data ? (
          <div className="card-body text-center py-4">
            <span className="spinner-border text-primary" role="status" />
          </div>
        ) : filtered.length === 0 ? (
          <div className="card-body">
            <EmptyState icon={<IconLifeBuoy />} title={t.portal.supportPage.noTickets} />
          </div>
        ) : (
          <>
            <div className="table-responsive">
              <table className="table table-hover align-middle mb-0">
                <thead className="ems-table-head">
                  <tr>
                    <th>{t.portal.supportPage.subjectLabel}</th>
                    <th>{t.common.status}</th>
                    <th className="text-center">{t.portal.supportPage.replies}</th>
                    <th className="text-center">{t.portal.supportPage.attachmentsLabel}</th>
                    <th>{t.portal.supportPage.lastUpdate}</th>
                    <th className="text-end">{t.common.actions}</th>
                  </tr>
                </thead>
                <tbody>
                  {pager.paged.map((x) => (
                    <tr key={x.id}>
                      <td>
                        <p className="mb-0 f-w-700">{x.subject}</p>
                        <p className="mb-0 ems-fs-11 text-muted">
                          #{x.id} · {formatDate(x.createdAt, locale)}
                        </p>
                      </td>
                      <td>
                        <StatusBadge status={x.status} label={t.status[x.status as keyof typeof t.status]} />
                      </td>
                      <td className="text-center f-w-600">{x.replyCount}</td>
                      <td className="text-center">
                        {x.attachmentCount > 0 ? (
                          <span className="badge badge-secondary">
                            <IconPaperclip className="svg-12" /> {x.attachmentCount}
                          </span>
                        ) : (
                          "—"
                        )}
                      </td>
                      <td className="ems-fs-12 text-muted">
                        {formatDate(x.lastActivityAt, locale)}
                        <p className="mb-0 ems-fs-11">
                          {x.lastReplyBy === "SUPER_ADMIN"
                            ? t.portal.supportPage.supportTeam
                            : x.lastReplyBy === "INSTITUTION_ADMIN"
                              ? t.portal.supportPage.you
                              : ""}
                        </p>
                      </td>
                      <td className="text-end">
                        <Button size="sm" variant="secondary" title={t.portal.supportPage.conversation} onClick={() => openDetail(x.id)}>
                          <IconEye className="svg-16" />
                        </Button>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
            <Pagination {...pager} onPageChange={pager.setPage} onSizeChange={pager.setSize} />
          </>
        )}
      </div>

      {/* Create ticket modal */}
      <Modal open={createOpen} onClose={() => setCreateOpen(false)} title={t.portal.supportPage.newTicket} wide>
        <form className="theme-form" onSubmit={submitTicket}>
          <Input
            label={t.portal.supportPage.subjectLabel}
            required
            value={form.subject}
            onChange={(e) => setForm({ ...form, subject: e.target.value })}
          />
          <Textarea
            label={t.portal.supportPage.messageLabel}
            required
            rows={4}
            value={form.message}
            onChange={(e) => setForm({ ...form, message: e.target.value })}
          />
          <div className="mb-3">
            <label className="col-form-label pt-0 f-w-600">{t.portal.supportPage.attachmentsLabel}</label>
            <input ref={fileRef} type="file" multiple className="d-none" onChange={(e) => handleFiles(e.target.files)} />
            <div className="d-flex flex-wrap align-items-center gap-2">
              <Button type="button" size="sm" variant="secondary" onClick={() => fileRef.current?.click()}>
                <IconPaperclip className="svg-16" />
                <span className="ms-1">{t.portal.supportPage.addFiles}</span>
              </Button>
              <span className="ems-fs-11 text-muted">{t.portal.supportPage.attachHint}</span>
            </div>
            {files.length > 0 && (
              <div className="d-flex flex-wrap gap-2 mt-2">
                {files.map((f, i) => (
                  <span key={i} className="badge badge-secondary d-inline-flex align-items-center gap-1">
                    <IconPaperclip className="svg-12" />
                    {f.fileName} ({fileKB(f.fileSize)})
                    <button
                      type="button"
                      className="btn p-0 border-0 bg-transparent text-reset ms-1"
                      title={t.common.delete}
                      onClick={() => setFiles(files.filter((_, j) => j !== i))}
                    >
                      <IconX className="svg-12" />
                    </button>
                  </span>
                ))}
              </div>
            )}
          </div>
          <div className="d-flex justify-content-end gap-2">
            <Button type="button" variant="secondary" onClick={() => setCreateOpen(false)}>
              {t.common.cancel}
            </Button>
            <Button type="submit" loading={busy} disabled={!form.subject.trim() || !form.message.trim()}>
              {t.common.create}
            </Button>
          </div>
        </form>
      </Modal>

      {/* Ticket conversation modal */}
      <Modal
        open={detailOpen}
        onClose={() => setDetailOpen(false)}
        title={detail ? `#${detail.id} — ${detail.subject}` : ""}
        wide
      >
        {detail && (
          <div>
            <div className="d-flex flex-wrap align-items-center gap-2 mb-3">
              <StatusBadge status={detail.status} label={t.status[detail.status as keyof typeof t.status]} />
              <span className="ems-fs-12 text-muted">
                {t.portal.supportPage.reportedOn} {formatDate(detail.createdAt, locale)}
              </span>
              {detail.status !== "CLOSED" && (
                <Button size="sm" variant="secondary" className="ms-auto" onClick={closeTicket}>
                  <IconCheckCircle className="svg-16" />
                  <span className="ms-1">{t.portal.supportPage.closeTicket}</span>
                </Button>
              )}
            </div>

            <div className="ems-thread">
              {/* opening message */}
              <div className="ems-thread-item ems-thread-me">
                <p className="mb-1 ems-fs-11 text-muted f-w-600">
                  {t.portal.supportPage.you} · {formatDate(detail.createdAt, locale)}
                </p>
                <p className="mb-0" style={{ whiteSpace: "pre-wrap" }}>{detail.message}</p>
              </div>
              {detail.messages.map((m) => (
                <div key={m.id} className={`ems-thread-item ${m.senderRole === "SUPER_ADMIN" ? "ems-thread-support" : "ems-thread-me"}`}>
                  <p className="mb-1 ems-fs-11 text-muted f-w-600">
                    {m.senderRole === "SUPER_ADMIN" ? `${t.portal.supportPage.supportTeam} — ${m.senderName}` : t.portal.supportPage.you}
                    {" · "}
                    {formatDate(m.createdAt, locale)}
                    {m.isSolution && (
                      <span className="badge badge-success ms-2">{t.portal.supportPage.solution}</span>
                    )}
                  </p>
                  <p className="mb-0" style={{ whiteSpace: "pre-wrap" }}>{m.message}</p>
                </div>
              ))}
            </div>

            {detail.attachments.length > 0 && (
              <div className="mt-3">
                <p className="mb-1 f-w-600 ems-fs-13">{t.portal.supportPage.attachmentsLabel}</p>
                <div className="d-flex flex-wrap gap-2">
                  {detail.attachments.map((a) => (
                    <a
                      key={a.id}
                      href={`/api/attachment/${a.id}`}
                      target="_blank"
                      rel="noreferrer"
                      className="badge badge-secondary d-inline-flex align-items-center gap-1 text-decoration-none"
                    >
                      <IconDownload className="svg-12" />
                      {a.fileName} ({fileKB(a.fileSize)})
                    </a>
                  ))}
                </div>
              </div>
            )}

            <div className="mt-3 border-top pt-3">
              {detail.status === "CLOSED" ? (
                <p className="mb-0 ems-fs-12 text-muted">{t.portal.supportPage.ticketClosedError}</p>
              ) : (
                <>
                  {detail.status === "RESOLVED" && (
                    <p className="mb-1 ems-fs-11 text-muted">{t.portal.supportPage.reopenHint}</p>
                  )}
                  <Textarea
                    label={t.portal.supportPage.replyLabel}
                    rows={2}
                    value={reply}
                    onChange={(e) => setReply(e.target.value)}
                  />
                  <div className="d-flex justify-content-end">
                    <Button loading={busy} disabled={!reply.trim()} onClick={sendReply}>
                      <IconSend className="svg-16" />
                      <span className="ms-1">{t.portal.supportPage.sendReply}</span>
                    </Button>
                  </div>
                </>
              )}
            </div>
          </div>
        )}
      </Modal>
    </div>
  );
}
