"use client";

import { useEffect, useMemo, useState, type FormEvent } from "react";

type CurrencyCode = "ZAR" | "USD" | "EUR" | "GBP";
type PricingItem = { carat: number; prices: Record<CurrencyCode, number> };
type OrderStatus = "new" | "confirmed" | "in_production" | "completed" | "cancelled";
type AdminOrder = {
  id: string;
  reference: string;
  createdAt: string;
  customerName: string;
  weddingDate: string;
  email: string;
  phone: string;
  deliveryAddress: string;
  deliveryRecipient: string;
  notes: string;
  guestCount: number;
  carat: number;
  currency: CurrencyCode;
  pricePerGuest: number;
  total: number;
  status: OrderStatus;
  design: { partnerOne: string; partnerTwo: string; heading: string } | null;
  uploadedDesign: { id: string; fileName: string } | null;
};
type SavedDesign = {
  id: string;
  email: string;
  createdAt: string;
  design: { partnerOne: string; partnerTwo: string; weddingDate: string; heading: string; palette: string };
};
type AdminData = { pricing: PricingItem[]; orders: AdminOrder[]; designs: SavedDesign[] };
type AdminTab = "overview" | "orders" | "designs" | "products";
type OrderEditorDraft = Pick<AdminOrder, "customerName" | "weddingDate" | "email" | "phone" | "deliveryAddress" | "deliveryRecipient" | "notes" | "guestCount" | "carat" | "currency" | "status">;

const currencyCodes: CurrencyCode[] = ["ZAR", "USD", "EUR", "GBP"];
const currencySymbols: Record<CurrencyCode, string> = { ZAR: "R", USD: "$", EUR: "€", GBP: "£" };

function formatMoney(amount: number, currency: CurrencyCode) {
  return new Intl.NumberFormat(currency === "ZAR" ? "en-ZA" : currency === "EUR" ? "en-IE" : currency === "GBP" ? "en-GB" : "en-US", {
    style: "currency",
    currency,
    maximumFractionDigits: 0,
  }).format(amount);
}
const statusLabels: Record<OrderStatus, string> = {
  new: "New",
  confirmed: "Confirmed",
  in_production: "In production",
  completed: "Completed",
  cancelled: "Cancelled",
};

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

function formatWeddingDate(value: string) {
  return new Intl.DateTimeFormat("en-ZA", { day: "2-digit", month: "short", year: "numeric" }).format(new Date(`${value}T12:00:00`));
}

export default function AdminPage() {
  const [authenticated, setAuthenticated] = useState<boolean | null>(null);
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [loginError, setLoginError] = useState("");
  const [loginBusy, setLoginBusy] = useState(false);
  const [data, setData] = useState<AdminData>({ pricing: [], orders: [], designs: [] });
  const [pricingDraft, setPricingDraft] = useState<PricingItem[]>([]);
  const [tab, setTab] = useState<AdminTab>("overview");
  const [notice, setNotice] = useState("");
  const [activeOrderId, setActiveOrderId] = useState<string | null>(null);
  const [orderDialogMode, setOrderDialogMode] = useState<"view" | "edit">("view");
  const [orderDraft, setOrderDraft] = useState<OrderEditorDraft | null>(null);
  const [orderSaving, setOrderSaving] = useState(false);
  const [orderDeleting, setOrderDeleting] = useState(false);

  useEffect(() => {
    fetch("/api/admin/session")
      .then((response) => response.json())
      .then((result: { authenticated?: boolean }) => {
        const isAuthenticated = Boolean(result.authenticated);
        setAuthenticated(isAuthenticated);
        if (isAuthenticated) loadData();
      })
      .catch(() => setAuthenticated(false));
  }, []);

  async function loadData() {
    const response = await fetch("/api/admin/data");
    if (response.status === 401) {
      setAuthenticated(false);
      return;
    }
    const result = await response.json() as AdminData & { error?: string };
    if (!response.ok) throw new Error(result.error || "Unable to load dashboard data.");
    setData(result);
    setPricingDraft(result.pricing);
  }

  async function signIn(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setLoginBusy(true);
    setLoginError("");
    try {
      const response = await fetch("/api/admin/session", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email, password }),
      });
      const result = await response.json() as { authenticated?: boolean; error?: string };
      if (!response.ok || !result.authenticated) throw new Error(result.error || "Unable to sign in.");
      setAuthenticated(true);
      setPassword("");
      await loadData();
    } catch (error) {
      setLoginError(error instanceof Error ? error.message : "Unable to sign in.");
    } finally {
      setLoginBusy(false);
    }
  }

  async function signOut() {
    await fetch("/api/admin/session", { method: "DELETE" });
    setAuthenticated(false);
    setData({ pricing: [], orders: [], designs: [] });
  }

  async function savePricing() {
    setNotice("Saving prices…");
    try {
      const response = await fetch("/api/admin/data", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ action: "pricing", pricing: pricingDraft }),
      });
      const result = await response.json() as { pricing?: PricingItem[]; error?: string };
      if (!response.ok || !result.pricing) throw new Error(result.error || "Unable to save prices.");
      setData((current) => ({ ...current, pricing: result.pricing! }));
      setPricingDraft(result.pricing);
      setNotice("Prices saved. The order page is updated.");
    } catch (error) {
      setNotice(error instanceof Error ? error.message : "Unable to save prices.");
    }
  }

  async function changeOrderStatus(orderId: string, status: OrderStatus) {
    setData((current) => ({ ...current, orders: current.orders.map((order) => order.id === orderId ? { ...order, status } : order) }));
    const response = await fetch("/api/admin/data", {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ action: "order-status", orderId, status }),
    });
    if (!response.ok) {
      setNotice("The status could not be saved. Refreshing orders…");
      await loadData();
    } else {
      setNotice("Order status updated.");
    }
  }

  function openOrderDialog(order: AdminOrder, mode: "view" | "edit") {
    setActiveOrderId(order.id);
    setOrderDialogMode(mode);
    setOrderDraft({
      customerName: order.customerName,
      weddingDate: order.weddingDate,
      email: order.email,
      phone: order.phone,
      deliveryAddress: order.deliveryAddress,
      deliveryRecipient: order.deliveryRecipient,
      notes: order.notes,
      guestCount: order.guestCount,
      carat: order.carat,
      currency: order.currency,
      status: order.status,
    });
  }

  function closeOrderDialog() {
    setActiveOrderId(null);
    setOrderDraft(null);
    setOrderSaving(false);
    setOrderDeleting(false);
  }

  async function saveOrderDraft() {
    if (!activeOrderId || !orderDraft) return;
    setOrderSaving(true);
    try {
      const response = await fetch("/api/admin/data", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ action: "order-update", orderId: activeOrderId, updates: orderDraft }),
      });
      const result = await response.json() as { order?: AdminOrder; error?: string };
      if (!response.ok || !result.order) throw new Error(result.error || "Unable to save order changes.");
      setData((current) => ({ ...current, orders: current.orders.map((order) => order.id === activeOrderId ? result.order! : order) }));
      setNotice(`Order ${result.order.reference} updated.`);
      closeOrderDialog();
    } catch (error) {
      setNotice(error instanceof Error ? error.message : "Unable to save order changes.");
      setOrderSaving(false);
    }
  }

  async function deleteOrder(order: AdminOrder) {
    if (!window.confirm(`Delete ${order.reference}? This cannot be undone.`)) return;
    setOrderDeleting(true);
    try {
      const response = await fetch("/api/admin/data", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ action: "order-delete", orderId: order.id }),
      });
      const result = await response.json() as { deleted?: boolean; error?: string };
      if (!response.ok || !result.deleted) throw new Error(result.error || "Unable to delete order.");
      setData((current) => ({ ...current, orders: current.orders.filter((item) => item.id !== order.id) }));
      setNotice(`Order ${order.reference} deleted.`);
      closeOrderDialog();
    } catch (error) {
      setNotice(error instanceof Error ? error.message : "Unable to delete order.");
      setOrderDeleting(false);
    }
  }

  const metrics = useMemo(() => {
    const revenueByCurrency = { ZAR: 0, USD: 0, EUR: 0, GBP: 0 } as Record<CurrencyCode, number>;
    data.orders.filter((order) => order.status !== "cancelled").forEach((order) => {
      revenueByCurrency[order.currency || "ZAR"] += order.total;
    });
    return {
      totalOrders: data.orders.length,
      newOrders: data.orders.filter((order) => order.status === "new").length,
      savedDesigns: data.designs.length,
      revenueByCurrency,
    };
  }, [data]);

  const activeOrder = useMemo(
    () => (activeOrderId ? data.orders.find((order) => order.id === activeOrderId) || null : null),
    [activeOrderId, data.orders],
  );

  if (authenticated === null) {
    return <main className="admin-loading"><span>◇</span><p>Opening studio…</p></main>;
  }

  if (!authenticated) {
    return (
      <main className="admin-login-page">
        <section className="admin-login-brand">
          <a className="brand brand-light" href="/"><img className="brand-mark" src="/logo.svg" width="24" height="38" alt="" aria-hidden="true" /><span>Gem Vial</span></a>
          <div><p>Private studio</p><h1>Everything precious,<br /><em>beautifully managed.</em></h1></div>
          <span>Orders · Card designs · Product pricing</span>
        </section>
        <section className="admin-login-panel">
          <form onSubmit={signIn}>
            <p className="eyebrow"><span /> Owner access</p>
            <h2>Welcome back.</h2>
            <p>Sign in to manage Gem Vial orders and products.</p>
            <label><span>Email address</span><input type="email" value={email} onChange={(event) => setEmail(event.target.value)} autoComplete="username" required autoFocus /></label>
            <label><span>Password</span><input type="password" value={password} onChange={(event) => setPassword(event.target.value)} autoComplete="current-password" required /></label>
            {loginError && <div className="admin-login-error">{loginError}</div>}
            <button className="button button-dark" type="submit" disabled={loginBusy}>{loginBusy ? "Signing in…" : "Enter the studio"}</button>
            <a href="/">← Return to website</a>
          </form>
        </section>
      </main>
    );
  }

  return (
    <main className="admin-page">
      <aside className="admin-sidebar">
        <a className="brand brand-light" href="/"><img className="brand-mark" src="/logo.svg" width="24" height="38" alt="" aria-hidden="true" /><span>Gem Vial</span></a>
        <div className="admin-owner"><span>Owner studio</span><strong>Michael</strong></div>
        <nav className="admin-nav" aria-label="Admin navigation">
          <button className={tab === "overview" ? "active" : ""} onClick={() => setTab("overview")}><span>01</span>Overview</button>
          <button className={tab === "orders" ? "active" : ""} onClick={() => setTab("orders")}><span>02</span>Orders <i>{metrics.newOrders || ""}</i></button>
          <button className={tab === "designs" ? "active" : ""} onClick={() => setTab("designs")}><span>03</span>Saved cards</button>
          <button className={tab === "products" ? "active" : ""} onClick={() => setTab("products")}><span>04</span>Products & prices</button>
        </nav>
        <div className="admin-sidebar-footer"><a href="/" target="_blank">View website ↗</a><button onClick={signOut}>Sign out</button></div>
      </aside>

      <section className="admin-content">
        <header className="admin-topbar">
          <div><span>Gem Vial /</span><strong>{tab === "designs" ? "Saved cards" : tab === "products" ? "Products & prices" : `${tab.charAt(0).toUpperCase()}${tab.slice(1)}`}</strong></div>
          <div>{new Intl.DateTimeFormat("en-ZA", { weekday: "long", day: "2-digit", month: "long" }).format(new Date())}</div>
        </header>
        {notice && <div className="admin-notice" role="status"><span>◇</span>{notice}<button onClick={() => setNotice("")}>×</button></div>}

        {tab === "overview" && (
          <div className="admin-view">
            <div className="admin-view-title"><div><p>Good day, Michael</p><h1>Your studio<br /><em>at a glance.</em></h1></div><button className="admin-refresh" onClick={() => loadData()}>Refresh data</button></div>
            <div className="metric-grid">
              <article><span>01</span><small>Total orders</small><strong>{metrics.totalOrders}</strong><button onClick={() => setTab("orders")}>View orders →</button></article>
              <article><span>02</span><small>New enquiries</small><strong>{metrics.newOrders}</strong><button onClick={() => setTab("orders")}>Review now →</button></article>
              <article><span>03</span><small>Saved cards</small><strong>{metrics.savedDesigns}</strong><button onClick={() => setTab("designs")}>View designs →</button></article>
              <article><span>04</span><small>Quoted value</small><div className="metric-currency-stack">{currencyCodes.map((code) => <strong key={code}>{formatMoney(metrics.revenueByCurrency[code], code)}</strong>)}</div><em>Excluding cancelled</em></article>
            </div>
            <section className="admin-latest">
              <div className="admin-section-title"><h2>Latest orders</h2><button onClick={() => setTab("orders")}>View all</button></div>
              <OrdersTable
                orders={data.orders.slice(0, 5)}
                onStatusChange={changeOrderStatus}
                onView={(order) => openOrderDialog(order, "view")}
                onEdit={(order) => openOrderDialog(order, "edit")}
              />
            </section>
          </div>
        )}

        {tab === "orders" && (
          <div className="admin-view">
            <div className="admin-view-title compact"><div><p>Order management</p><h1>Orders <em>({data.orders.length})</em></h1></div><button className="admin-refresh" onClick={() => loadData()}>Refresh data</button></div>
            <OrdersTable
              orders={data.orders}
              onStatusChange={changeOrderStatus}
              onView={(order) => openOrderDialog(order, "view")}
              onEdit={(order) => openOrderDialog(order, "edit")}
            />
          </div>
        )}

        {tab === "designs" && (
          <div className="admin-view">
            <div className="admin-view-title compact"><div><p>Customer creativity</p><h1>Saved cards <em>({data.designs.length})</em></h1></div></div>
            <div className="design-admin-grid">
              {data.designs.length ? data.designs.map((saved) => (
                <article key={saved.id}>
                  <div className={`mini-card palette-${saved.design.palette}`}><span>◇</span><strong>{saved.design.heading}</strong><small>{saved.design.partnerOne} & {saved.design.partnerTwo}</small></div>
                  <div><strong>{saved.design.partnerOne} & {saved.design.partnerTwo}</strong><span>{saved.email}</span><small>{formatDate(saved.createdAt)} · Wedding {saved.design.weddingDate || "date pending"}</small></div>
                </article>
              )) : <div className="admin-empty">No customer designs have been saved yet.</div>}
            </div>
          </div>
        )}

        {tab === "products" && (
          <div className="admin-view">
            <div className="admin-view-title compact"><div><p>Diamond catalogue</p><h1>Products & <em>prices.</em></h1></div><button className="button button-dark" onClick={savePricing}>Save prices</button></div>
            <div className="admin-pricing-list">
              <div className="pricing-header"><span>Diamond</span><span>Material</span>{currencyCodes.map((code) => <span key={code}>{code} / guest</span>)}</div>
              {pricingDraft.map((item, index) => (
                <div className="pricing-row" key={item.carat}>
                  <strong><i>✦</i>{item.carat.toFixed(2)} ct</strong>
                  <span>Lab-grown · Round brilliant</span>
                  {currencyCodes.map((code) => (
                    <label key={code}><b>{currencySymbols[code]}</b><input type="number" min="0" step="1" value={item.prices[code]} onChange={(event) => setPricingDraft((current) => current.map((price, priceIndex) => priceIndex === index ? { ...price, prices: { ...price.prices, [code]: Number(event.target.value) } } : price))} /></label>
                  ))}
                </div>
              ))}
            </div>
            <p className="admin-pricing-note">These prices appear immediately on the customer order page after saving. Enter whole South African Rand amounts per guest.</p>
          </div>
        )}
      </section>

      {activeOrder && orderDraft && (
        <div className="admin-order-modal-backdrop" role="dialog" aria-modal="true" aria-label={`Order ${activeOrder.reference}`}>
          <article className="admin-order-modal">
            <button className="admin-order-modal-close" onClick={closeOrderDialog} aria-label="Close order details">×</button>
            <div className="admin-order-modal-header">
              <div>
                <p>Order details</p>
                <h2>{activeOrder.reference}</h2>
                <span>Placed {formatDate(activeOrder.createdAt)}</span>
              </div>
              <div className="admin-order-modal-actions">
                <button className="admin-order-action" onClick={() => setOrderDialogMode(orderDialogMode === "view" ? "edit" : "view")}>{orderDialogMode === "view" ? "Edit order" : "View mode"}</button>
                <button className="admin-order-delete" onClick={() => deleteOrder(activeOrder)} disabled={orderDeleting || orderSaving}>{orderDeleting ? "Deleting…" : "Delete order"}</button>
              </div>
            </div>

            <div className="admin-order-grid">
              <label><span>Customer name</span><input value={orderDraft.customerName} onChange={(event) => setOrderDraft((current) => current ? { ...current, customerName: event.target.value } : current)} disabled={orderDialogMode === "view"} /></label>
              <label><span>Wedding date</span><input type="date" value={orderDraft.weddingDate || ""} onChange={(event) => setOrderDraft((current) => current ? { ...current, weddingDate: event.target.value } : current)} disabled={orderDialogMode === "view"} /></label>
              <label><span>Email</span><input type="email" value={orderDraft.email} onChange={(event) => setOrderDraft((current) => current ? { ...current, email: event.target.value } : current)} disabled={orderDialogMode === "view"} /></label>
              <label><span>Phone</span><input value={orderDraft.phone} onChange={(event) => setOrderDraft((current) => current ? { ...current, phone: event.target.value } : current)} disabled={orderDialogMode === "view"} /></label>
              <label><span>Delivery recipient</span><input value={orderDraft.deliveryRecipient || ""} onChange={(event) => setOrderDraft((current) => current ? { ...current, deliveryRecipient: event.target.value } : current)} disabled={orderDialogMode === "view"} /></label>
              <label><span>Delivery address</span><input value={orderDraft.deliveryAddress || ""} onChange={(event) => setOrderDraft((current) => current ? { ...current, deliveryAddress: event.target.value } : current)} disabled={orderDialogMode === "view"} /></label>
              <label><span>Guests</span><input type="number" min="1" step="1" value={orderDraft.guestCount} onChange={(event) => setOrderDraft((current) => current ? { ...current, guestCount: Number(event.target.value || 0) } : current)} disabled={orderDialogMode === "view"} /></label>
              <label><span>Diamond size</span><select value={orderDraft.carat} onChange={(event) => setOrderDraft((current) => current ? { ...current, carat: Number(event.target.value) } : current)} disabled={orderDialogMode === "view"}>{data.pricing.map((item) => <option key={item.carat} value={item.carat}>{item.carat.toFixed(2)} ct</option>)}</select></label>
              <label><span>Currency</span><select value={orderDraft.currency} onChange={(event) => setOrderDraft((current) => current ? { ...current, currency: event.target.value as CurrencyCode } : current)} disabled={orderDialogMode === "view"}>{currencyCodes.map((code) => <option key={code} value={code}>{code}</option>)}</select></label>
              <label><span>Status</span><select className={`status-${orderDraft.status}`} value={orderDraft.status} onChange={(event) => setOrderDraft((current) => current ? { ...current, status: event.target.value as OrderStatus } : current)} disabled={orderDialogMode === "view"}>{Object.entries(statusLabels).map(([value, label]) => <option key={value} value={value}>{label}</option>)}</select></label>
              <label className="admin-order-notes"><span>Order notes</span><textarea value={orderDraft.notes || ""} rows={5} onChange={(event) => setOrderDraft((current) => current ? { ...current, notes: event.target.value } : current)} disabled={orderDialogMode === "view"} placeholder="Add internal notes for this order." /></label>
            </div>

            {activeOrder.uploadedDesign && (
              <a className="admin-pdf-link" href={`/api/admin/uploads?id=${encodeURIComponent(activeOrder.uploadedDesign.id)}`} target="_blank" rel="noreferrer">Open uploaded artwork ↗</a>
            )}

            {orderDialogMode === "edit" && (
              <div className="admin-order-save-row">
                <button className="button button-dark" onClick={saveOrderDraft} disabled={orderSaving || orderDeleting}>{orderSaving ? "Saving…" : "Save order changes"}</button>
              </div>
            )}
          </article>
        </div>
      )}
    </main>
  );
}

function OrdersTable({
  orders,
  onStatusChange,
  onView,
  onEdit,
}: {
  orders: AdminOrder[];
  onStatusChange: (id: string, status: OrderStatus) => void;
  onView: (order: AdminOrder) => void;
  onEdit: (order: AdminOrder) => void;
}) {
  if (!orders.length) return <div className="admin-empty">No orders have been placed yet.</div>;
  return (
    <div className="admin-table-wrap">
      <table className="admin-table">
        <thead><tr><th>Order</th><th>Customer</th><th>Delivery</th><th>Diamond</th><th>Guests</th><th>Total</th><th>Status</th><th>Actions</th></tr></thead>
        <tbody>{orders.map((order) => (
          <tr key={order.id}>
            <td><strong>{order.reference}</strong><span>{formatDate(order.createdAt)}</span></td>
            <td><strong>{order.customerName}</strong><span>{order.email}</span><span>{order.phone}</span>{order.weddingDate && <span>Wedding · {formatWeddingDate(order.weddingDate)}</span>}</td>
            <td className="admin-delivery"><strong>{order.deliveryRecipient || "Not captured"}</strong><span>{order.deliveryAddress || "—"}</span></td>
            <td><strong>{order.carat.toFixed(2)} ct</strong><span>{formatMoney(order.pricePerGuest, order.currency || "ZAR")} each</span></td>
            <td>
              <strong>{order.guestCount}</strong>
              {order.uploadedDesign ? (
                <a className="admin-pdf-link" href={`/api/admin/uploads?id=${encodeURIComponent(order.uploadedDesign.id)}`} target="_blank" rel="noreferrer">PDF artwork ↗</a>
              ) : order.design ? <span>{order.design.partnerOne} & {order.design.partnerTwo}</span> : null}
            </td>
            <td><strong>{formatMoney(order.total, order.currency || "ZAR")}</strong></td>
            <td><select className={`status-${order.status}`} value={order.status} onChange={(event) => onStatusChange(order.id, event.target.value as OrderStatus)}>{Object.entries(statusLabels).map(([value, label]) => <option key={value} value={value}>{label}</option>)}</select></td>
            <td>
              <div className="admin-table-actions">
                <button onClick={() => onView(order)}>View</button>
                <button onClick={() => onEdit(order)}>Edit</button>
              </div>
            </td>
          </tr>
        ))}</tbody>
      </table>
    </div>
  );
}
