/* the turn - Explore. The landscape: all areas ranked. Filters + sorts,
   a bespoke verdict-coloured coast map toggle, and a collapsed gated-out list. */
const { SpotMarker: ESpotMarker } = window.TheTurnDesignSystem_583d9e;

/* ---- one ranked area card ---- */
function AreaCard({ area, rank, onArea, onSpecies }) {
  const v = VERDICT[area.today.verdict];
  const t = area.today;
  const oor = t.outOfRange;

  // Out-of-range marks: muted, no verdict colour, no confident call. They stay
  // visible (you can still drill in + log a trip to start grounding them) but
  // are honestly marked "no local read".
  if (oor) {
    return (
      <button onClick={() => onArea(area.id)} style={{
        display: 'block', width: '100%', minWidth: 0, maxWidth: '100%', textAlign: 'left', cursor: 'pointer',
        background: 'var(--surface)', border: '1px dashed var(--border)', borderRadius: 'var(--r-md)',
        padding: 'var(--space-4)', position: 'relative', overflow: 'hidden', opacity: 0.7,
      }}>
        <div style={{ display: 'flex', alignItems: 'flex-start', gap: 12 }}>
          <div style={{ minWidth: 0, flex: 1 }}>
            <span style={{ display: 'block', fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 17, color: 'var(--text-dim)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{area.name}</span>
            <span style={{ display: 'block', fontSize: 12, color: 'var(--text-label)', marginTop: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{area.sub}</span>
          </div>
          <span style={{ flex: '0 0 auto', fontFamily: 'var(--font-mono)', fontSize: 10, letterSpacing: '.06em', textTransform: 'uppercase', color: 'var(--text-label)', border: '1px solid var(--border-strong)', borderRadius: 'var(--r-pill)', padding: '3px 8px', whiteSpace: 'nowrap' }}>out of range</span>
        </div>
        <div style={{ fontSize: 12.5, color: 'var(--text-label)', marginTop: 10, lineHeight: 1.4 }}>
          {area.distKm}km {area.bearing} · no local conditions yet — log a trip here and it starts building its own read.
        </div>
      </button>
    );
  }

  return (
    <button onClick={() => onArea(area.id)} style={{
      display: 'block', width: '100%', minWidth: 0, maxWidth: '100%', textAlign: 'left', cursor: 'pointer',
      background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 'var(--r-md)',
      padding: 'var(--space-4)', position: 'relative', overflow: 'hidden',
    }}>
      {/* top row */}
      <div style={{ display: 'flex', alignItems: 'flex-start', gap: 12 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, flex: 1, minWidth: 0 }}>
          <VerdictDot verdict={t.verdict} confidence={t.confidence} size={14} />
          <div style={{ minWidth: 0, flex: 1 }}>
            <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, minWidth: 0 }}>
              <span style={{ flex: '0 0 auto', fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--text-label)' }}>{String(rank).padStart(2, '0')}</span>
              <span style={{ flex: 1, minWidth: 0, fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 18, color: 'var(--text)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{area.name}</span>
            </div>
            <div style={{ fontSize: 12, color: 'var(--text-dim)', marginTop: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{area.sub}</div>
          </div>
        </div>
        <div style={{ textAlign: 'right', flex: '0 0 auto' }}>
          <span style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--text-label)' }}>{t.score || '-'}</span>
          <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--text-label)', marginTop: 2 }}>{area.distKm}km {area.bearing}</div>
        </div>
      </div>

      {/* meta line */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, margin: '12px 0', flexWrap: 'wrap' }}>
        <PostureBadge posture={area.posture} />
        {t.verdict !== 'skip' && (
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
            <TagChip>{PLATFORM_LABEL[t.platform]}</TagChip>
            <TagChip>{METHOD_LABEL[t.method]}</TagChip>
          </span>
        )}
        {t.window && t.window !== '-' && <span className="metric" style={{ fontSize: 12, color: 'var(--text-dim)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', minWidth: 0, flex: '1 1 auto' }}>{t.window}</span>}
      </div>

      {/* species */}
      {t.species && t.species.length > 0 && (
        <div style={{ display: 'flex', gap: 7, flexWrap: 'wrap', marginBottom: 10 }}>
          {t.species.slice(0, 4).map(id => <SpeciesChip key={id} id={id} onClick={onSpecies} color={v.color} />)}
        </div>
      )}

      {/* footer callout */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, borderTop: '1px solid var(--hairline)', paddingTop: 10 }}>
        {area.callout ? (
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 7, fontSize: 12.5, color: area.lifecycle === 'guide' ? 'var(--verdict-go)' : 'var(--text-dim)' }}>
            <ConfidenceBadge lifecycle={area.lifecycle} showLabel={false} />{area.callout}
          </span>
        ) : (
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 7, fontSize: 12.5, color: 'var(--text-label)' }}>
            <span style={{ width: 16, height: 16, borderRadius: '50%', border: '1.5px dashed var(--text-label)', display: 'grid', placeItems: 'center', flex: '0 0 auto' }}><span style={{ width: 3, height: 3, borderRadius: '50%', background: 'var(--text-label)' }} /></span>
            {area.scoutQ}
          </span>
        )}
        {area.bestDay && <span style={{ marginLeft: 'auto', fontFamily: 'var(--font-mono)', fontSize: 10, letterSpacing: '.06em', textTransform: 'uppercase', color: 'var(--verdict-go)', border: '1px solid var(--verdict-go)', borderRadius: 'var(--r-pill)', padding: '3px 8px', whiteSpace: 'nowrap' }}>best {area.bestDay}</span>}
      </div>
    </button>
  );
}

/* ---- bespoke coast map (verdict-coloured, offline) ---- */
function ExploreMap({ areas, onArea }) {
  const { useState } = React;
  const [sel, setSel] = useState(null);
  const visible = areas.filter(a => !a.gatedOut);
  return (
    <div style={{ position: 'relative', height: 440, borderRadius: 'var(--r-md)', overflow: 'hidden', border: '1px solid var(--border)' }}>
      <svg viewBox="0 0 390 440" preserveAspectRatio="none" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%' }}>
        <rect width="390" height="440" fill="var(--map-water)" />
        <path d="M0,150 C150,215 250,215 390,195" fill="none" stroke="var(--map-contour)" strokeWidth="1" strokeDasharray="2 7" />
        <path d="M0,215 C150,275 260,275 390,250" fill="none" stroke="var(--map-contour)" strokeWidth="1" strokeDasharray="2 7" />
        <path d="M0,108 C20,114 45,120 66,108 C90,116 110,126 133,148 C150,162 158,182 190,184 C225,186 240,180 265,186 C295,194 315,172 345,160 C365,154 380,152 390,150 L390,0 L0,0 Z" fill="var(--map-land)" />
        <path d="M0,108 C20,114 45,120 66,108 C90,116 110,126 133,148 C150,162 158,182 190,184 C225,186 240,180 265,186 C295,194 315,172 345,160 C365,154 380,152 390,150" fill="none" stroke="var(--map-coast)" strokeWidth="2.5" strokeLinecap="round" />
        <text x="20" y="48" fill="var(--map-label)" fontFamily="var(--font-mono)" fontSize="11" letterSpacing="2">HERMANUS</text>
        <text x="255" y="70" fill="var(--map-label)" fontFamily="var(--font-mono)" fontSize="11" letterSpacing="2">GANSBAAI</text>
      </svg>
      {/* you are here */}
      <div style={{ position: 'absolute', left: '18%', top: '26%', transform: 'translate(-50%,-50%)', zIndex: 1 }}>
        <span style={{ position: 'relative', display: 'block', width: 13, height: 13 }}>
          <span style={{ position: 'absolute', inset: -8, borderRadius: '50%', background: 'var(--keyline-soft)' }} />
          <span style={{ position: 'absolute', inset: 0, borderRadius: '50%', background: 'var(--keyline)', border: '2px solid var(--bg)' }} />
        </span>
      </div>
      {visible.map(a => (
        <div key={a.id} style={{ position: 'absolute', left: a.x + '%', top: a.y + '%', transform: 'translate(-50%,-50%)', zIndex: sel === a.id ? 5 : 2 }}>
          <ESpotMarker
            verdict={a.today.verdict} confidence={a.today.confidence}
            risk={a.risk && a.today.verdict === 'skip'} gate={a.gate}
            label={sel === a.id ? a.name : undefined} selected={sel === a.id} size={15}
            onClick={() => { sel === a.id ? onArea(a.id) : setSel(a.id); }}
          />
        </div>
      ))}
      {/* glass legend */}
      <div style={{ position: 'absolute', left: 12, right: 12, bottom: 12, zIndex: 4, display: 'flex', alignItems: 'center', gap: 14, padding: '10px 14px', background: 'var(--glass)', backdropFilter: 'var(--blur-bar)', WebkitBackdropFilter: 'var(--blur-bar)', border: '1px solid var(--hairline-bold)', borderRadius: 'var(--r-md)' }}>
        <MapLegend color="var(--verdict-go)" label="go" />
        <MapLegend color="var(--verdict-worth)" label="scout" />
        <MapLegend color="var(--verdict-dont)" label="skip" />
        <span style={{ marginLeft: 'auto', fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--text-label)', letterSpacing: '.04em' }}>{sel ? 'tap again to open' : 'tap a mark'}</span>
      </div>
    </div>
  );
}
function MapLegend({ color, label }) {
  return <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}><span style={{ width: 10, height: 10, borderRadius: '50%', background: color }} /><span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, letterSpacing: '.1em', textTransform: 'uppercase', color: 'var(--text-label)' }}>{label}</span></span>;
}

/* ============================================================
   Explore screen
   ============================================================ */
function Explore({ onArea, onSpecies, onConditions, wide = false }) {
  const { useState, useMemo } = React;
  const T = window.TURN;
  const [view, setView] = useState('list');     // 'list' | 'map'
  const [dist, setDist] = useState('200');
  const [posture, setPosture] = useState('all');
  const [method, setMethod] = useState('any');
  const [sort, setSort] = useState('score');
  const [gatedOpen, setGatedOpen] = useState(false);
  const [query, setQuery] = useState('');

  const gated = T.areas.filter(a => a.gatedOut);
  const active = T.areas.filter(a => !a.gatedOut);

  // Search across marks, areas + species. Marks are the thing people actually
  // name ("New Harbour", "Kwaaiwater") so they lead the results.
  const q = query.trim().toLowerCase();
  const allMarks = T.areas.flatMap(a => (a.marks || []).map(m => ({ ...m, areaId: a.id, areaName: a.name })));
  const markHits = q ? allMarks.filter(m =>
    m.name.toLowerCase().includes(q) ||
    (m.type || '').toLowerCase().includes(q) ||
    (m.knownFor || []).some(s => String(s).toLowerCase().replace(/[_-]/g, ' ').includes(q))
  ) : [];
  const areaHits = q ? T.areas.filter(a =>
    a.name.toLowerCase().includes(q) || (a.sub || '').toLowerCase().includes(q)
  ) : [];
  const speciesHits = q ? T.species.filter(s =>
    (s.common || '').toLowerCase().includes(q) || (s.sci || '').toLowerCase().includes(q)
  ) : [];

  const filtered = useMemo(() => {
    let r = active.filter(a => {
      if (dist === '30' && a.distKm > 30) return false;
      if (dist === '100' && a.distKm > 100) return false;
      if (posture !== 'all' && a.posture !== posture) return false;
      if (method !== 'any' && a.today.method !== method) return false;
      return true;
    });
    const rank = { go: 0, scout: 1, skip: 2 };
    r = [...r].sort((a, b) => {
      if (sort === 'distance') return a.distKm - b.distKm;
      if (sort === 'best3') return (b.bestDay === 'today' ? 1 : 0) - (a.bestDay === 'today' ? 1 : 0) || b.today.score - a.today.score;
      // default: verdict then score
      return (rank[a.today.verdict] - rank[b.today.verdict]) || (b.today.score - a.today.score);
    });
    return r;
  }, [dist, posture, method, sort]);

  return (
    <div style={{ padding: '4px var(--gutter) 0', display: 'flex', flexDirection: 'column', gap: 14 }}>
      {/* header */}
      <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between' }}>
        <div>
          <div style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 22, color: 'var(--text)', letterSpacing: '-0.02em' }}>Explore</div>
          <div className="overline" style={{ marginTop: 2 }}>{active.length} areas · within {dist === '200' ? '200km' : dist + 'km'}</div>
        </div>
        {/* list/map toggle (now a real Africa coastline w/ pan+zoom) */}
        <div style={{ display: 'flex', background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 'var(--r-pill)', padding: 3 }}>
          {[{ id: 'list', icon: 'lookahead' }, { id: 'map', icon: 'map' }].map(o => (
            <button key={o.id} onClick={() => setView(o.id)} style={{
              width: 42, height: 32, borderRadius: 'var(--r-pill)', cursor: 'pointer', border: 'none', display: 'grid', placeItems: 'center',
              background: view === o.id ? 'var(--surface-raised)' : 'transparent', color: view === o.id ? 'var(--text)' : 'var(--text-label)',
              boxShadow: view === o.id ? 'inset 0 0 0 1.5px var(--border-strong)' : 'none',
            }}><Icon name={o.icon} size={18} /></button>
          ))}
        </div>
      </div>

      {/* search - marks, areas, fish */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, height: 44, padding: '0 14px', background: 'var(--surface)', border: '1px solid var(--border-strong)', borderRadius: 'var(--r-md)' }}>
        <Icon name="pin" size={16} color="var(--text-label)" />
        <input
          value={query}
          onChange={e => setQuery(e.target.value)}
          placeholder="Search a mark, area or fish — e.g. New Harbour"
          style={{ flex: 1, minWidth: 0, background: 'none', border: 'none', outline: 'none', color: 'var(--text)', fontFamily: 'var(--font-body)', fontSize: 15 }}
        />
        {query && (
          <button onClick={() => setQuery('')} aria-label="clear search" style={{ flex: '0 0 auto', background: 'none', border: 'none', cursor: 'pointer', color: 'var(--text-label)', display: 'grid', placeItems: 'center' }}>
            <Icon name="close" size={15} />
          </button>
        )}
      </div>

      {q ? (
        <SearchResults
          markHits={markHits} areaHits={areaHits} speciesHits={speciesHits}
          onArea={onArea} onSpecies={onSpecies}
        />
      ) : (
      <React.Fragment>
      <ConditionsStrip c={T.conditions} onClick={onConditions} />

      {/* filters */}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 9 }}>
        <FilterRow label="dist" value={dist} onChange={setDist} options={[{ value: '30', label: '≤30km' }, { value: '100', label: '≤100km' }, { value: '200', label: '200km' }]} />
        <FilterRow label="who" value={posture} onChange={setPosture} options={[{ value: 'all', label: 'all' }, { value: 'atlas', label: 'Atlas' }, { value: 'scout', label: 'Scout' }, { value: 'guide', label: 'Guide' }]} />
        <FilterRow label="sort" value={sort} onChange={setSort} options={[{ value: 'score', label: 'by score' }, { value: 'distance', label: 'by distance' }, { value: 'best3', label: 'best in 3 days' }]} />
      </div>

      {view === 'map' ? (
        <AfricaMap areas={T.areas} onArea={onArea} />
      ) : (
        <div style={{ display: 'grid', gridTemplateColumns: wide ? 'repeat(2, 1fr)' : '1fr', gap: 10 }}>
          {filtered.map((a, i) => <AreaCard key={a.id} area={a} rank={i + 1} onArea={onArea} onSpecies={onSpecies} />)}
        </div>
      )}

      {/* gated out */}
      {gated.length > 0 && (
        <div style={{ marginTop: 4 }}>
          <button onClick={() => setGatedOpen(o => !o)} style={{ display: 'flex', alignItems: 'center', gap: 8, width: '100%', padding: '12px 14px', background: 'var(--surface-sunk)', border: '1px solid var(--border)', borderRadius: 'var(--r-md)', cursor: 'pointer', color: 'var(--text-dim)' }}>
            <span className="overline">off the table today · {gated.length}</span>
            <span style={{ marginLeft: 'auto', transform: gatedOpen ? 'rotate(90deg)' : 'none', transition: 'transform var(--dur-base) var(--ease-out)' }}><Icon name="chevron" size={15} color="var(--text-label)" /></span>
          </button>
          {gatedOpen && (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 1, marginTop: 8 }}>
              {gated.map(a => (
                <button key={a.id} onClick={() => onArea(a.id)} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '12px 14px', background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 'var(--r-sm)', cursor: 'pointer', textAlign: 'left' }}>
                  <span style={{ width: 9, height: 9, borderRadius: 2, background: 'var(--surface-raised)', border: '1.5px solid var(--border-strong)', flex: '0 0 auto', display: 'grid', placeItems: 'center', fontSize: 8, color: 'var(--text-label)' }}>⌗</span>
                  <span style={{ fontSize: 14, color: 'var(--text)', fontWeight: 600, flex: '0 0 auto' }}>{a.name}</span>
                  <span style={{ fontSize: 12.5, color: 'var(--text-label)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{a.gatedOut}</span>
                </button>
              ))}
            </div>
          )}
        </div>
      )}
      </React.Fragment>
      )}
      <div style={{ height: 8 }} />
    </div>
  );
}

/* ---- search results: marks first (what people name), then areas + fish ---- */
function SearchResults({ markHits, areaHits, speciesHits, onArea, onSpecies }) {
  const total = markHits.length + areaHits.length + speciesHits.length;
  if (total === 0) {
    return (
      <div style={{ padding: '28px 16px', textAlign: 'center', color: 'var(--text-label)', fontSize: 14 }}>
        Nothing matches that yet. Try a mark (New Harbour, Kwaaiwater), an area, or a fish.
      </div>
    );
  }
  const Row = ({ kind, title, sub, onClick }) => (
    <button onClick={onClick} style={{ display: 'flex', alignItems: 'center', gap: 12, width: '100%', padding: '12px 14px', background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 'var(--r-md)', cursor: 'pointer', textAlign: 'left' }}>
      <span style={{ flex: '0 0 auto', fontFamily: 'var(--font-mono)', fontSize: 9, letterSpacing: '.06em', textTransform: 'uppercase', color: 'var(--text-label)', border: '1px solid var(--border-strong)', borderRadius: 'var(--r-pill)', padding: '2px 7px' }}>{kind}</span>
      <span style={{ flex: 1, minWidth: 0 }}>
        <span style={{ display: 'block', fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 15, color: 'var(--text)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{title}</span>
        {sub && <span style={{ display: 'block', fontSize: 12, color: 'var(--text-label)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{sub}</span>}
      </span>
      <Icon name="chevron" size={15} color="var(--text-label)" />
    </button>
  );
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
      {markHits.length > 0 && <div className="overline" style={{ fontSize: 10, marginTop: 2 }}>marks · {markHits.length}</div>}
      {markHits.map(m => (
        <Row key={m.id} kind="mark" title={m.name} sub={`${m.type} · in ${m.areaName}`} onClick={() => onArea(m.areaId)} />
      ))}
      {areaHits.length > 0 && <div className="overline" style={{ fontSize: 10, marginTop: 8 }}>areas · {areaHits.length}</div>}
      {areaHits.map(a => (
        <Row key={a.id} kind="area" title={a.name} sub={`${a.sub || ''} · ${a.distKm}km ${a.bearing}`} onClick={() => onArea(a.id)} />
      ))}
      {speciesHits.length > 0 && <div className="overline" style={{ fontSize: 10, marginTop: 8 }}>fish · {speciesHits.length}</div>}
      {speciesHits.map(s => (
        <Row key={s.id} kind="fish" title={s.common} sub={s.sci} onClick={() => onSpecies(s.id)} />
      ))}
    </div>
  );
}

Object.assign(window, { Explore });
