"use client";

import { useMemo, useState } from "react";
import { applicationDocuments, applications } from "../../db/schema";
import {
  ApplicationStatus,
  STATUSES,
  statusMeta,
} from "../../lib/workflow";

type Application = typeof applications.$inferSelect & {
  documents: (typeof applicationDocuments.$inferSelect)[];
};

function formatDate(value: string) {
  return new Intl.DateTimeFormat("ar-MA", {
    day: "2-digit",
    month: "short",
    year: "numeric",
  }).format(new Date(value));
}

export function Dashboard({
  initialApplications,
  adminName,
  databaseReady,
  signOutPath,
}: {
  initialApplications: Application[];
  adminName: string;
  databaseReady: boolean;
  signOutPath: string;
}) {
  const [items, setItems] = useState(initialApplications);
  const [selectedId, setSelectedId] = useState<number | null>(
    initialApplications[0]?.id ?? null,
  );
  const [query, setQuery] = useState("");
  const [filter, setFilter] = useState<"all" | ApplicationStatus>("all");
  const [saving, setSaving] = useState(false);
  const [notice, setNotice] = useState("");
  const selected = items.find((item) => item.id === selectedId) ?? null;

  const filtered = useMemo(() => {
    const normalized = query.trim().toLowerCase();
    return items.filter((item) => {
      const matchesStatus = filter === "all" || item.status === filter;
      const matchesQuery =
        !normalized ||
        [
          item.fullName,
          item.reference,
          item.phone,
          item.email,
          item.city,
          item.professionalField,
        ].some((value) => value.toLowerCase().includes(normalized));
      return matchesStatus && matchesQuery;
    });
  }, [filter, items, query]);

  const metrics = useMemo(() => {
    const active = items.filter((item) => !["new", "completed"].includes(item.status)).length;
    const completed = items.filter((item) => item.status === "completed").length;
    const scored = items.filter((item) => item.eligibilityScore > 0);
    const average = scored.length
      ? Math.round(scored.reduce((sum, item) => sum + item.eligibilityScore, 0) / scored.length)
      : 0;
    return {
      total: items.length,
      newCount: items.filter((item) => item.status === "new").length,
      active,
      completed,
      average,
    };
  }, [items]);

  async function saveApplication(form: HTMLFormElement) {
    if (!selected) return;
    setSaving(true);
    setNotice("");
    const data = new FormData(form);
    try {
      const response = await fetch(`/api/admin/applications/${selected.id}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          status: data.get("status"),
          advisor: data.get("advisor"),
          nextAction: data.get("nextAction"),
          internalNote: data.get("internalNote"),
        }),
      });
      const payload = (await response.json()) as { application?: Application; error?: string };
      if (!response.ok || !payload.application) throw new Error(payload.error || "تعذر الحفظ");
      setItems((current) =>
        current.map((item) =>
          item.id === payload.application?.id ? payload.application : item,
        ),
      );
      setNotice("تم حفظ التحديث وإظهاره للمترشح.");
    } catch (error) {
      setNotice(error instanceof Error ? error.message : "تعذر الحفظ حالياً.");
    } finally {
      setSaving(false);
    }
  }

  async function updateDocument(documentId: number, status: string) {
    if (!selected) return;
    setNotice("");
    try {
      const response = await fetch(`/api/admin/applications/${selected.id}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ document: { id: documentId, status } }),
      });
      const payload = (await response.json()) as {
        document?: typeof applicationDocuments.$inferSelect;
        error?: string;
      };
      if (!response.ok || !payload.document) throw new Error(payload.error || "تعذر تحديث الوثيقة");
      setItems((current) => current.map((item) => item.id === selected.id ? {
        ...item,
        documents: item.documents.map((document) => document.id === payload.document?.id ? payload.document : document),
      } : item));
      setNotice("تم تحديث الوثيقة في فضاء المترشح.");
    } catch (error) {
      setNotice(error instanceof Error ? error.message : "تعذر تحديث الوثيقة.");
    }
  }

  function exportCsv() {
    const headers = ["Référence", "Nom", "Téléphone", "Email", "Ville", "Domaine", "Statut", "Score", "Date"];
    const rows = filtered.map((item) => [
      item.reference,
      item.fullName,
      item.phone,
      item.email,
      item.city,
      item.professionalField,
      statusMeta[item.status as ApplicationStatus]?.label ?? item.status,
      item.eligibilityScore,
      item.createdAt,
    ]);
    const csv = [headers, ...rows]
      .map((row) => row.map((cell) => `"${String(cell).replaceAll('"', '""')}"`).join(","))
      .join("\n");
    const link = document.createElement("a");
    link.href = URL.createObjectURL(new Blob(["\uFEFF", csv], { type: "text/csv;charset=utf-8" }));
    link.download = `competences-plus-inscriptions-${new Date().toISOString().slice(0, 10)}.csv`;
    link.click();
    URL.revokeObjectURL(link.href);
  }

  return (
    <div className="admin-shell" dir="rtl">
      <aside className="admin-sidebar">
        <a href="/" className="admin-logo">
          <span>C+</span>
          <b>Compétences+</b>
        </a>
        <nav>
          <a className="active" href="/admin"><span>◫</span> التسجيلات</a>
          <a href="/candidate"><span>◎</span> معاينة فضاء المترشح</a>
          <a href="/#simulator"><span>✦</span> محاكي الأهلية</a>
          <a href="/"><span>↗</span> الموقع الرئيسي</a>
        </nav>
        <div className="admin-user">
          <span>{adminName.slice(0, 1)}</span>
          <div><b>{adminName}</b><small>مدير النظام</small></div>
        </div>
        <a className="admin-signout" href={signOutPath}>تسجيل الخروج</a>
      </aside>

      <main className="admin-main">
        <header className="admin-topbar">
          <div><small>Dashboard التسجيلات</small><h1>مركز متابعة ملفات المترشحين</h1></div>
          <div className="admin-top-actions">
            <button type="button" onClick={exportCsv}>↓ تصدير Excel / CSV</button>
            <a href="/#register">+ تسجيل جديد</a>
          </div>
        </header>

        {!databaseReady ? (
          <div className="admin-alert">قاعدة البيانات كتوجد دابا. من بعد النشر الأول غادي تولّي التسجيلات متاحة هنا تلقائياً.</div>
        ) : null}

        <section className="admin-kpis">
          <article><small>جميع الطلبات</small><strong>{metrics.total}</strong><span>ملف مسجل</span></article>
          <article className="accent"><small>طلبات جديدة</small><strong>{metrics.newCount}</strong><span>تحتاج تواصل أولي</span></article>
          <article><small>قيد المعالجة</small><strong>{metrics.active}</strong><span>مسارات نشطة</span></article>
          <article><small>متوسط المحاكي</small><strong>{metrics.average}%</strong><span>{metrics.completed} ملفات مكتملة</span></article>
        </section>

        <section className="admin-workspace">
          <div className="applications-panel">
            <div className="panel-heading"><div><h2>التسجيلات</h2><span>{filtered.length} نتيجة</span></div></div>
            <div className="dashboard-filters">
              <label><span className="sr-only">بحث</span><input value={query} onChange={(event) => setQuery(event.target.value)} placeholder="بحث بالاسم، الهاتف، المدينة أو المرجع…" /></label>
              <select value={filter} onChange={(event) => setFilter(event.target.value as "all" | ApplicationStatus)}>
                <option value="all">جميع الحالات</option>
                {STATUSES.map((status) => <option value={status} key={status}>{statusMeta[status].label}</option>)}
              </select>
            </div>
            <div className="application-list">
              {filtered.length ? filtered.map((item) => {
                const meta = statusMeta[item.status as ApplicationStatus] ?? statusMeta.new;
                return (
                  <button className={selectedId === item.id ? "selected" : ""} type="button" key={item.id} onClick={() => { setSelectedId(item.id); setNotice(""); }}>
                    <span className="application-avatar">{item.fullName.slice(0, 1)}</span>
                    <span className="application-main"><b>{item.fullName}</b><small>{item.reference} • {item.professionalField}</small></span>
                    <span className="status-chip" data-status={item.status}>{meta.short}</span>
                    <span className="application-date">{formatDate(item.createdAt)}</span>
                  </button>
                );
              }) : (
                <div className="empty-list"><span>◫</span><h3>ما كاين حتى ملف بهاد البحث</h3><p>أول تسجيل من الموقع غادي يبان هنا أوتوماتيكياً.</p></div>
              )}
            </div>
          </div>

          <aside className="application-detail">
            {selected ? (
              <form key={selected.id} onSubmit={(event) => { event.preventDefault(); void saveApplication(event.currentTarget); }}>
                <div className="detail-head">
                  <div className="application-avatar large">{selected.fullName.slice(0, 1)}</div>
                  <div><small>{selected.reference}</small><h2>{selected.fullName}</h2><p>{selected.job} • {selected.city}</p></div>
                </div>
                <div className="detail-score"><div><span style={{ width: `${selected.eligibilityScore}%` }} /></div><b>{selected.eligibilityScore || "—"}%</b><small>مؤشر الأهلية التوجيهي</small></div>
                <div className="detail-contact"><a href={`tel:${selected.phone}`}>☎ {selected.phone}</a><a href={selected.email ? `mailto:${selected.email}` : undefined}>✉ {selected.email || "البريد غير مدخل"}</a></div>
                <dl className="detail-facts">
                  <div><dt>الخبرة</dt><dd>{selected.experienceLabel}</dd></div>
                  <div><dt>المجال</dt><dd>{selected.professionalField}</dd></div>
                  <div><dt>المستوى</dt><dd>{selected.educationLabel}</dd></div>
                  <div><dt>الهدف</dt><dd>{selected.targetLabel}</dd></div>
                </dl>
                <div className="admin-documents">
                  <div><b>وثائق الملف</b><small>التغيير كيبان للمترشح مباشرة</small></div>
                  {selected.documents.map((document) => (
                    <label key={document.id}>
                      <span>{document.label}</span>
                      <select value={document.status} onChange={(event) => void updateDocument(document.id, event.target.value)}>
                        <option value="missing">مطلوبة</option>
                        <option value="received">تم التوصل</option>
                        <option value="validated">تم التحقق</option>
                      </select>
                    </label>
                  ))}
                </div>
                <label><span>حالة الملف</span><select name="status" defaultValue={selected.status}>{STATUSES.map((status) => <option value={status} key={status}>{statusMeta[status].label} — {statusMeta[status].progress}%</option>)}</select></label>
                <label><span>المستشار المسؤول</span><input name="advisor" defaultValue={selected.advisor} /></label>
                <label><span>الخطوة المقبلة الظاهرة للمترشح</span><textarea name="nextAction" rows={3} defaultValue={selected.nextAction} /></label>
                <label><span>ملاحظة داخلية (لا تظهر للمترشح)</span><textarea name="internalNote" rows={3} defaultValue={selected.internalNote} /></label>
                {notice ? <div className="save-notice" role="status">{notice}</div> : null}
                <button className="button primary detail-save" disabled={saving}>{saving ? "جاري الحفظ…" : "حفظ وتحديث فضاء المترشح"}</button>
              </form>
            ) : (
              <div className="empty-detail"><span>◎</span><h3>اختر ملفاً لعرض تفاصيله</h3><p>غادي تقدر تغيّر الحالة، المستشار والخطوة المقبلة.</p></div>
            )}
          </aside>
        </section>
      </main>
    </div>
  );
}
