import { useEffect, useMemo, useState } from "react";
import { emptyPrompt, emptyState } from "./data";
import type { AppState, CricutPanel, CricutProject, InventoryMaterial, Section } from "./types";
import { buildProjectFromPrompt, downloadTextFile, handoffManifest } from "./services/cricut";
import { loadState, resetState, saveState } from "./services/storage";

const navItems: Array<{ id: Section; label: string; icon: string }> = [
  { id: "dashboard", label: "Dashboard", icon: "DB" },
  { id: "projectBuilder", label: "AI Project Builder", icon: "AI" },
  { id: "cricutExport", label: "Cricut Export", icon: "CX" },
  { id: "materialsDeals", label: "Materials & Deals", icon: "MD" },
  { id: "customers", label: "Customers", icon: "CU" },
  { id: "orders", label: "Orders", icon: "OR" },
  { id: "products", label: "Products", icon: "PR" },
  { id: "templates", label: "Templates", icon: "TP" },
  { id: "inventory", label: "Inventory", icon: "IN" },
  { id: "pricing", label: "Pricing", icon: "PC" },
  { id: "marketing", label: "Marketing", icon: "MK" },
  { id: "license", label: "License", icon: "LC" },
  { id: "release", label: "Mobile Release", icon: "MOB" }
];

const projectTabs = ["Plan", "SVG", "Panels", "Assembly"] as const;

const copyrightNotice = "© 2026 ProjectCraft Pro. All rights reserved.";
const ownershipStatement = "ProjectCraft Pro is proprietary software owned and operated under the ProjectCraft Pro brand.";
const cricutDisclaimer = "Cricut is a trademark of Cricut, Inc. ProjectCraft Pro is not affiliated with, sponsored by, authorized by, or endorsed by Cricut, Inc.";
const pricingDisclaimer = "Prices and availability may change. Confirm the final price with the retailer before purchasing.";
const retailerDisclaimer = "Retailer and product names are trademarks of their respective owners. ProjectCraft Pro is not affiliated with, sponsored by, authorized by, or endorsed by any listed retailer unless a written partnership is separately disclosed.";
const affiliateDisclosure = "Affiliate disclosure: ProjectCraft Pro may earn a commission from qualifying purchases when affiliate links are used. Affiliate links are optional and disabled until approved accounts are configured.";
const catalogDisclaimer = "Material recommendations use approved product feeds or manual catalog entries that you add. Placeholder prices and retailer placeholders are not bundled in production builds.";

type ProjectTab = (typeof projectTabs)[number];
const materialDealTabs = ["Materials", "Where to Buy", "Price Comparison", "Shopping List", "Project Cost", "Alternatives", "Sale Alerts", "Admin Catalog"] as const;
type MaterialDealTab = (typeof materialDealTabs)[number];

type MaterialDealProduct = {
  id: string;
  name: string;
  category: "Permanent Vinyl" | "Stencil Vinyl" | "Heat Transfer Vinyl" | "Transfer Tape" | "Cardstock" | "Blank";
  retailer: string;
  brand: string;
  color: string;
  width: number;
  length: number;
  regularPrice: number;
  salePrice?: number;
  inventory: "In stock" | "Low stock" | "Online only" | "Admin review";
  dataSource: "Approved Feed" | "Admin Entry";
  lastChecked: string;
  productUrl: string;
  notes: string;
  compatibility: string;
  quality: "Budget" | "Balanced" | "Professional";
};

const materialCatalog: MaterialDealProduct[] = [];

function currency(value: number): string {
  return new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(value);
}

function number(value: number): string {
  return new Intl.NumberFormat("en-US", { maximumFractionDigits: 1 }).format(value);
}

function productPrice(product: MaterialDealProduct): number {
  return product.salePrice ?? product.regularPrice;
}

function productCoverage(product: MaterialDealProduct): number {
  return product.width * product.length;
}

function priceFreshness(product: MaterialDealProduct): string {
  return `Price last checked: ${product.lastChecked}`;
}

function projectArea(project: CricutProject | null): number {
  if (!project) {
    return 24 * 18;
  }

  const layerArea = project.layers.reduce((sum, layer) => sum + layer.width * layer.height, 0);
  return Math.max(layerArea * 1.15, project.width * project.height * 0.35);
}

function preferredMaterialCategory(project: CricutProject | null): MaterialDealProduct["category"] {
  const text = `${project?.prompt ?? ""} ${project?.layers.map((layer) => layer.material).join(" ") ?? ""}`.toLowerCase();
  if (text.includes("shirt") || text.includes("apparel") || text.includes("htv") || text.includes("heat transfer")) {
    return "Heat Transfer Vinyl";
  }
  if (text.includes("stencil") || text.includes("painted") || text.includes("wood") || text.includes("mdf")) {
    return "Stencil Vinyl";
  }
  return "Permanent Vinyl";
}

function recommendedMaterials(project: CricutProject | null): MaterialDealProduct[] {
  const primaryCategory = preferredMaterialCategory(project);
  const primary = materialCatalog.filter((product) => product.category === primaryCategory);
  const transferTape = primaryCategory === "Heat Transfer Vinyl" ? [] : materialCatalog.filter((product) => product.category === "Transfer Tape");
  return [...primary, ...transferTape].sort((a, b) => productPrice(a) - productPrice(b));
}

function productQuantity(product: MaterialDealProduct, requiredArea: number): number {
  return Math.max(1, Math.ceil(requiredArea / Math.max(productCoverage(product), 1)));
}

function shoppingListText(project: CricutProject | null, products: MaterialDealProduct[], requiredArea: number): string {
  const title = project?.title ?? "ProjectCraft Pro material project";
  const rows = products.map((product) => {
    const quantity = productQuantity(product, requiredArea);
    return `- ${quantity} x ${product.name} (${product.color}) from ${product.retailer}: ${currency(productPrice(product) * quantity)} - ${priceFreshness(product)}`;
  });

  return [
    `ProjectCraft Pro Shopping List: ${title}`,
    pricingDisclaimer,
    catalogDisclaimer,
    retailerDisclaimer,
    affiliateDisclosure,
    "",
    ...(rows.length > 0 ? rows : ["No approved catalog products are available yet. Add manual catalog entries or connect approved product feeds before purchasing materials."])
  ].join("\n");
}

function App() {
  const [section, setSection] = useState<Section>("dashboard");
  const [state, setState] = useState<AppState>(emptyState);
  const [prompt, setPrompt] = useState(emptyPrompt);
  const [projectTab, setProjectTab] = useState<ProjectTab>("Plan");
  const [status, setStatus] = useState("Loading local workspace...");
  const [saving, setSaving] = useState(false);

  useEffect(() => {
    let isMounted = true;
    loadState()
      .then((loadedState) => {
        if (!isMounted) return;
        setState(loadedState);
        if (loadedState.currentProject) {
          setPrompt(loadedState.currentProject.prompt);
        }
        setStatus("Mobile workspace ready.");
      })
      .catch(() => {
        if (!isMounted) return;
        setStatus("Starting with a clean workspace because saved data could not be loaded.");
      });

    return () => {
      isMounted = false;
    };
  }, []);

  const totals = useMemo(() => {
    const revenue = state.orders.reduce((sum, order) => sum + order.total, 0);
    const paid = state.orders.reduce((sum, order) => sum + order.paid, 0);
    const productById = new Map(state.products.map((product) => [product.id, product]));
    const estimatedCost = state.orders.reduce((sum, order) => {
      const product = productById.get(order.productId);
      if (!product) return sum;
      return sum + product.materialCost * order.quantity + (product.laborMinutes / 60) * 32;
    }, 0);
    const profit = revenue - estimatedCost;
    return {
      revenue,
      paid,
      outstanding: revenue - paid,
      profit,
      margin: revenue > 0 ? (profit / revenue) * 100 : 0,
      activeOrders: state.orders.filter((order) => order.status !== "Delivered").length,
      lowStock: state.inventory.filter((material) => material.onHand - material.reserved <= material.reorderPoint).length
    };
  }, [state]);

  async function persist(nextState: AppState, message: string) {
    setSaving(true);
    setState(nextState);
    const savedState = await saveState(nextState);
    setState(savedState);
    setStatus(message);
    setSaving(false);
  }

  function buildProject() {
    if (!prompt.trim()) {
      setStatus("Paste a project prompt before building.");
      return;
    }

    const project = buildProjectFromPrompt(prompt);
    void persist({ ...state, currentProject: project }, `Built ${project.title} with ${project.panels.length} tiled panels.`);
    setProjectTab("Plan");
    setSection("projectBuilder");
  }

  function downloadMaster(project: CricutProject) {
    downloadTextFile(`${project.title}.svg`, project.svg, "image/svg+xml");
    setStatus("Downloaded master SVG. Use it as a reference before cutting tiled panels.");
  }

  function downloadManifest(project: CricutProject) {
    downloadTextFile(`${project.title} Cricut Handoff.txt`, handoffManifest(project));
    setStatus("Downloaded Cricut handoff manifest.");
  }

  function downloadPanel(panel: CricutPanel) {
    downloadTextFile(`${panel.id}.svg`, panel.svg, "image/svg+xml");
    setStatus(`Downloaded ${panel.id}.svg.`);
  }

  function updateMarketingFromProject(project: CricutProject) {
    void persist(
      {
        ...state,
        marketingDraft: {
          listingTitle: `${project.title} - layered wall display`,
          shortDescription: `A ${project.width} in x ${project.height} in layered SVG wall sign with labeled Cricut panels and registration guidance.`,
          socialPost: "A blank wall can become a clean branded focal point with a layered Cricut-ready wall logo package.",
          productionNote: `Cut ${project.panels.length} tiled panels by layer, keep registration squares in place, and install from the bridge baseline upward.`
        }
      },
      "Marketing draft updated from the current Cricut project."
    );
  }

  const currentProject = state.currentProject;

  return (
    <div className="app-shell">
      <aside className="sidebar">
        <div className="brand-block">
          <img className="brand-mark" src="/icons/icon-128.png" alt="" />
          <div>
            <h1>ProjectCraft Pro</h1>
            <p>Plan. Cut. Create. Profit.</p>
          </div>
        </div>
        <nav className="nav-list" aria-label="Main sections">
          {navItems.map((item) => (
            <button
              key={item.id}
              className={section === item.id ? "nav-item active" : "nav-item"}
              onClick={() => setSection(item.id)}
              type="button"
              title={item.label}
            >
              <span className="material-symbol">{item.icon}</span>
              <span>{item.label}</span>
            </button>
          ))}
        </nav>
        <div className="legal-footnote">
          <strong>ProjectCraft Pro</strong>
          <span>{copyrightNotice}</span>
        </div>
      </aside>

      <main className="workspace">
        <header className="topbar">
          <div>
            <p className="eyebrow">Mobile app port</p>
            <h2>{navItems.find((item) => item.id === section)?.label}</h2>
          </div>
          <div className="topbar-actions">
            <span className={saving ? "save-chip saving" : "save-chip"}>
              {saving ? "Saving" : `Saved ${new Date(state.lastSavedAt).toLocaleTimeString([], { hour: "numeric", minute: "2-digit" })}`}
            </span>
            <button
              className="ghost-button"
              type="button"
              onClick={() => {
                const freshState = resetState();
                setPrompt(emptyPrompt);
                void persist(freshState, "Workspace cleared.");
              }}
            >
              Clear Workspace
            </button>
          </div>
        </header>

        <section className="status-strip">{status}</section>

        {section === "dashboard" && (
          <DashboardView state={state} totals={totals} openProjectBuilder={() => setSection("projectBuilder")} />
        )}
        {section === "projectBuilder" && (
          <ProjectBuilderView
            prompt={prompt}
            setPrompt={setPrompt}
            project={currentProject}
            projectTab={projectTab}
            setProjectTab={setProjectTab}
            buildProject={buildProject}
            downloadMaster={downloadMaster}
            downloadManifest={downloadManifest}
            downloadPanel={downloadPanel}
          />
        )}
        {section === "cricutExport" && (
          <CricutExportView
            project={currentProject}
            downloadMaster={downloadMaster}
            downloadManifest={downloadManifest}
            downloadPanel={downloadPanel}
            openBuilder={() => setSection("projectBuilder")}
          />
        )}
        {section === "materialsDeals" && <MaterialsDealsView project={currentProject} inventory={state.inventory} />}
        {section === "customers" && <CustomersView state={state} />}
        {section === "orders" && <OrdersView state={state} />}
        {section === "products" && <ProductsView state={state} />}
        {section === "templates" && <TemplatesView state={state} />}
        {section === "inventory" && <InventoryView state={state} />}
        {section === "pricing" && <PricingView state={state} />}
        {section === "marketing" && (
          <MarketingView state={state} project={currentProject} updateFromProject={updateMarketingFromProject} />
        )}
        {section === "license" && <LicenseView />}
        {section === "release" && <ReleaseView />}
      </main>
    </div>
  );
}

function DashboardView({
  state,
  totals,
  openProjectBuilder
}: {
  state: AppState;
  totals: {
    revenue: number;
    paid: number;
    outstanding: number;
    profit: number;
    margin: number;
    activeOrders: number;
    lowStock: number;
  };
  openProjectBuilder: () => void;
}) {
  return (
    <div className="view-stack">
      <div className="metric-grid">
        <Metric title="Revenue" value={currency(totals.revenue)} detail="Open pipeline" />
        <Metric title="Gross Profit" value={currency(totals.profit)} detail={`${number(totals.margin)}% margin`} />
        <Metric title="Outstanding" value={currency(totals.outstanding)} detail="Unpaid balance" />
        <Metric title="Active Orders" value={String(totals.activeOrders)} detail={`${totals.lowStock} low stock alerts`} />
      </div>

      <div className="split-grid">
        <Panel title="Production Board" action={<button type="button" onClick={openProjectBuilder}>Build Project</button>}>
          {state.orders.length === 0 ? (
            <EmptyState text="No orders yet." />
          ) : (
            <div className="timeline-list">
              {state.orders.map((order) => (
                <div key={order.id} className="timeline-row">
                  <span className={`status-dot ${order.status.toLowerCase().replaceAll(" ", "-")}`} />
                  <div>
                    <strong>{order.orderNumber}</strong>
                    <p>{order.status} - Due {order.dueDate}</p>
                  </div>
                  <b>{currency(order.total)}</b>
                </div>
              ))}
            </div>
          )}
        </Panel>
        <Panel title="Most Profitable Products">
          {state.products.length === 0 ? (
            <EmptyState text="No products yet." />
          ) : (
            <div className="product-profit-list">
              {[...state.products]
                .sort((a, b) => b.targetMargin - a.targetMargin)
                .map((product) => (
                  <div key={product.id} className="profit-row">
                    <span>{product.name}</span>
                    <strong>{number(product.targetMargin)}%</strong>
                  </div>
                ))}
            </div>
          )}
        </Panel>
      </div>
    </div>
  );
}

function ProjectBuilderView({
  prompt,
  setPrompt,
  project,
  projectTab,
  setProjectTab,
  buildProject,
  downloadMaster,
  downloadManifest,
  downloadPanel
}: {
  prompt: string;
  setPrompt: (value: string) => void;
  project: CricutProject | null;
  projectTab: ProjectTab;
  setProjectTab: (value: ProjectTab) => void;
  buildProject: () => void;
  downloadMaster: (project: CricutProject) => void;
  downloadManifest: (project: CricutProject) => void;
  downloadPanel: (panel: CricutPanel) => void;
}) {
  return (
    <div className="builder-layout">
      <Panel title="Paste Prompt">
        <textarea
          className="prompt-box"
          value={prompt}
          onChange={(event) => setPrompt(event.target.value)}
          placeholder="Paste a customer project prompt, SVG brief, or Cricut cut-template request."
        />
        <div className="button-row">
          <button type="button" className="primary-button" onClick={buildProject}>Build Local Project</button>
        </div>
      </Panel>

      <Panel
        title={project ? project.title : "No Project Built"}
        action={
          project ? (
            <div className="button-row compact">
              <button type="button" onClick={() => downloadManifest(project)}>Manifest</button>
              <button type="button" onClick={() => downloadMaster(project)}>Master SVG</button>
            </div>
          ) : null
        }
      >
        {!project && <EmptyState text="Paste a Cricut project prompt and build the local mobile project packet." />}
        {project && (
          <>
            <div className="project-summary">
              <Metric title="Finished Size" value={`${project.width} in x ${project.height} in`} detail="Wall display" />
              <Metric title="Layers" value={String(project.layers.length)} detail="Separate colors" />
              <Metric title="Panels" value={String(project.panels.length)} detail="12 in mat workflow" />
            </div>
            <div className="tabs">
              {projectTabs.map((tab) => (
                <button key={tab} className={projectTab === tab ? "tab active" : "tab"} onClick={() => setProjectTab(tab)} type="button">
                  {tab}
                </button>
              ))}
            </div>
            {projectTab === "Plan" && <pre className="output-block">{project.projectPlan}</pre>}
            {projectTab === "SVG" && (
              <div className="svg-preview-wrap">
                <div className="svg-preview" dangerouslySetInnerHTML={{ __html: project.svg }} />
              </div>
            )}
            {projectTab === "Panels" && (
              <PanelTable panels={project.panels.slice(0, 12)} downloadPanel={downloadPanel} />
            )}
            {projectTab === "Assembly" && <pre className="output-block">{project.assemblyGuide}</pre>}
          </>
        )}
      </Panel>
    </div>
  );
}

function CricutExportView({
  project,
  downloadMaster,
  downloadManifest,
  downloadPanel,
  openBuilder
}: {
  project: CricutProject | null;
  downloadMaster: (project: CricutProject) => void;
  downloadManifest: (project: CricutProject) => void;
  downloadPanel: (panel: CricutPanel) => void;
  openBuilder: () => void;
}) {
  if (!project) {
    return (
      <Panel title="Cricut Export Center">
        <EmptyState text="Build a project first, then export master and tile SVG files for Cricut Design Space." />
        <button type="button" onClick={openBuilder}>Open Project Builder</button>
      </Panel>
    );
  }

  return (
    <div className="view-stack">
      <Panel
        title="Cricut Handoff"
        action={
          <div className="button-row compact">
            <button type="button" onClick={() => downloadManifest(project)}>Download Manifest</button>
            <button type="button" onClick={() => downloadMaster(project)}>Download Master SVG</button>
          </div>
        }
      >
        <div className="warning-box">
          Use the master SVG as a reference. For the real full-size wall sign, upload and cut tiled panel SVGs one at a time by layer.
          <p className="disclaimer-text">{cricutDisclaimer}</p>
        </div>
        <div className="layer-grid">
          {project.layers.map((layer) => (
            <div className="layer-card" key={layer.id}>
              <strong>{layer.name}</strong>
              <p>{layer.material}</p>
              <span>{layer.width} in x {layer.height} in</span>
            </div>
          ))}
        </div>
      </Panel>
      <Panel title={`Tiled Panels (${project.panels.length})`}>
        <PanelTable panels={project.panels} downloadPanel={downloadPanel} />
      </Panel>
    </div>
  );
}

function MaterialsDealsView({ project, inventory }: { project: CricutProject | null; inventory: InventoryMaterial[] }) {
  const [tab, setTab] = useState<MaterialDealTab>("Materials");
  const products = useMemo(() => recommendedMaterials(project), [project]);
  const requiredArea = useMemo(() => projectArea(project), [project]);
  const comparisonProducts = useMemo(
    () => [...materialCatalog].sort((a, b) => productPrice(a) - productPrice(b)),
    []
  );
  const projectCost = products.reduce((sum, product) => {
    return sum + productPrice(product) * productQuantity(product, requiredArea);
  }, 0);
  const retailSavings = products.reduce((sum, product) => {
    const quantity = productQuantity(product, requiredArea);
    return sum + Math.max(product.regularPrice - productPrice(product), 0) * quantity;
  }, 0);
  const lowStockMaterials = inventory.filter((material) => material.onHand - material.reserved <= material.reorderPoint);

  function exportShoppingList() {
    downloadTextFile("ProjectCraft-Pro-Shopping-List.txt", shoppingListText(project, products, requiredArea), "text/plain");
  }

  return (
    <div className="view-stack">
      <Panel
        title="Material Recommendations"
        action={<button type="button" onClick={exportShoppingList}>Export Shopping List</button>}
      >
        <div className="warning-box">
          {pricingDisclaimer}
          <p className="disclaimer-text">{catalogDisclaimer}</p>
          <p className="disclaimer-text">{retailerDisclaimer}</p>
        </div>
        <div className="deal-tabs" role="tablist" aria-label="Material shopping sections">
          {materialDealTabs.map((item) => (
            <button
              key={item}
              className={tab === item ? "tab active" : "tab"}
              onClick={() => setTab(item)}
              type="button"
            >
              {item}
            </button>
          ))}
        </div>

        {tab === "Materials" && (
          products.length === 0 ? (
            <EmptyState text="No material catalog products yet. Add approved product feeds or manual catalog entries before showing material recommendations." />
          ) : (
            <div className="deal-card-grid">
              {products.map((product) => (
                <div className="deal-card" key={product.id}>
                  <div className="deal-card-header">
                    <strong>{product.name}</strong>
                    <span>{currency(productPrice(product))}</span>
                  </div>
                  <p>{product.notes}</p>
                  <div className="badge-row">
                    <span className="badge">{product.category}</span>
                    <span className="badge">{product.color}</span>
                    <span className="badge">{product.quality}</span>
                    <span className="badge warning">{product.dataSource}</span>
                  </div>
                  <small className="freshness-note">{priceFreshness(product)}</small>
                </div>
              ))}
            </div>
          )
        )}

        {tab === "Where to Buy" && (
          <DataTable
            headers={["Retailer", "Product", "Availability", "Source", "Action"]}
            rows={products.map((product) => [
              product.retailer,
              product.name,
              product.inventory,
              product.dataSource,
              product.productUrl ? "Open retailer site" : "Add retailer URL"
            ])}
          />
        )}

        {tab === "Price Comparison" && (
          <DataTable
            headers={["Product", "Retailer", "Regular", "Current", "Savings", "Freshness"]}
            rows={comparisonProducts.map((product) => [
              product.name,
              product.retailer,
              currency(product.regularPrice),
              currency(productPrice(product)),
              product.salePrice ? currency(product.regularPrice - product.salePrice) : "-",
              priceFreshness(product)
            ])}
          />
        )}

        {tab === "Shopping List" && (
          <div className="view-stack">
            <DataTable
              headers={["Item", "Qty", "Estimate", "Retailer", "Notes"]}
              rows={products.map((product) => {
                const quantity = productQuantity(product, requiredArea);
                return [
                  `${product.name} - ${product.color}`,
                  String(quantity),
                  currency(productPrice(product) * quantity),
                  product.retailer,
                  priceFreshness(product)
                ];
              })}
            />
            <div className="warning-box">
              {affiliateDisclosure}
            </div>
          </div>
        )}

        {tab === "Project Cost" && (
          <div className="metric-grid">
            <Metric title="Material Area" value={`${number(requiredArea)} sq in`} detail="Includes waste allowance" />
            <Metric title="Estimated Cost" value={currency(projectCost)} detail="Approved catalog pricing" />
            <Metric title="Sale Savings" value={currency(retailSavings)} detail="Only when sale price is entered" />
            <Metric title="Local Alerts" value={String(lowStockMaterials.length)} detail="From current inventory records" />
          </div>
        )}

        {tab === "Alternatives" && (
          comparisonProducts.length === 0 ? (
            <EmptyState text="No catalog alternatives yet. Add approved materials in Admin Catalog to compare options." />
          ) : (
            <div className="deal-card-grid">
              {comparisonProducts.slice(0, 6).map((product) => (
                <div className="deal-card" key={product.id}>
                  <div className="deal-card-header">
                    <strong>{product.quality} Alternative</strong>
                    <span>{currency(productPrice(product))}</span>
                  </div>
                  <p>{product.name} from {product.retailer}. {product.compatibility}</p>
                  <div className="badge-row">
                    <span className="badge">{product.category}</span>
                    <span className="badge">{product.inventory}</span>
                  </div>
                </div>
              ))}
            </div>
          )
        )}

        {tab === "Sale Alerts" && (
          <DataTable
            headers={["Rule", "Status", "Privacy"]}
            rows={[
              ["Target savings threshold", "Ready for user preference", "Stored locally"],
              ["Preferred retailers", "Ready for admin catalog", "No login or retailer account stored"],
              ["ZIP prefix for nearby stores", "Optional", "Do not store full address"],
              ["Live notifications", "Pending", "Requires approved API/feed and notification permission"]
            ]}
          />
        )}

        {tab === "Admin Catalog" && (
          <DataTable
            headers={["Catalog Area", "Current Status", "Commercial Requirement"]}
            rows={[
              ["Retailer adapters", "No placeholder adapters bundled", "Add approved retailer APIs or product feeds"],
              ["Manual prices", "Supported in native app", "Review timestamp and source before publish"],
              ["Affiliate links", "Disclosure prepared", "Configure approved affiliate accounts before enabling"],
              ["Scraping", "Not used", "Use written retailer permission, API, feed, or manual entry"]
            ]}
          />
        )}
      </Panel>
    </div>
  );
}

function CustomersView({ state }: { state: AppState }) {
  return (
    <Panel title="Customers">
      <DataTable
        headers={["Name", "Company", "Tags", "Lifetime Value"]}
        rows={state.customers.map((customer) => [
          customer.name,
          customer.company,
          customer.tags.join(", "),
          currency(customer.lifetimeValue)
        ])}
      />
    </Panel>
  );
}

function OrdersView({ state }: { state: AppState }) {
  const customerName = new Map(state.customers.map((customer) => [customer.id, customer.name]));
  return (
    <Panel title="Orders">
      <DataTable
        headers={["Order", "Customer", "Status", "Due", "Total", "Paid"]}
        rows={state.orders.map((order) => [
          order.orderNumber,
          customerName.get(order.customerId) ?? "Unknown",
          order.status,
          order.dueDate,
          currency(order.total),
          currency(order.paid)
        ])}
      />
    </Panel>
  );
}

function ProductsView({ state }: { state: AppState }) {
  return (
    <Panel title="Products">
      <DataTable
        headers={["Product", "Category", "Material", "Labor", "Retail", "Margin"]}
        rows={state.products.map((product) => [
          product.name,
          product.category,
          currency(product.materialCost),
          `${product.laborMinutes} min`,
          currency(product.retailPrice),
          `${product.targetMargin}%`
        ])}
      />
    </Panel>
  );
}

function TemplatesView({ state }: { state: AppState }) {
  return (
    <Panel title="Template Library">
      <DataTable
        headers={["Template", "Category", "Skill", "Price", "Margin"]}
        rows={state.templates.map((template) => [
          template.name,
          template.category,
          template.skill,
          currency(template.price),
          `${template.margin}%`
        ])}
      />
    </Panel>
  );
}

function InventoryView({ state }: { state: AppState }) {
  return (
    <Panel title="Inventory">
      <DataTable
        headers={["Material", "Supplier", "Color", "Available", "Reorder", "Unit Cost"]}
        rows={state.inventory.map((material) => [
          material.name,
          material.supplier,
          material.color,
          String(material.onHand - material.reserved),
          String(material.reorderPoint),
          currency(material.unitCost)
        ])}
      />
    </Panel>
  );
}

function PricingView({ state }: { state: AppState }) {
  const rows = state.products.map((product) => {
    const laborCost = (product.laborMinutes / 60) * 32;
    const totalCost = product.materialCost + laborCost;
    const profit = product.retailPrice - totalCost;
    const margin = product.retailPrice > 0 ? (profit / product.retailPrice) * 100 : 0;
    return [product.name, currency(totalCost), currency(product.retailPrice), currency(profit), `${number(margin)}%`];
  });

  return (
    <Panel title="Pricing and Profit">
      <DataTable headers={["Product", "Est. Cost", "Retail", "Gross Profit", "Gross Margin"]} rows={rows} />
    </Panel>
  );
}

function MarketingView({
  state,
  project,
  updateFromProject
}: {
  state: AppState;
  project: CricutProject | null;
  updateFromProject: (project: CricutProject) => void;
}) {
  return (
    <Panel
      title="Marketing Studio"
      action={project ? <button type="button" onClick={() => updateFromProject(project)}>Draft From Project</button> : null}
    >
      <div className="copy-grid">
        <CopyBlock label="Listing Title" value={state.marketingDraft.listingTitle} />
        <CopyBlock label="Short Description" value={state.marketingDraft.shortDescription} />
        <CopyBlock label="Social Post" value={state.marketingDraft.socialPost} />
        <CopyBlock label="Production Note" value={state.marketingDraft.productionNote} />
      </div>
    </Panel>
  );
}

function LicenseView() {
  return (
    <Panel title="License and Activation">
      <div className="release-grid">
        <Metric title="Product" value="ProjectCraft Pro" detail="$499 license" />
        <Metric title="Activation" value="Required" detail="License service pending" />
        <Metric title="Offline Grace" value="7 days" detail="License backend required" />
      </div>
      <div className="warning-box">
        This mobile app port preserves the same commercial boundary as the Mac preview: data stays viewable/exportable, but customer license activation requires the secure licensing service.
      </div>
    </Panel>
  );
}

function ReleaseView() {
  return (
    <Panel title="Mobile Store Release Readiness">
      <DataTable
        headers={["Area", "Status", "Next Step"]}
        rows={[
          ["Native wrappers", "Added", "Open iOS in Xcode and Android in Android Studio"],
          ["Local persistence", "Added", "Uses device WebView storage"],
          ["Cricut export", "Added", "Saves SVG/text files and opens native share sheet when available"],
          ["Apple App Store", "Pending", "Archive, sign, TestFlight, and App Review"],
          ["Google Play", "Pending", "Build signed AAB, internal test, and Play review"],
          ["Legal/release QA", "Pending", "Complete store privacy, screenshots, age rating, and policy forms"]
        ]}
      />
    </Panel>
  );
}

function Panel({
  title,
  action,
  children
}: {
  title: string;
  action?: React.ReactNode;
  children: React.ReactNode;
}) {
  return (
    <section className="panel">
      <div className="panel-header">
        <h3>{title}</h3>
        {action}
      </div>
      {children}
    </section>
  );
}

function Metric({ title, value, detail }: { title: string; value: string; detail: string }) {
  return (
    <div className="metric-card">
      <span>{title}</span>
      <strong>{value}</strong>
      <p>{detail}</p>
    </div>
  );
}

function DataTable({ headers, rows, emptyText = "No records yet." }: { headers: string[]; rows: string[][]; emptyText?: string }) {
  return (
    <div className="table-wrap">
      <table>
        <thead>
          <tr>
            {headers.map((header) => (
              <th key={header}>{header}</th>
            ))}
          </tr>
        </thead>
        <tbody>
          {rows.length === 0 ? (
            <tr>
              <td className="empty-table-cell" colSpan={headers.length}>{emptyText}</td>
            </tr>
          ) : (
            rows.map((row, index) => (
              <tr key={`${row[0]}-${index}`}>
                {row.map((cell, cellIndex) => (
                  <td key={`${cell}-${cellIndex}`}>{cell}</td>
                ))}
              </tr>
            ))
          )}
        </tbody>
      </table>
    </div>
  );
}

function PanelTable({ panels, downloadPanel }: { panels: CricutPanel[]; downloadPanel: (panel: CricutPanel) => void }) {
  return (
    <div className="table-wrap">
      <table>
        <thead>
          <tr>
            <th>Panel</th>
            <th>Layer</th>
            <th>Grid</th>
            <th>Size</th>
            <th>File</th>
          </tr>
        </thead>
        <tbody>
          {panels.map((panel) => (
            <tr key={panel.id}>
              <td>{panel.id}</td>
              <td>{panel.layerName}</td>
              <td>C{panel.column} R{panel.row}</td>
              <td>{panel.width} in x {panel.height} in</td>
              <td>
                <button type="button" onClick={() => downloadPanel(panel)}>Download</button>
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

function EmptyState({ text }: { text: string }) {
  return <div className="empty-state">{text}</div>;
}

function CopyBlock({ label, value }: { label: string; value: string }) {
  return (
    <div className="copy-block">
      <span>{label}</span>
      <p>{value || "Not drafted yet."}</p>
    </div>
  );
}

export default App;
