// Dashboard, asset cards, toolbar, banner, progress
const { useState: useStateD, useMemo } = React;

function ProgressCard({ total, read }) {
  const pct = Math.round((read / total) * 100);
  return (
    <div className="progress-card">
      <div className="text">
        <div className="head">Your reading progress</div>
        <div className="sub">{read} of {total} items completed &middot; {total - read} remaining</div>
      </div>
      <div className="progress-bar"><span style={{width: `${pct}%`}}/></div>
      <div className="pct">{pct}%</div>
    </div>
  );
}

function ActionBanner({ count, onView }) {
  if (!count) return null;
  return (
    <div className="banner">
      <div className="icon-box"><I.Alert/></div>
      <div className="text">
        <strong>{count} item{count === 1 ? "" : "s"} require your attention.</strong>{" "}
        <span className="muted">Mandatory reads &amp; forms with deadlines.</span>
      </div>
      <button className="ghost" onClick={onView}>Review now <I.Arrow/></button>
    </div>
  );
}

function Toolbar({ search, setSearch, sort, setSort, view, setView, count }) {
  return (
    <div className="toolbar">
      <div className="search">
        <I.Search/>
        <input
          placeholder="Search by title, category, type…"
          value={search}
          onChange={(e) => setSearch(e.target.value)}
        />
      </div>
      <select value={sort} onChange={e => setSort(e.target.value)}>
        <option value="recent">Sort: Recently updated</option>
        <option value="title">Sort: Title (A–Z)</option>
        <option value="due">Sort: Due date</option>
        <option value="status">Sort: Unread first</option>
      </select>
      <div className="viewtoggle">
        <button className={view === "grid" ? "active" : ""} onClick={() => setView("grid")} title="Grid view">
          <I.Grid/>
        </button>
        <button className={view === "list" ? "active" : ""} onClick={() => setView("list")} title="List view">
          <I.List/>
        </button>
      </div>
      <span className="muted" style={{marginLeft: 4}}>{count} result{count === 1 ? "" : "s"}</span>
    </div>
  );
}

function AssetCard({ asset, isRead, onOpen, onToggleRead, view, density }) {
  const TypeIcon = TYPE_ICONS[asset.type];
  const typeLabel = WITNESS_DATA.ASSET_TYPES[asset.type].label;
  const cat = WITNESS_DATA.CATEGORIES.find(c => c.id === asset.category)?.label;

  const dueText = asset.requiredBy
    ? new Date(asset.requiredBy).toLocaleDateString("en-GB", { day: "numeric", month: "short" })
    : null;

  if (view === "list") {
    return (
      <div className={`card row ${isRead ? "read" : ""}`} onClick={onOpen}>
        <div className="thumb" style={{width: 96}}>
          <TypeIcon width="22" height="22"/>
        </div>
        <div className="card-body">
          <div className="left">
            <h3>{asset.title}</h3>
            <div className="meta">
              <span>{typeLabel}</span>
              <span>·</span>
              <span>{cat}</span>
              {dueText && <><span>·</span><span>Due {dueText}</span></>}
              {asset.required && !isRead && <><span>·</span><span style={{color: 'var(--ink)'}}>Required</span></>}
            </div>
          </div>
          <button
            className="ghost"
            onClick={(e) => { e.stopPropagation(); onToggleRead(); }}
            title={isRead ? "Mark as unread" : "Mark as read"}
            style={{display: 'inline-flex', alignItems: 'center', gap: 6}}
          >
            {isRead ? <><I.CircleCheck/> Read</> : <><I.Circle/> Mark read</>}
          </button>
          <button className="primary" onClick={(e) => { e.stopPropagation(); onOpen(); }}>
            {WITNESS_DATA.ASSET_TYPES[asset.type].verb}
          </button>
        </div>
      </div>
    );
  }

  return (
    <div className={`card ${isRead ? "read" : ""}`} onClick={onOpen}>
      <div className="thumb">
        <span className="typebadge">
          <TypeIcon width="11" height="11" style={{verticalAlign: '-2px', marginRight: 4}}/>
          {typeLabel}
        </span>
        <span className="corner-status">
          {isRead ? (
            <span className="tag solid"><I.Check width="10" height="10"/> Read</span>
          ) : asset.required ? (
            <span className="tag dot">Required</span>
          ) : null}
        </span>
        <TypeIcon width="36" height="36" style={{opacity: 0.4}}/>
      </div>
      <div className="card-body">
        <h3>{asset.title}</h3>
        {density !== "compact" && <div className="desc">{asset.desc}</div>}
        <div className="meta">
          <span>{cat}</span>
          {dueText && <><span>·</span><span>Due {dueText}</span></>}
          {asset.duration && <><span>·</span><span>{asset.duration}</span></>}
          {asset.pages && <><span>·</span><span>{asset.pages} pp</span></>}
          {asset.fileExt && <><span>·</span><span>{asset.fileExt}</span></>}
        </div>
        <div className="cta-row" onClick={(e) => e.stopPropagation()}>
          <button className="primary" onClick={onOpen} style={{flex: 1, padding: '6px 10px', fontSize: 12}}>
            {WITNESS_DATA.ASSET_TYPES[asset.type].verb}
          </button>
          <button
            className="ghost"
            onClick={onToggleRead}
            title={isRead ? "Mark unread" : "Mark read"}
            style={{padding: '6px 10px', fontSize: 12, display: 'inline-flex', alignItems: 'center', gap: 4}}
          >
            {isRead ? <I.CircleCheck/> : <I.Circle/>}
          </button>
        </div>
      </div>
    </div>
  );
}

function CategorySidebar({ categories, current, onSelect, assets, readMap }) {
  const counts = useMemo(() => {
    const c = { all: assets.length };
    categories.forEach(cat => {
      if (cat.id === "all") return;
      c[cat.id] = assets.filter(a => a.category === cat.id).length;
    });
    return c;
  }, [assets, categories]);

  const requiredUnread = assets.filter(a => a.required && !readMap[a.id]).length;

  return (
    <aside className="sidebar">
      <h4>Filters</h4>
      <ul>
        {categories.map(c => (
          <li
            key={c.id}
            className={current === c.id ? "active" : ""}
            onClick={() => onSelect(c.id)}
          >
            <span>{c.label}</span>
            <span className="count">{counts[c.id] ?? 0}</span>
          </li>
        ))}
      </ul>

      <h4>Status</h4>
      <ul>
        <li onClick={() => onSelect("__required")} className={current === "__required" ? "active" : ""}>
          <span>Action required</span>
          <span className="count">{requiredUnread}</span>
        </li>
        <li onClick={() => onSelect("__unread")} className={current === "__unread" ? "active" : ""}>
          <span>Unread</span>
          <span className="count">{assets.filter(a => !readMap[a.id]).length}</span>
        </li>
        <li onClick={() => onSelect("__read")} className={current === "__read" ? "active" : ""}>
          <span>Read</span>
          <span className="count">{Object.keys(readMap).length}</span>
        </li>
      </ul>

      <h4>Help</h4>
      <ul>
        <li><span>How this works</span></li>
        <li><span>Contact Admin</span></li>
      </ul>
    </aside>
  );
}

function Dashboard({
  user, readMap, onOpen, onToggleRead, layout, density,
  loading, emptyDemo,
}) {
  const [search, setSearch] = useStateD("");
  const [sort, setSort] = useStateD("recent");
  const [view, setView] = useStateD("grid");
  const [category, setCategory] = useStateD("all");

  const allAssets = WITNESS_DATA.SEED_ASSETS;
  const cats = WITNESS_DATA.CATEGORIES;

  const filtered = useMemo(() => {
    let list = emptyDemo ? [] : allAssets;
    if (category === "__required") list = list.filter(a => a.required && !readMap[a.id]);
    else if (category === "__unread") list = list.filter(a => !readMap[a.id]);
    else if (category === "__read") list = list.filter(a => readMap[a.id]);
    else if (category !== "all") list = list.filter(a => a.category === category);

    if (search.trim()) {
      const q = search.trim().toLowerCase();
      list = list.filter(a =>
        a.title.toLowerCase().includes(q) ||
        a.desc.toLowerCase().includes(q) ||
        cats.find(c => c.id === a.category)?.label.toLowerCase().includes(q) ||
        WITNESS_DATA.ASSET_TYPES[a.type].label.toLowerCase().includes(q)
      );
    }

    const sorted = [...list].sort((a, b) => {
      if (sort === "title") return a.title.localeCompare(b.title);
      if (sort === "due") {
        const da = a.requiredBy ? new Date(a.requiredBy).getTime() : Infinity;
        const db = b.requiredBy ? new Date(b.requiredBy).getTime() : Infinity;
        return da - db;
      }
      if (sort === "status") return (readMap[a.id] ? 1 : 0) - (readMap[b.id] ? 1 : 0);
      return new Date(b.updated) - new Date(a.updated);
    });

    return sorted;
  }, [search, sort, category, readMap, emptyDemo]);

  const requiredCount = allAssets.filter(a => a.required && !readMap[a.id]).length;
  const recent = useMemo(() =>
    [...allAssets].sort((a,b) => new Date(b.updated) - new Date(a.updated)).slice(0, 4),
    []
  );

  const showHeroSections = !search && category === "all" && !emptyDemo;

  return (
    <div className="page">
      <CategorySidebar
        categories={cats}
        current={category}
        onSelect={setCategory}
        assets={allAssets}
        readMap={readMap}
      />
      <main className="main">
        <div className="page-header">
          <div>
            <h1>Welcome back, {user.firstName}</h1>
            <div className="sub">
              {new Date().toLocaleDateString("en-GB", { weekday: "long", day: "numeric", month: "long" })}
              {" · "} {allAssets.length} items in your library
            </div>
          </div>
          <div className="cta-row">
            <button className="ghost" onClick={() => setView(view === "grid" ? "list" : "grid")}>
              {view === "grid" ? <><I.List/> List view</> : <><I.Grid/> Grid view</>}
            </button>
          </div>
        </div>

        <ProgressCard
          total={allAssets.length}
          read={Object.keys(readMap).length}
        />

        <ActionBanner count={requiredCount} onView={() => setCategory("__required")}/>

        {/* Recently added — only on default view */}
        {showHeroSections && !loading && (
          <>
            <div className="section-head">
              <h2>Recently added</h2>
              <span className="count">Last 30 days</span>
            </div>
            <div className={`grid ${density}`} style={{marginBottom: 20}}>
              {recent.map(a => (
                <AssetCard
                  key={a.id}
                  asset={a}
                  isRead={!!readMap[a.id]}
                  onOpen={() => onOpen(a)}
                  onToggleRead={() => onToggleRead(a.id)}
                  view="grid"
                  density={density}
                />
              ))}
            </div>
          </>
        )}

        <div className="section-head">
          <h2>{
            category === "all" ? (showHeroSections ? "All items" : "Results") :
            category === "__required" ? "Action required" :
            category === "__unread" ? "Unread" :
            category === "__read" ? "Read" :
            cats.find(c => c.id === category)?.label
          }</h2>
          {!loading && <span className="count">{filtered.length} item{filtered.length === 1 ? "" : "s"}</span>}
        </div>

        <Toolbar
          search={search} setSearch={setSearch}
          sort={sort} setSort={setSort}
          view={view} setView={setView}
          count={filtered.length}
        />

        {loading ? (
          <div className={`grid ${density}`}>
            {Array.from({length: 8}).map((_, i) => (
              <div key={i} className="sk-card">
                <div className="thumb"/>
                <div className="body">
                  <div className="skeleton" style={{height: 14, width: '80%'}}/>
                  <div className="skeleton" style={{height: 10, width: '95%'}}/>
                  <div className="skeleton" style={{height: 10, width: '60%'}}/>
                </div>
              </div>
            ))}
          </div>
        ) : filtered.length === 0 ? (
          <div className="empty">
            <div className="glyph"><I.Search width="22" height="22"/></div>
            <h3>{emptyDemo ? "Nothing here yet" : "No items match"}</h3>
            <p>{emptyDemo ? "Items assigned to you will appear here" : "Try adjusting your search or category filter"}</p>
            {!emptyDemo && (
              <div style={{marginTop: 16}}>
                <button className="ghost" onClick={() => { setSearch(""); setCategory("all"); }}>
                  Clear filters
                </button>
              </div>
            )}
          </div>
        ) : (
          <div className={`grid ${view === "list" ? "list" : density}`}>
            {filtered.map(a => (
              <AssetCard
                key={a.id}
                asset={a}
                isRead={!!readMap[a.id]}
                onOpen={() => onOpen(a)}
                onToggleRead={() => onToggleRead(a.id)}
                view={view}
                density={density}
              />
            ))}
          </div>
        )}
      </main>
    </div>
  );
}

window.Dashboard = Dashboard;
