"use client";

import { useEffect, useRef, useState, type ReactNode } from "react";
import Link from "next/link";
import { CreditCard, FileText, LayoutDashboard, MessageSquare, Package, RotateCcw, Store, X } from "lucide-react";
import fixture from "@/data/client-space.json";
import { catalogProducts } from "@/data/catalog";
import { useAccount } from "./account-store";
import { useDemoStore } from "@/components/shop/demo-store";
import { authHref, demoPassword, ordersForAccount, type DemoProfile } from "@/lib/account";
import { customerForEmail, label, minorMoney as money, orderStages, ownedOrders, ownedTickets, reorderPlan, validateTicket, wholesaleAccess, type ClientCustomer, type ClientOrder, type ClientOrderItem, type ClientTicket } from "@/lib/client-space";
import { invoiceSummary, partyLedger } from "@/lib/wholesale-preview.mjs";

type Tab = "overview" | "orders" | "documents" | "tickets" | "wholesale";
type Modal = { kind: "order" | "invoice"; order: ClientOrder } | { kind: "ticket"; id: string } | { kind: "trade-invoice"; id: string } | { kind: "receipt"; id: string; trade: boolean } | { kind: "reorder"; order: ClientOrder; plan: ReturnType<typeof reorderPlan> } | { kind: "request"; items: ClientOrderItem[]; issues: string[] };
const tabs = [{ id: "overview", name: "Overview", icon: LayoutDashboard }, { id: "orders", name: "My orders", icon: Package }, { id: "documents", name: "Payments & invoices", icon: FileText }, { id: "tickets", name: "Support tickets", icon: MessageSquare }, { id: "wholesale", name: "Wholesale", icon: Store }] as const;
const Badge = ({ value }: { value: string }) => <span className={`portal-badge ${value}`}>{label(value)}</span>;

export function ClientPortal() {
  const account = useAccount();
  const { hydrated } = useDemoStore();
  const [error, setError] = useState("");
  function demo(type: "customer" | "wholesale") {
    const email = type === "customer" ? "customer@example.com" : "wholesale@example.com";
    const name = type === "customer" ? "Demo Customer" : "North Lane Buyer";
    const issue = account.signIn(email, demoPassword);
    setError(issue ? account.register(name, email, demoPassword) : "");
  }
  return <section className="portal-page section-padding"><div className="portal-heading"><div><p className="eyebrow">FASHION MART / CLIENT PORTAL</p><h1>Your account workspace</h1><p>Orders, invoices, payments and support in one place.</p></div><div className="portal-demo-switch"><span>Sample account</span><button type="button" disabled={!account.ready} onClick={() => demo("customer")}>Customer demo</button><button type="button" disabled={!account.ready} onClick={() => demo("wholesale")}>Wholesale demo</button></div></div><p className="demo-note">UI preview only. Use sample details. Demo sign-in uses {demoPassword}; no real authentication, payment or support message is connected.</p>{error && <p className="commerce-error" role="alert">{error}</p>}{!account.ready || !hydrated ? <p role="status">Loading your demo account…</p> : !account.profile ? <div className="account-card"><h2>Sign in to your space</h2><p>Use a sample account above, or sign in with an account created in this browser.</p><div className="portal-auth-actions"><Link href={authHref("login", "/account/portal")} className="button button-primary">Sign in</Link><Link href={authHref("register", "/account/portal")} className="text-link">Create demo account</Link></div></div> : <PortalWorkspace key={account.profile.email} profile={account.profile} />}</section>;
}

function PortalWorkspace({ profile }: { profile: DemoProfile }) {
  const account = useAccount();
  const store = useDemoStore();
  const client: ClientCustomer = customerForEmail(fixture.customers, profile.email) || { id: `local:${profile.email}`, name: profile.name, email: profile.email, phone: profile.phone, address: "", status: "active", type: "customer", wholesaleStatus: "none", partyId: "", businessName: "" };
  const [tab, setTab] = useState<Tab>("overview");
  const [modal, setModal] = useState<Modal | null>(null);
  const [notice, setNotice] = useState("");
  const [statusFilter, setStatusFilter] = useState("");
  const [tickets, setTickets] = useState<ClientTicket[]>(() => ownedTickets(fixture.tickets, fixture.customers, profile.email));
  const [requests, setRequests] = useState<{ id: string; items: ClientOrderItem[]; total: number }[]>([]);
  const [application, setApplication] = useState(false);
  const localOrders: ClientOrder[] = ordersForAccount(store.orders, profile.email).map((order) => ({ id: order.id, customerId: client.id, channel: "retail", createdAt: order.placedAt.slice(0, 10), status: "confirmed", paymentStatus: "unpaid", received: 0, method: "Cash on delivery", delivery: order.delivery * 100, discount: 0, total: order.total * 100, invoiceId: `INV-${order.id}`, courier: "", tracking: "", address: order.customer.address, history: [{ status: "confirmed", at: order.placedAt, actor: "Demo checkout", note: "Saved in this browser; no live order was sent." }], items: order.items.map((item) => ({ productId: item.productId, variantId: item.variantId, name: item.name, colour: item.color, size: item.size, image: item.image, sku: fixture.products.find((p) => p.id === item.productId)?.variants.find((v) => v.id === item.variantId)?.sku || "", quantity: item.quantity, unitPrice: item.unitPrice * 100 })) }));
  const orders = [...localOrders, ...ownedOrders(fixture.orders, fixture.customers, profile.email)].sort((a, b) => b.createdAt.localeCompare(a.createdAt));
  const trade = wholesaleAccess(client);
  const ledger = trade ? partyLedger(fixture.wholesale, client.partyId) : null;
  const invoices = orders.filter((order) => order.invoiceId && !order.invoiceId.startsWith("WH"));
  const tradeInvoices = trade ? fixture.wholesale.invoices.filter((invoice) => invoice.partyId === client.partyId && invoice.status === "confirmed") : [];
  const payments = fixture.payments.filter((payment) => payment.customerId === client.id && !orders.find((order) => order.id === payment.orderId)?.invoiceId.startsWith("WH"));
  const tradePayments = trade ? [...fixture.wholesale.payments.filter((payment) => payment.partyId === client.partyId), ...tradeInvoices.filter((invoice) => invoice.received > 0).map((invoice) => ({ id: `${invoice.id}-PAY`, partyId: invoice.partyId, invoiceId: invoice.id, date: invoice.date, amount: invoice.received, method: invoice.method, reference: invoice.id, note: "Payment with invoice" }))] : [];
  if (client.status === "suspended") return <div className="account-card"><h2>Account suspended — demo</h2><p>This sample account is unavailable for portal actions.</p><button type="button" className="button button-outline" onClick={account.signOut}>Sign out</button></div>;
  function reorder(order: ClientOrder) {
    const plan = reorderPlan(order.items, order.channel === "wholesale" ? fixture.products : catalogProducts, order.channel === "wholesale" ? [] : store.cart);
    setModal({ kind: "reorder", order, plan });
  }
  function requestItems(items: ClientOrderItem[], issues: string[] = []) { setModal({ kind: "request", items, issues }); }
  function invoiceFromTrade(id: string): ClientOrder | undefined {
    const invoice = tradeInvoices.find((item) => item.id === id);
    if (!invoice) return;
    const summary = invoiceSummary(invoice, fixture.wholesale.payments);
    return { id, customerId: client.id, channel: "wholesale", createdAt: invoice.date, status: "confirmed", paymentStatus: summary.paymentStatus, received: summary.paid, method: invoice.method, total: summary.total, delivery: invoice.delivery, discount: invoice.discount, invoiceId: invoice.id, courier: "", tracking: "", address: client.address, history: [], items: invoice.lines.map((line) => { const p = fixture.products.find((item) => item.id === line.productId)!; const v = p.variants.find((item) => item.id === line.variantId)!; return { productId: p.id, variantId: v.id, name: p.name, colour: v.colour, size: v.size, sku: v.sku, image: v.images[0], quantity: line.quantity, unitPrice: line.rate }; }) };
  }
  function modalContent(): ReactNode {
    if (!modal) return null;
    if (modal.kind === "order" || modal.kind === "invoice") {
      const order = orders.find((item) => item.id === modal.order.id);
      if (!order) return <p>Order unavailable for this account.</p>;
      return modal.kind === "invoice" ? <PortalInvoice order={order} name={profile.name} /> : <><p className="portal-muted">{order.createdAt} · <Badge value={order.status} /> <Badge value={order.paymentStatus} /></p><OrderTimeline order={order} /><PortalLines items={order.items} /><dl className="portal-totals"><div><dt>Total</dt><dd>{money(order.total)}</dd></div><div><dt>Received</dt><dd>{money(order.received)}</dd></div><div><dt>Courier / tracking</dt><dd>{order.courier || "Not assigned"}<br />{order.tracking || "Not available yet"}</dd></div><div><dt>Delivery address</dt><dd>{order.address}</dd></div></dl><ol className="portal-history">{order.history.map((entry, index) => <li key={index}><strong>{label(entry.status)}</strong> · {entry.note}<small>{entry.at} · {entry.actor}</small></li>)}</ol><div className="portal-actions" data-print-hide><button type="button" className="button button-outline" onClick={() => reorder(order)}><RotateCcw size={14} /> Reorder</button>{order.invoiceId && <button type="button" className="button button-primary" onClick={() => setModal({ kind: "invoice", order })}>Invoice preview</button>}<button type="button" className="button button-outline" onClick={() => { setModal(null); setTab("tickets"); }}>Get support</button></div></>;
    }
    if (modal.kind === "trade-invoice") { const order = invoiceFromTrade(modal.id); return order ? <PortalInvoice order={order} name={client.businessName || profile.name} /> : <p>Invoice unavailable.</p>; }
    if (modal.kind === "receipt") {
      const receipt = modal.trade ? tradePayments.find((item) => item.id === modal.id) : payments.find((item) => item.id === modal.id);
      return receipt ? <div className="portal-paper"><p className="eyebrow">FASHION MART / DEMO RECEIPT</p><h3>{receipt.id}</h3><p>{profile.name} · {receipt.date}</p><dl className="portal-totals"><div><dt>Received</dt><dd>{money(receipt.amount)}</dd></div><div><dt>Method</dt><dd>{receipt.method}</dd></div><div><dt>Reference</dt><dd>{receipt.reference}</dd></div></dl><p className="demo-note">DEMO / NOT POSTED. No payment was made.</p><button type="button" className="button button-outline" data-print-hide onClick={() => window.print()}>Print / Save PDF</button></div> : <p>Receipt unavailable.</p>;
    }
    if (modal.kind === "ticket") {
      const ticket = tickets.find((item) => item.id === modal.id);
      if (!ticket) return <p>Ticket unavailable.</p>;
      return <><p><Badge value={ticket.status} /> · {ticket.orderId || "General enquiry"}</p><div className="portal-conversation">{ticket.messages.map((entry, index) => <div className={`portal-chat ${entry.actor}`} key={index}><strong>{entry.name}</strong><p>{entry.text}</p><small>{entry.at}</small></div>)}</div>{ticket.status === "closed" ? <button className="button button-outline" type="button" onClick={() => setTickets((items) => items.map((item) => item.id === ticket.id ? { ...item, status: "open" } : item))}>Reopen ticket preview</button> : <form className="portal-form" onSubmit={(event) => { event.preventDefault(); const text = String(new FormData(event.currentTarget).get("reply") || "").trim(); if (text.length < 5) return; setTickets((items) => items.map((item) => item.id === ticket.id ? { ...item, status: "open", messages: [...item.messages, { actor: "customer", name: profile.name, text, at: new Date().toISOString() }] } : item)); event.currentTarget.reset(); setNotice("Reply preview added. No message was sent."); }}><label>Reply<textarea name="reply" required minLength={5} maxLength={2000} rows={3} /></label><button className="button button-primary" type="submit">Preview reply</button></form>}</>;
    }
    if (modal.kind === "reorder") return <><p>Availability is checked again. Current prices will be used.</p>{modal.plan.issues.map((issue) => <p className="portal-warning" key={issue}>{issue}</p>)}<div className="portal-table-scroll"><table className="portal-table"><thead><tr><th>Variant</th><th>Qty</th><th>Current amount</th></tr></thead><tbody>{modal.plan.lines.map((line) => <tr key={line.variantId}><td>{modal.order.items.find((item) => item.variantId === line.variantId)?.name || "Product variant"}<small>{modal.order.items.find((item) => item.variantId === line.variantId)?.colour} / {modal.order.items.find((item) => item.variantId === line.variantId)?.size}</small></td><td>{line.quantity}</td><td>{money(line.priceMinor * line.quantity)}</td></tr>)}</tbody></table></div><button type="button" className="button button-primary" disabled={!modal.plan.lines.length} onClick={() => { if (modal.order.channel === "wholesale") { if (!trade) return; requestItems(modal.plan.lines.map((line) => { const old = modal.order.items.find((item) => item.variantId === line.variantId)!; return { ...old, quantity: line.quantity, unitPrice: (fixture.wholesale.rates as Record<string, number>)[line.variantId] || line.priceMinor }; }), modal.plan.issues); } else { const added = modal.plan.lines.filter((line) => store.addItem(line.productId, line.variantId, line.quantity)); setNotice(`${added.length} variants added to your bag at current prices.`); setModal(null); } }}>{modal.order.channel === "wholesale" ? "Preview wholesale request" : "Add available items to bag"}</button><p className="portal-muted">A reorder does not duplicate the old invoice or payment.</p></>;
    if (modal.kind === "request") return <><PortalLines items={modal.items} />{modal.issues.map((issue) => <p className="portal-warning" key={issue}>{issue}</p>)}<p>Indicative amount: <strong>{money(modal.items.reduce((sum, item) => sum + item.quantity * item.unitPrice, 0))}</strong></p><p className="demo-note">Wholesale requests require review before an invoice is issued. This request is a local UI preview and will not be sent.</p><button type="button" className="button button-primary" onClick={() => { if (!trade) return; setRequests((items) => [...items, { id: `RQPREVIEW-${Date.now().toString(36).toUpperCase()}`, items: modal.items, total: modal.items.reduce((sum, item) => sum + item.quantity * item.unitPrice, 0) }]); setModal(null); setTab("wholesale"); setNotice("Request preview created for this page only. Nothing was sent."); }}>Create request preview</button></>;
    return null;
  }
  return <><div className="portal-layout"><nav className="portal-navigation" aria-label="Client account navigation"><strong>{profile.name}</strong><small>{profile.email}</small>{tabs.map((item) => { const Icon = item.icon; return <button type="button" key={item.id} aria-pressed={tab === item.id} onClick={() => setTab(item.id)}><Icon size={16} />{item.name}</button>; })}<Link href="/account">Profile</Link><Link href="/account/addresses">Addresses</Link><Link href="/cart">Shopping bag</Link><button type="button" onClick={account.signOut}>Sign out</button></nav><div className="portal-content">{notice && <p className="portal-notice" role="status">{notice}</p>}
    {tab === "overview" && <><div className="portal-section-title"><h2>Account overview</h2><Badge value={trade ? "wholesale" : "customer"} /></div><div className="portal-metrics">{[["My orders", orders.length], ["Active orders", orders.filter((order) => !["delivered", "returned", "cancelled"].includes(order.status)).length], ["Open tickets", tickets.filter((ticket) => !["closed", "resolved"].includes(ticket.status)).length], [trade ? "Wholesale due" : "Account", trade ? money(ledger!.closing) : "Active"]].map(([title, value]) => <article key={title}><small>{title}</small><strong>{value}</strong></article>)}</div><div className="portal-section-title"><h3>Recent orders</h3><button type="button" className="text-link" onClick={() => setTab("orders")}>View all</button></div><OrdersTable orders={orders.slice(0, 4)} onView={(order) => setModal({ kind: "order", order })} onReorder={reorder} />{!orders.length && <Link className="text-link" href="/shop">Browse products</Link>}<p className="portal-muted">You can manage delivery addresses from your address book and open a ticket for help with an order or payment.</p></>}
    {tab === "orders" && <><div className="portal-section-title"><h2>My orders</h2><label className="portal-select">Status<select value={statusFilter} onChange={(event) => setStatusFilter(event.target.value)}><option value="">All statuses</option>{[...orderStages, "cancelled", "returned", "delivery_failed"].map((status) => <option key={status} value={status}>{label(status)}</option>)}</select></label></div><OrdersTable orders={orders.filter((order) => !statusFilter || order.status === statusFilter)} onView={(order) => setModal({ kind: "order", order })} onReorder={reorder} /><Link className="text-link" href="/account/orders">View original browser checkout history</Link></>}
    {tab === "documents" && <><h2>Invoices &amp; payments</h2><h3>Invoices</h3><div className="portal-table-scroll"><table className="portal-table"><thead><tr><th>Invoice</th><th>Date</th><th>Total</th><th>Payment</th><th></th></tr></thead><tbody>{invoices.map((order) => <tr key={order.id}><td>{order.invoiceId}</td><td>{order.createdAt}</td><td>{money(order.total)}</td><td><Badge value={order.paymentStatus} /></td><td><button type="button" onClick={() => setModal({ kind: "invoice", order })}>View / Print</button></td></tr>)}{tradeInvoices.map((invoice) => { const totals = invoiceSummary(invoice, fixture.wholesale.payments); return <tr key={invoice.id}><td>{invoice.id}</td><td>{invoice.date}</td><td>{money(totals.total)}</td><td><Badge value={totals.paymentStatus} /></td><td><button type="button" onClick={() => setModal({ kind: "trade-invoice", id: invoice.id })}>View / Print</button></td></tr>; })}{!invoices.length && !tradeInvoices.length && <tr><td colSpan={5}>No invoices for this account.</td></tr>}</tbody></table></div><h3>Payment receipts</h3><div className="portal-table-scroll"><table className="portal-table"><thead><tr><th>Receipt</th><th>Date</th><th>Method</th><th>Amount</th><th></th></tr></thead><tbody>{[...payments.map((payment) => ({ ...payment, trade: false })), ...tradePayments.map((payment) => ({ ...payment, trade: true }))].map((payment) => <tr key={payment.id}><td>{payment.id}</td><td>{payment.date}</td><td>{payment.method}</td><td>{money(payment.amount)}</td><td><button type="button" onClick={() => setModal({ kind: "receipt", id: payment.id, trade: payment.trade })}>Receipt</button></td></tr>)}{!payments.length && !tradePayments.length && <tr><td colSpan={5}>No receipts for this account.</td></tr>}</tbody></table></div><button type="button" className="button button-outline" onClick={() => setTab("tickets")}>Payment enquiry</button></>}
    {tab === "tickets" && <><h2>Support tickets</h2><div className="portal-table-scroll"><table className="portal-table"><thead><tr><th>Ticket / Subject</th><th>Order</th><th>Status</th><th></th></tr></thead><tbody>{tickets.map((ticket) => <tr key={ticket.id}><td><strong>{ticket.id}</strong><small>{ticket.subject}</small></td><td>{ticket.orderId || "General"}</td><td><Badge value={ticket.status} /></td><td><button type="button" onClick={() => setModal({ kind: "ticket", id: ticket.id })}>Open</button></td></tr>)}{!tickets.length && <tr><td colSpan={4}>No support tickets yet.</td></tr>}</tbody></table></div><TicketComposer orders={orders} onCreate={(values) => { const issue = validateTicket(values.subject, values.text, values.orderId, orders); if (issue) return issue; const id = `TKPREVIEW-${Date.now().toString(36).toUpperCase()}`; setTickets((items) => [...items, { id, customerId: client.id, orderId: values.orderId, subject: values.subject.trim(), category: values.category, priority: "normal", status: "open", createdAt: new Date().toISOString().slice(0, 10), messages: [{ actor: "customer", name: profile.name, text: values.text.trim(), at: new Date().toISOString() }] }]); setNotice("Ticket preview opened in this page only. No message was sent."); return ""; }} /></>}
    {tab === "wholesale" && (trade ? <><div className="portal-section-title"><h2>Wholesale workspace</h2><Badge value="approved" /></div><p>{client.businessName} · Party {client.partyId}</p><div className="portal-metrics">{[["Opening / debit", money(ledger!.debit)], ["Received", money(ledger!.credit)], ["Current due", money(ledger!.closing)]].map(([title, value]) => <article key={title}><small>{title}</small><strong>{value}</strong></article>)}</div><h3>Purchase invoices</h3><div className="portal-table-scroll"><table className="portal-table"><thead><tr><th>Invoice</th><th>Total</th><th>Due</th><th></th></tr></thead><tbody>{tradeInvoices.map((invoice) => { const summary = invoiceSummary(invoice, fixture.wholesale.payments); return <tr key={invoice.id}><td>{invoice.id}</td><td>{money(summary.total)}</td><td>{money(summary.due)}</td><td><button type="button" onClick={() => setModal({ kind: "trade-invoice", id: invoice.id })}>Invoice</button><button type="button" onClick={() => { const order = invoiceFromTrade(invoice.id); if (order) reorder(order); }}>Reorder</button></td></tr>; })}</tbody></table></div><h3>Transaction ledger</h3><div className="portal-table-scroll"><table className="portal-table"><thead><tr><th>Date / Reference</th><th>Debit</th><th>Credit</th><th>Balance</th></tr></thead><tbody>{ledger!.rows.map((row) => <tr key={row.id}><td>{row.date}<small>{row.reference} · {row.description}</small></td><td>{money(row.debit)}</td><td>{money(row.credit)}</td><td>{money(row.balance)}</td></tr>)}</tbody></table></div><WholesaleRequest onPreview={requestItems} /><h3>Request previews</h3>{requests.length ? requests.map((request) => <article className="portal-request" key={request.id}><strong>{request.id}</strong><Badge value="awaiting_review" /><p>{request.items.length} variants · Indicative {money(request.total)}</p><small>Local preview only; not submitted.</small></article>) : <p className="portal-muted">No new request previews.</p>}</> : <><h2>Wholesale account</h2><Badge value={application ? "pending" : client.wholesaleStatus === "none" ? "not_applied" : client.wholesaleStatus} /><p>Approved accounts can view wholesale invoices, outstanding balances and the Party ledger, and preview new order requests.</p><form className="portal-form account-card" onSubmit={(event) => { event.preventDefault(); setApplication(true); setNotice("Wholesale application preview is pending review. No application was submitted or access granted."); }}><h3>Application preview</h3><label>Business / shop name<input name="business" required minLength={2} maxLength={100} defaultValue={client.businessName} /></label><label>Business phone<input name="phone" type="tel" required pattern="01[3-9][0-9]{8}" maxLength={11} placeholder="01XXXXXXXXX" defaultValue={profile.phone || client.phone} /></label><label>Business address<textarea name="address" required minLength={10} maxLength={300} rows={2} defaultValue={client.address} /></label><button type="submit" className="button button-primary">Preview application</button></form></>)}
    <p className="portal-muted portal-session-note">Portal requests and ticket replies reset when you leave this page. Admin previews and this portal are not live-connected yet.</p></div></div>{modal && <PortalModal title={modal.kind === "ticket" ? modal.id : modal.kind === "request" ? "Wholesale request preview" : modal.kind === "reorder" ? "Reorder availability" : modal.kind === "trade-invoice" || modal.kind === "receipt" ? modal.id : modal.order.id} onClose={() => setModal(null)}>{modalContent()}</PortalModal>}</>;
}

function OrdersTable({ orders, onView, onReorder }: { orders: ClientOrder[]; onView: (order: ClientOrder) => void; onReorder: (order: ClientOrder) => void }) {
  return <div className="portal-table-scroll"><table className="portal-table"><thead><tr><th>Order / Date</th><th>Total</th><th>Status</th><th>Payment</th><th></th></tr></thead><tbody>{orders.map((order) => <tr key={order.id}><td><strong>{order.id}</strong><small>{order.createdAt}</small></td><td>{money(order.total)}</td><td><Badge value={order.status} /></td><td><Badge value={order.paymentStatus} /></td><td><button type="button" onClick={() => onView(order)}>Details</button><button type="button" onClick={() => onReorder(order)} aria-label={`Reorder ${order.id}`}>Reorder</button></td></tr>)}{!orders.length && <tr><td colSpan={5}>No orders match this account or filter.</td></tr>}</tbody></table></div>;
}
function OrderTimeline({ order }: { order: ClientOrder }) {
  const index = order.status === "returned" ? 4 : order.status === "delivery_failed" ? 3 : orderStages.indexOf(order.status);
  return <ol className="portal-timeline" aria-label="Order progress">{orderStages.map((status, step) => <li key={status} className={step <= index || order.history.some((entry) => entry.status === status) ? "done" : ""} aria-current={order.status === status ? "step" : undefined}>{label(status)}</li>)}</ol>;
}
function PortalLines({ items }: { items: ClientOrderItem[] }) { return <div className="portal-lines">{items.map((item) => <div key={item.variantId}><img src={item.image} alt="" width={48} height={58} /><span><strong>{item.name}</strong><small>{item.colour} / {item.size} · {item.sku} · Qty {item.quantity}</small></span><b>{money(item.quantity * item.unitPrice)}</b></div>)}</div>; }
function PortalInvoice({ order, name }: { order: ClientOrder; name: string }) { return <article className="portal-paper"><p className="eyebrow">FASHION MART / INVOICE PREVIEW</p><div className="portal-section-title"><h3>{order.invoiceId || order.id}</h3><Badge value={order.paymentStatus} /></div><p>{name} · {order.createdAt}</p><p className="portal-muted">{order.address}</p><PortalLines items={order.items} /><dl className="portal-totals"><div><dt>Discount</dt><dd>{money(order.discount)}</dd></div><div><dt>Delivery</dt><dd>{money(order.delivery)}</dd></div><div><dt>Invoice total</dt><dd>{money(order.total)}</dd></div><div><dt>Received</dt><dd>{money(order.received)}</dd></div></dl><p className="demo-note">DEMO / NOT POSTED. This document does not confirm a real sale or payment.</p><button type="button" className="button button-outline" data-print-hide onClick={() => window.print()}>Print / Save PDF</button></article>; }
function PortalModal({ title, children, onClose }: { title: string; children: ReactNode; onClose: () => void }) {
  const ref = useRef<HTMLDialogElement>(null);
  useEffect(() => { const dialog = ref.current!; const previous = document.body.style.overflow; const focus = document.activeElement instanceof HTMLElement ? document.activeElement : null; if (!dialog.open) dialog.showModal(); document.body.style.overflow = "hidden"; return () => { document.body.style.overflow = previous; focus?.focus(); }; }, []);
  return <dialog className="portal-modal" ref={ref} onClose={onClose} aria-labelledby="portal-modal-title" onClick={(event) => { if (event.target === ref.current) { const box = ref.current.getBoundingClientRect(); if (event.clientX < box.left || event.clientX > box.right || event.clientY < box.top || event.clientY > box.bottom) ref.current.close(); } }}><header data-print-hide><h2 id="portal-modal-title">{title}</h2><button type="button" aria-label="Close preview" onClick={() => ref.current?.close()}><X size={19} /></button></header><div className="portal-modal-body">{children}</div></dialog>;
}
function TicketComposer({ orders, onCreate }: { orders: ClientOrder[]; onCreate: (values: { orderId: string; subject: string; category: string; text: string }) => string }) {
  const [error, setError] = useState("");
  return <form className="portal-form account-card" onSubmit={(event) => { event.preventDefault(); const form = event.currentTarget; const fields = new FormData(form); const issue = onCreate({ orderId: String(fields.get("orderId")), subject: String(fields.get("subject")), category: String(fields.get("category")), text: String(fields.get("text")) }); setError(issue); if (!issue) form.reset(); }}><h3>Open a ticket preview</h3>{error && <p className="commerce-error" role="alert">{error}</p>}<div className="portal-form-pair"><label>Related order<select name="orderId"><option value="">General enquiry</option>{orders.map((order) => <option value={order.id} key={order.id}>{order.id}</option>)}</select></label><label>Category<select name="category"><option>Order</option><option>Payment</option><option>Wholesale</option><option>Return</option><option>General</option></select></label></div><label>Subject<input name="subject" required minLength={5} maxLength={120} /></label><label>Message<textarea name="text" required minLength={5} maxLength={2000} rows={3} /></label><button type="submit" className="button button-primary">Open ticket preview</button></form>;
}
function WholesaleRequest({ onPreview }: { onPreview: (items: ClientOrderItem[], issues?: string[]) => void }) {
  const [query, setQuery] = useState(""); const [variantId, setVariantId] = useState(""); const [quantity, setQuantity] = useState(1); const [items, setItems] = useState<ClientOrderItem[]>([]); const [error, setError] = useState("");
  const variants = fixture.products.filter((product) => product.status === "active").flatMap((product) => product.variants.filter((variant) => variant.enabled && variant.stock > 0).map((variant) => ({ product, variant }))).filter(({ product, variant }) => `${product.name} ${variant.sku} ${variant.colour} ${variant.size}`.toLowerCase().includes(query.toLowerCase()));
  return <section className="account-card portal-form"><h3>New wholesale request</h3><label>Search products or SKU<input type="search" value={query} onChange={(event) => setQuery(event.target.value)} /></label><label>Product / colour / size<select value={variants.some((item) => item.variant.id === variantId) ? variantId : ""} onChange={(event) => setVariantId(event.target.value)}><option value="">Choose a variant</option>{variants.map(({ product, variant }) => <option value={variant.id} key={variant.id}>{product.name} · {variant.colour} / {variant.size} · {variant.sku}</option>)}</select></label><label>Quantity<input type="number" min={1} step={1} value={Number.isNaN(quantity) ? "" : quantity} onChange={(event) => setQuantity(Number(event.target.value))} /></label><button type="button" className="button button-outline" onClick={() => { const found = variants.find((item) => item.variant.id === variantId); if (!found || !Number.isSafeInteger(quantity) || quantity <= 0) return setError("Choose a variant and positive whole quantity."); const previous = items.find((item) => item.variantId === variantId); if ((previous?.quantity || 0) + quantity > found.variant.stock) return setError("Quantity exceeds current demo stock."); const line: ClientOrderItem = { productId: found.product.id, variantId, name: found.product.name, colour: found.variant.colour, size: found.variant.size, sku: found.variant.sku, image: found.variant.images[0], quantity, unitPrice: (fixture.wholesale.rates as Record<string, number>)[variantId] || found.variant.price * 100 }; setItems((current) => previous ? current.map((item) => item.variantId === variantId ? { ...item, quantity: item.quantity + quantity } : item) : [...current, line]); setError(""); }}>Add variant</button>{error && <p className="commerce-error" role="alert">{error}</p>}{items.length > 0 && <><PortalLines items={items} /><div className="portal-actions"><button type="button" className="button button-outline" onClick={() => setItems([])}>Clear items</button><button type="button" className="button button-primary" onClick={() => onPreview(items)}>Preview request</button></div></>}<p className="portal-muted">Sample rates are indicative. Wholesale requests require review before invoicing.</p></section>;
}
