/* global React, Icon, IconBtn, useLiveQuery, db, relTime, PinButton */
/* Flashcard tool — entry point.
 * Holds the in-tool router and the collections dashboard. The detail
 * view, schema builder, card form, import wizard, and study session
 * each live in their own file and are mounted via window.* refs.
 */
const { useState, useEffect, useMemo, useCallback } = React;

// ----------------------------------------------------------------
// Tool-level router
// ----------------------------------------------------------------
// view shape:
//   { name: 'list' }
//   { name: 'detail',  collectionId }
//   { name: 'builder', collectionId | null }   // null = creating
//   { name: 'import',  collectionId }
//   { name: 'study',   collectionId }
//
// Stored in db.kv under 'flashcardLastView' so re-opening the tool
// drops you back where you were.

function useFlashcardRoute() {
  const [view, setView] = useState({ name: 'list' });
  useEffect(() => {
    db.kv.get('flashcardLastView').then(r => {
      if (r?.v && typeof r.v === 'object' && r.v.name) setView(r.v);
    });
  }, []);
  const go = useCallback((next) => {
    setView(next);
    db.kv.put({ k: 'flashcardLastView', v: next });
  }, []);
  return [view, go];
}

// ----------------------------------------------------------------
// Tweaks (per-tool preferences) — persisted in kv
// ----------------------------------------------------------------
const DEFAULT_FC_PREFS = {
  flipAnimation: 'flip',       // 'flip' | 'fade' | 'slide' | 'none'
  sessionLength: 20,           // 10 | 20 | 50 | -1 (unlimited)
  showDueCounts: true,
  keyboardLayout: '1-4',       // '1-4' | 'asdf' | 'hjkl'
  cardListDensity: 'comfy',    // 'comfy' | 'compact'
};
function useFcPrefs() {
  const [prefs, setPrefs] = useState(DEFAULT_FC_PREFS);
  useEffect(() => {
    const load = () => db.kv.get('flashcardPrefs').then(r => setPrefs({ ...DEFAULT_FC_PREFS, ...(r?.v || {}) }));
    load();
    const unsub = db.subscribe(({ store, value }) => {
      if (store === 'kv' && (!value || value.k === 'flashcardPrefs')) load();
    });
    return unsub;
  }, []);
  const update = (patch) => {
    setPrefs(prev => {
      const next = { ...prev, ...patch };
      db.kv.put({ k: 'flashcardPrefs', v: next });
      return next;
    });
  };
  return [prefs, update];
}
window.useFcPrefs = useFcPrefs;
window.DEFAULT_FC_PREFS = DEFAULT_FC_PREFS;

// ----------------------------------------------------------------
// Main tool
// ----------------------------------------------------------------
function FlashcardTool() {
  const [view, go] = useFlashcardRoute();
  const [prefs] = useFcPrefs();
  const data = useLiveQuery(['flashcardCollections', 'flashcardCards']) || {};
  const collections = data.flashcardCollections || [];
  const cards = data.flashcardCards || [];

  // If the saved view points at a collection that no longer exists, recover gracefully.
  useEffect(() => {
    if (!data.flashcardCollections) return;
    if (view.collectionId && !collections.find(c => c.id === view.collectionId)) {
      go({ name: 'list' });
    }
  }, [view, collections, data.flashcardCollections]);

  if (!data.flashcardCollections) {
    return <div className="fc"><div className="fc-empty" style={{ minHeight: '60vh' }}><div className="icon-wrap"><Icon name="hourglass_empty" /></div></div></div>;
  }

  const currentCollection = view.collectionId ? collections.find(c => c.id === view.collectionId) : null;
  const cardsForCurrent = currentCollection ? cards.filter(c => c.collectionId === currentCollection.id) : [];

  let body;
  if (view.name === 'builder') {
    body = <window.FlashcardBuilder
      collection={currentCollection}
      cardsCount={cardsForCurrent.length}
      onCancel={() => go(currentCollection ? { name: 'detail', collectionId: currentCollection.id } : { name: 'list' })}
      onSaved={(coll) => go({ name: 'detail', collectionId: coll.id })}
    />;
  } else if (view.name === 'import' && currentCollection) {
    body = <window.FlashcardImport
      collection={currentCollection}
      onDone={() => go({ name: 'detail', collectionId: currentCollection.id })}
    />;
  } else if (view.name === 'study' && currentCollection) {
    body = <window.FlashcardStudy
      collection={currentCollection}
      cards={cardsForCurrent}
      prefs={prefs}
      onExit={() => go({ name: 'detail', collectionId: currentCollection.id })}
    />;
  } else if (view.name === 'detail' && currentCollection) {
    body = <window.FlashcardDetail
      collection={currentCollection}
      cards={cardsForCurrent}
      prefs={prefs}
      onBack={() => go({ name: 'list' })}
      onEditSchema={() => go({ name: 'builder', collectionId: currentCollection.id })}
      onImport={() => go({ name: 'import', collectionId: currentCollection.id })}
      onStudy={() => go({ name: 'study', collectionId: currentCollection.id })}
    />;
  } else {
    body = <CollectionDashboard
      collections={collections}
      allCards={cards}
      prefs={prefs}
      onOpen={(c) => go({ name: 'detail', collectionId: c.id })}
      onStudy={(c) => go({ name: 'study', collectionId: c.id })}
      onNew={() => go({ name: 'builder', collectionId: null })}
    />;
  }

  return <div className="fc">{body}</div>;
}

window.FlashcardTool = FlashcardTool;

// ----------------------------------------------------------------
// Settings panel — rendered inside Settings → Tools → Flashcards
// Acts as the "Tweaks" surface for this tool.
// ----------------------------------------------------------------
function FlashcardSettings() {
  const [prefs, update] = useFcPrefs();

  const Row = ({ title, sub, children }) => (
    <div style={{
      display: 'flex', justifyContent: 'space-between', alignItems: 'center',
      gap: 12, padding: '10px 0', borderBottom: '1px solid var(--color-border)', flexWrap: 'wrap',
    }}>
      <div style={{ flex: 1, minWidth: 180 }}>
        <div style={{ color: 'var(--text-hi)', fontSize: 13, fontWeight: 500 }}>{title}</div>
        <div style={{ color: 'var(--text-muted)', fontSize: 11, marginTop: 2 }}>{sub}</div>
      </div>
      <div>{children}</div>
    </div>
  );

  const Segmented = ({ value, onChange, options }) => (
    <div style={{ display: 'flex', gap: 2, padding: 2, background: 'var(--color-surface)', border: '1px solid var(--color-border)', borderRadius: 8 }}>
      {options.map(o => (
        <button
          key={o.value}
          onClick={() => onChange(o.value)}
          style={{
            background: value === o.value ? 'var(--color-primary)' : 'transparent',
            color: value === o.value ? 'white' : 'var(--text-md)',
            border: 0, padding: '5px 10px', borderRadius: 6,
            cursor: 'pointer', fontSize: 11, fontFamily: 'inherit', fontWeight: 500,
          }}
        >{o.label}</button>
      ))}
    </div>
  );

  return (
    <div style={{ paddingTop: 8 }}>
      <Row title="Card flip animation" sub="How the answer is revealed during review.">
        <Segmented
          value={prefs.flipAnimation}
          onChange={v => update({ flipAnimation: v })}
          options={[
            { value: 'flip',  label: '3D flip' },
            { value: 'fade',  label: 'Fade' },
            { value: 'slide', label: 'Slide' },
            { value: 'none',  label: 'None' },
          ]}
        />
      </Row>
      <Row title="Session length" sub="Maximum cards shown in a single review session.">
        <Segmented
          value={prefs.sessionLength}
          onChange={v => update({ sessionLength: v })}
          options={[
            { value: 10, label: '10' },
            { value: 20, label: '20' },
            { value: 50, label: '50' },
            { value: -1, label: 'No limit' },
          ]}
        />
      </Row>
      <Row title="Keyboard shortcuts" sub="Keys used to rate cards in review mode.">
        <Segmented
          value={prefs.keyboardLayout}
          onChange={v => update({ keyboardLayout: v })}
          options={[
            { value: '1-4',  label: '1 – 4' },
            { value: 'asdf', label: 'a s d f' },
            { value: 'hjkl', label: 'h j k l' },
          ]}
        />
      </Row>
      <Row title="Due-count chips" sub="Show or hide the orange 'X due' chip on collection cards.">
        <label style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 12, cursor: 'pointer' }}>
          <input
            type="checkbox"
            checked={prefs.showDueCounts}
            onChange={e => update({ showDueCounts: e.target.checked })}
            style={{ accentColor: 'var(--color-primary)', width: 16, height: 16 }}
          />
          {prefs.showDueCounts ? 'Visible' : 'Hidden'}
        </label>
      </Row>
      <Row title="Card list density" sub="How tightly the card table packs in collection detail.">
        <Segmented
          value={prefs.cardListDensity}
          onChange={v => update({ cardListDensity: v })}
          options={[
            { value: 'comfy',   label: 'Comfortable' },
            { value: 'compact', label: 'Compact' },
          ]}
        />
      </Row>
    </div>
  );
}

window.toolSettingsRegistry = window.toolSettingsRegistry || {};
window.toolSettingsRegistry.flashcard = FlashcardSettings;

// ----------------------------------------------------------------
// Dashboard — list of collections + overview stats
// ----------------------------------------------------------------
function CollectionDashboard({ collections, allCards, prefs, onOpen, onStudy, onNew }) {
  const { dueStats } = window.flashcards;
  const [q, setQ] = useState('');
  const [showArchived, setShowArchived] = useState(false);
  const [sort, setSort] = useState('recent'); // 'recent' | 'name' | 'size'

  const byCollection = useMemo(() => {
    const map = new Map();
    for (const card of allCards) {
      if (!map.has(card.collectionId)) map.set(card.collectionId, []);
      map.get(card.collectionId).push(card);
    }
    return map;
  }, [allCards]);

  const stats = useMemo(() => {
    const active = collections.filter(c => !c.archived);
    const totalCards = allCards.length;
    let totalDue = 0;
    for (const c of allCards) if (window.flashcards.isDue(c)) totalDue++;
    return { collections: active.length, totalCards, totalDue };
  }, [collections, allCards]);

  const visible = useMemo(() => {
    let list = collections.filter(c => (showArchived ? true : !c.archived));
    if (q.trim()) {
      const needle = q.trim().toLowerCase();
      list = list.filter(c =>
        (c.name || '').toLowerCase().includes(needle) ||
        (c.description || '').toLowerCase().includes(needle) ||
        (c.srcLang || '').toLowerCase().includes(needle) ||
        (c.tgtLang || '').toLowerCase().includes(needle));
    }
    if (sort === 'recent') list = [...list].sort((a, b) => (b.updatedAt || 0) - (a.updatedAt || 0));
    if (sort === 'name')   list = [...list].sort((a, b) => (a.name || '').localeCompare(b.name || ''));
    if (sort === 'size')   list = [...list].sort((a, b) => (byCollection.get(b.id)?.length || 0) - (byCollection.get(a.id)?.length || 0));
    return list;
  }, [collections, q, showArchived, sort, byCollection]);

  if (collections.length === 0) {
    return (
      <div className="fc-dash">
        <div className="fc-empty" style={{ minHeight: '50vh' }}>
          <div className="icon-wrap"><Icon name="style" /></div>
          <h3>No collections yet</h3>
          <p>Collections group cards that share the same field structure. Make one to start adding flashcards.</p>
          <div className="row">
            <button className="lh-btn primary" onClick={onNew}>
              <Icon name="add" />Create your first collection
            </button>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="fc-dash">
      <div className="fc-dash-head">
        <div>
          <h2>Flashcards</h2>
          <p>Spaced-repetition study with custom-schema cards.</p>
        </div>
        <div className="fc-dash-actions">
          <button className="lh-btn primary" onClick={onNew}>
            <Icon name="add" />New collection
          </button>
        </div>
      </div>

      <div className="fc-dash-stats">
        <div className={`fc-statcard ${stats.totalDue > 0 ? 'is-due' : ''}`}>
          <Icon name="event_available" />
          <div>
            <div className="v">{stats.totalDue}</div>
            <div className="l">Due today</div>
          </div>
        </div>
        <div className="fc-statcard">
          <Icon name="style" />
          <div>
            <div className="v">{stats.collections}</div>
            <div className="l">Collections</div>
          </div>
        </div>
        <div className="fc-statcard">
          <Icon name="layers" />
          <div>
            <div className="v">{stats.totalCards}</div>
            <div className="l">Total cards</div>
          </div>
        </div>
        <div className="fc-statcard">
          <Icon name="local_fire_department" />
          <div>
            <div className="v">{stats.totalCards > 0 ? Math.round((1 - stats.totalDue / Math.max(1, stats.totalCards)) * 100) : 0}%</div>
            <div className="l">Retention buffer</div>
          </div>
        </div>
      </div>

      <div className="fc-dash-filter">
        <div className="fc-search">
          <Icon name="search" />
          <input
            placeholder="Search collections…"
            value={q}
            onChange={e => setQ(e.target.value)}
          />
        </div>
        <select className="fc-select" style={{ width: 160 }} value={sort} onChange={e => setSort(e.target.value)}>
          <option value="recent">Recently used</option>
          <option value="name">Name (A–Z)</option>
          <option value="size">Most cards</option>
        </select>
        <button
          className={`lh-btn ${showArchived ? 'primary' : 'ghost'}`}
          onClick={() => setShowArchived(s => !s)}
        >
          <Icon name="archive" />{showArchived ? 'Hiding archive' : 'Show archived'}
        </button>
      </div>

      {visible.length === 0 ? (
        <div className="fc-empty">
          <div className="icon-wrap"><Icon name="search_off" /></div>
          <h3>No matches</h3>
          <p>Try a different search or clear the filter.</p>
        </div>
      ) : (
        <div className="fc-grid">
          {visible.map(c => {
            const list = byCollection.get(c.id) || [];
            const ds = dueStats(list);
            return (
              <button key={c.id} className={`fc-coll-card ${c.archived ? 'is-archived' : ''}`} onClick={() => onOpen(c)}>
                <div className="fc-cc-pin" onClick={(e) => e.stopPropagation()}>
                  <PinButton type="flashcard" id={c.id} />
                </div>
                <div className="fc-cc-head">
                  <div className="fc-cc-icon"><Icon name="style" /></div>
                  <div style={{ minWidth: 0 }}>
                    <div className="fc-cc-title">{c.name || 'Untitled'}</div>
                    {(c.srcLang || c.tgtLang) && (
                      <div className="fc-cc-sub">{c.srcLang || '?'} → {c.tgtLang || '?'}</div>
                    )}
                  </div>
                </div>
                <div className="fc-cc-desc">{c.description || <span style={{ color: 'var(--text-faint)' }}>No description</span>}</div>
                <div className="fc-cc-meta">
                  <span><b>{ds.total}</b> card{ds.total === 1 ? '' : 's'}</span>
                  {prefs.showDueCounts && (
                    <span className={`fc-cc-due ${ds.due === 0 ? 'is-zero' : ''}`}>
                      {ds.due === 0 ? 'Nothing due' : `${ds.due} due`}
                    </span>
                  )}
                  <span style={{ marginLeft: 'auto' }}>
                    {c.lastStudiedAt ? relTime(c.lastStudiedAt) : 'Not studied'}
                  </span>
                </div>
                {ds.due > 0 && !c.archived && (
                  <button
                    className="lh-btn primary"
                    style={{ alignSelf: 'flex-start', padding: '6px 12px', fontSize: 12 }}
                    onClick={(e) => { e.stopPropagation(); onStudy(c); }}
                  >
                    <Icon name="play_arrow" />Study {ds.due}
                  </button>
                )}
              </button>
            );
          })}
        </div>
      )}
    </div>
  );
}
