/* global React, C, Screen, Header, Tabs, Segmented, RosterRow, EmptyRosterSlot, CTA, Progress, Avatar, Pill, Chevron, Close, Search, Refresh, Scissors, GOLFERS, FIELD, STANDINGS */
// screens-3-4.jsx — PGA Lineup tab (with swap drawer) + PGA Standings tab

const POOL_TAB_ROUTES = {
  Lineup:    'pools/lineup',
  Standings: 'pools/standings',
  Matchup:   'pools/matchup',
  Clubhouse: 'pools/clubhouse',
};
function poolTab(name) {
  if (window.appNav) window.appNav.go(POOL_TAB_ROUTES[name]);
}

const CAP = 200;

function PGALineupScreen() {
  const slots = window.useStore((s) => s.lineupDraft.pga.slots);
  const savedAt = window.useStore((s) => s.lineupDraft.pga.savedAt);
  const [tournament, setTournament] = React.useState(null);
  const [field, setField] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [replacingSlot, setReplacingSlot] = React.useState(null); // index or null
  const drawerOpen = replacingSlot !== null;

  // Load tournament + field + existing lineup on mount.
  React.useEffect(() => {
    const api = window.cambamApi;
    if (!api || !api.isConfigured?.()) { setLoading(false); return; }
    let cancelled = false;
    (async () => {
      try {
        const t = await api.currentTournament?.();
        if (cancelled) return;
        setTournament(t || null);
        if (!t) { setLoading(false); return; }
        const [fld, existing] = await Promise.all([
          api.loadField(t.id),
          api.loadLineup(t.id),
        ]);
        if (cancelled) return;
        setField(fld || []);
        // Hydrate slots from the saved server lineup if there's one and the
        // local draft hasn't been touched (or differs by tournament).
        if (existing?.lineup_golfers?.length) {
          const next = Array(6).fill(null);
          for (const lg of existing.lineup_golfers) {
            if (lg.slot >= 1 && lg.slot <= 6) {
              next[lg.slot - 1] = {
                name: lg.golfer_name, golferId: lg.golfer_id, price: lg.price,
                country: '', points: 0, tone: 1, status: 'Saved',
              };
            }
          }
          window.STORE.set((s) => ({
            ...s,
            lineupDraft: { ...s.lineupDraft, pga: { slots: next, savedAt: existing.submitted_at || null } },
          }));
        }
        setLoading(false);
      } catch (e) {
        console.warn('lineup load failed', e);
        if (!cancelled) setLoading(false);
      }
    })();
    return () => { cancelled = true; };
  }, []);

  const openDrawer  = (i) => setReplacingSlot(i);
  const closeDrawer = ()  => setReplacingSlot(null);

  const used = slots.reduce((acc, g) => acc + (g ? g.price : 0), 0);
  const remaining = CAP - used;
  const overCap = remaining < 0;
  const filled = slots.filter(Boolean).length;
  const canSave = filled === 6 && !overCap && !!tournament;

  const pickGolfer = (golfer) => {
    if (replacingSlot === null) return;
    window.STORE.set((s) => {
      const next = s.lineupDraft.pga.slots.slice();
      next[replacingSlot] = {
        name: golfer.name, golferId: golfer.golferId || golfer.golfer_id || golfer.name,
        country: golfer.country, price: golfer.price,
        points: 0, tone: golfer.tone || 1, status: 'Picked',
      };
      return { ...s, lineupDraft: { ...s.lineupDraft, pga: { ...s.lineupDraft.pga, slots: next } } };
    });
    closeDrawer();
    window.STORE.toast(`Picked ${golfer.name}`);
  };

  const saveLineup = () => {
    if (!canSave) return;
    window.STORE.set((s) => ({
      ...s,
      lineupDraft: { ...s.lineupDraft, pga: { ...s.lineupDraft.pga, savedAt: new Date().toISOString() } },
    }));
    window.STORE.toast('Lineup saved');
    if (window.cambamApi && window.cambamApi.saveLineup && tournament) {
      window.cambamApi.saveLineup(tournament.id, slots).catch((e) => {
        console.warn('saveLineup failed', e);
        window.STORE.toast('Save failed: ' + (e?.message || 'unknown error'));
      });
    }
  };

  const autofillLastWeek = () => {
    // Copy from the Masters memory if we had one; for now seed with the top of the field.
    if (!field.length) { window.STORE.toast('Field not yet available'); return; }
    const cheapestSix = field.slice().sort((a, b) => a.salary - b.salary).slice(0, 6);
    window.STORE.set((s) => ({
      ...s,
      lineupDraft: { ...s.lineupDraft, pga: { ...s.lineupDraft.pga, slots: cheapestSix.map((g) => ({
        name: g.golfer_name, golferId: g.golfer_id, price: g.salary, country: g.country, points: 0, tone: 1, status: 'Auto',
      })) } },
    }));
    window.STORE.toast('Auto-filled from cheapest 6');
  };

  const copyFriendsLineup = () => {
    // Friends' lineups are visible after lock. We expose a member picker that
    // returns a lineup to write into your draft.
    if (window.appNav) window.appNav.openSheet('member-picker', { purpose: 'copy-lineup' });
  };

  const headerSubtitle =
    !tournament ? (loading ? 'Loading…' : 'No tournament yet') :
    tournament.status === 'live'  ? 'Live' :
    tournament.status === 'final' ? 'Final' :
    tournament.starts_at ? `Locks ${new Date(tournament.lineup_locks_at || tournament.starts_at).toLocaleString('en-US', { weekday: 'short', month: 'short', day: 'numeric', hour: 'numeric' })}` :
    '';

  return (
    <Screen label="03 PGA Lineup" bottomNav="pools" scroll={false}>
      <Header
        title={tournament?.name || (loading ? 'Loading…' : 'Lineup')}
        subtitle={headerSubtitle}
        onBack
      />

      <Tabs items={['Lineup', 'Standings', 'Matchup', 'Clubhouse']} active="Lineup" onChange={poolTab} />

      <div style={{ height: 'calc(100% - 110px)', overflow: 'hidden', position: 'relative' }}>
        <div style={{ height: '100%', overflow: 'auto', paddingBottom: drawerOpen ? 280 : 96 }}>
          {!tournament && !loading && (
            <div style={{ padding: '32px 24px', color: C.text2, font: '400 14px/22px Inter', textAlign: 'center' }}>
              No active tournament. Seed the 2026 majors via Admin or wait for the next one to be scheduled.
            </div>
          )}

          {tournament && (
            <>
              {/* Budget bar */}
              <div style={{ padding: '16px 16px 8px' }}>
                <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 8 }}>
                  <div>
                    <span className="tnum" style={{ font: '700 28px/32px Inter', color: overCap ? C.red : C.text }}>
                      {overCap ? '−' : ''}${Math.abs(remaining)}
                    </span>
                    <span style={{ font: '500 13px/18px Inter', color: C.text2, marginLeft: 6 }}>
                      {overCap ? 'over cap' : 'remaining'}
                    </span>
                  </div>
                  <button onClick={autofillLastWeek} style={{
                    background: 'none', border: 'none', cursor: 'pointer',
                    color: C.emerald, font: '500 13px/18px Inter',
                    display: 'inline-flex', alignItems: 'center', gap: 4,
                  }}>
                    <Refresh size={13} />
                    <span>Auto-fill cheapest</span>
                  </button>
                </div>
                <Progress value={used / CAP} color={overCap ? C.red : C.emerald} height={4} />
                <div style={{
                  display: 'flex', justifyContent: 'space-between', marginTop: 6,
                  font: '400 12px/16px Inter', color: C.text3,
                }}>
                  <span className="tnum">Used ${used}</span>
                  <span className="tnum">Cap $200</span>
                </div>
              </div>

              <div style={{
                padding: '12px 16px 4px',
                display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
              }}>
                <div style={{
                  font: '500 11px/16px Inter', textTransform: 'uppercase', letterSpacing: 0.04 * 11,
                  color: C.text3,
                }}>{filled} of 6 golfers</div>
                <button onClick={copyFriendsLineup} style={{
                  background: 'none', border: 'none', cursor: 'pointer',
                  color: C.emerald, font: '500 13px/18px Inter',
                }}>Copy a friend's lineup</button>
              </div>

              {field.length === 0 && !loading && (
                <div style={{ margin: '8px 16px 12px', padding: '14px 16px', background: C.surface, borderRadius: 12, color: C.text2, font: '400 13px/18px Inter' }}>
                  Field for <strong>{tournament.name}</strong> hasn't been priced yet. Golfers appear here ~5 days before lineup lock.
                </div>
              )}

              {slots.map((g, i) => (
                <React.Fragment key={i}>
                  {g
                    ? <RosterRow {...g} onClick={() => openDrawer(i)} />
                    : <div onClick={() => openDrawer(i)} role="button" tabIndex={0}
                        onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') openDrawer(i); }}
                        style={{ cursor: 'pointer' }}>
                        <EmptyRosterSlot position="G" />
                      </div>}
                  {i < slots.length - 1 && <div style={{ height: 8 }} />}
                </React.Fragment>
              ))}
            </>
          )}
        </div>

        {/* Sticky Save CTA — only shown when the drawer is closed. */}
        {!drawerOpen && tournament && (
          <div style={{
            position: 'absolute', left: 0, right: 0, bottom: 0,
            padding: '12px 16px',
            background: 'linear-gradient(to top, rgba(10,10,10,0.92), rgba(10,10,10,0))',
          }}>
            <CTA kind="primary" disabled={!canSave} onClick={saveLineup}>
              {savedAt ? 'Update lineup' : 'Save lineup'}
            </CTA>
          </div>
        )}

        {drawerOpen && <SwapDrawer field={field} onClose={closeDrawer} slotIndex={replacingSlot} remaining={remaining} onPick={pickGolfer} />}
      </div>
    </Screen>
  );
}

function SwapDrawer({ onClose, slotIndex, remaining, onPick, field }) {
  const dismiss = onClose || (() => {});
  const [query, setQuery]   = React.useState('');
  const [sort, setSort]     = React.useState('Salary fit');

  // Adapt the field rows from Supabase shape → drawer shape (golfer rows).
  const source = (field || []).filter((f) => f.is_active !== false).map((f) => ({
    name: f.golfer_name,
    golferId: f.golfer_id,
    country: f.country || '',
    price: f.salary,
    rank: f.world_rank ?? 999,
    tone: 1,
    owned: 0, // ownership not in field; future: compute from lineup_golfers join
  }));

  const filtered = source
    .filter((f) => !query || (f.name || '').toLowerCase().includes(query.toLowerCase()))
    .slice().sort((a, b) => {
      if (sort === '$ Price')    return b.price - a.price;
      if (sort === 'Owned %')    return b.owned - a.owned;
      if (sort === 'World Rank') return (a.rank || 999) - (b.rank || 999);
      // Salary fit: prioritize golfers that fit the remaining budget (lowest over-budget delta).
      const aFit = Math.max(0, a.price - remaining);
      const bFit = Math.max(0, b.price - remaining);
      return aFit - bFit || b.price - a.price;
    });

  return (
    <div
      onClick={(e) => { if (e.target === e.currentTarget) dismiss(); }}
      style={{
        position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.45)',
        zIndex: 25,
      }}>
    <div style={{
      position: 'absolute', left: 0, right: 0, bottom: 0,
      height: 410, background: C.surface, borderTopLeftRadius: 16, borderTopRightRadius: 16,
      boxShadow: '0 -1px 0 ' + C.hairline,
      display: 'flex', flexDirection: 'column', overflow: 'hidden',
      zIndex: 30,
    }}>
      <div style={{ display: 'flex', justifyContent: 'center', padding: '8px 0 4px', flexShrink: 0 }}>
        <div style={{ width: 36, height: 4, borderRadius: 999, background: C.hairline }} />
      </div>

      <div style={{
        padding: '8px 16px 12px', display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        flexShrink: 0,
      }}>
        <div>
          <div style={{ font: '600 18px/24px Inter', color: C.text }}>Pick a golfer</div>
          <div style={{ font: '400 13px/18px Inter', color: C.text2, marginTop: 2 }}>
            ${remaining} left · Replacing slot {slotIndex + 1}
          </div>
        </div>
        <button aria-label="Close swap drawer" onClick={dismiss} style={{
          width: 32, height: 32, borderRadius: 999, background: C.surface2,
          border: 'none', cursor: 'pointer', color: C.text2,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}><Close size={16} /></button>
      </div>

      <div style={{ padding: '0 16px 12px', flexShrink: 0 }}>
        <div style={{
          height: 40, background: C.surface2, borderRadius: 999,
          display: 'flex', alignItems: 'center', gap: 8, padding: '0 12px',
          color: C.text3,
        }}>
          <Search size={16} />
          <input
            type="text" placeholder="Search the field…"
            value={query} onChange={(e) => setQuery(e.target.value)}
            style={{
              flex: 1, background: 'transparent', border: 'none', outline: 'none',
              color: C.text, font: '400 14px/20px Inter',
            }}
          />
        </div>
      </div>

      <div style={{ padding: '0 16px 8px', display: 'flex', gap: 8, flexShrink: 0 }}>
        {['$ Price', 'Salary fit', 'Owned %', 'World Rank'].map((p) => {
          const on = p === sort;
          return (
            <button key={p} onClick={() => setSort(p)} style={{
              padding: '6px 12px', borderRadius: 999,
              background: on ? C.emeraldMute : C.surface2,
              color: on ? C.emerald : C.text2,
              border: 'none', cursor: 'pointer',
              font: '500 12px/16px Inter',
            }}>{p}</button>
          );
        })}
      </div>

      <div style={{ flex: 1, overflow: 'auto' }}>
        {source.length === 0 ? (
          <div style={{ padding: '24px 16px', textAlign: 'center', color: C.text3, font: '400 13px/18px Inter' }}>
            Field not yet announced. Yahoo posts the price list ~5 days before the major.
          </div>
        ) : filtered.length === 0 ? (
          <div style={{ padding: '24px 16px', textAlign: 'center', color: C.text3, font: '400 13px/18px Inter' }}>
            No golfer matches "{query}".
          </div>
        ) : filtered.slice(0, 50).map((f, i) => {
          const fits = f.price <= remaining;
          return (
            <button key={f.name + i} onClick={() => onPick(f)} style={{
              width: '100%', textAlign: 'left',
              height: 56, display: 'flex', alignItems: 'center', gap: 12,
              padding: '0 16px',
              background: 'transparent', border: 'none', cursor: 'pointer',
              color: C.text,
            }}>
              <Avatar name={f.name} size={36} tone={f.tone} />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ font: '600 15px/20px Inter', color: C.text }}>{f.name}</div>
                <div style={{ font: '400 12px/16px Inter', color: C.text2 }}>
                  {f.country} · {f.owned}% owned
                </div>
              </div>
              <div style={{ textAlign: 'right' }}>
                <div className="tnum" style={{ font: '600 15px/20px Inter', color: C.text }}>${f.price}</div>
                <div style={{ font: '500 11px/16px Inter', color: fits ? C.emerald : C.text3, marginTop: 1 }}>
                  {fits ? 'Fits' : `+$${f.price - remaining} over`}
                </div>
              </div>
            </button>
          );
        })}
      </div>
    </div>
    </div>
  );
}

function PGAStandingsScreen() {
  const me = window.useStore((s) => s.me);
  const [tournament, setTournament] = React.useState(null);
  const [rows, setRows] = React.useState([]);
  const [loading, setLoading] = React.useState(true);

  React.useEffect(() => {
    const api = window.cambamApi;
    if (!api || !api.isConfigured?.()) { setLoading(false); return; }
    let cancelled = false;
    (async () => {
      try {
        const t = await api.currentTournament?.();
        if (cancelled) return;
        setTournament(t || null);
        if (!t) { setLoading(false); return; }
        const data = await api.loadStandings(t.id);
        if (cancelled) return;
        setRows(data || []);
        setLoading(false);
      } catch (e) {
        console.warn('standings load failed', e);
        if (!cancelled) setLoading(false);
      }
    })();
    return () => { cancelled = true; };
  }, []);

  const subtitle =
    !tournament ? (loading ? 'Loading…' : 'No tournament') :
    `${tournament.status === 'live' ? 'Live' : tournament.status === 'final' ? 'Final' : 'Upcoming'} · ${rows.length} ${rows.length === 1 ? 'entry' : 'entries'}`;
  const leaderPts = rows[0]?.fantasy_pts ? Number(rows[0].fantasy_pts) : 1;

  return (
    <Screen label="04 PGA Standings" bottomNav="pools">
      <Header
        title={tournament?.name || (loading ? 'Loading…' : 'Standings')}
        subtitle={subtitle}
        onBack
      />
      <Tabs items={['Lineup', 'Standings', 'Matchup', 'Clubhouse']} active="Standings" onChange={poolTab} />

      <div style={{ padding: '16px 16px 4px' }}>
        <Segmented items={['Live', 'Projected']} active="Live" size="sm" />
      </div>

      {!tournament && !loading && (
        <div style={{ padding: '32px 24px', color: C.text2, font: '400 14px/22px Inter', textAlign: 'center' }}>
          No active tournament yet.
        </div>
      )}

      {tournament && rows.length === 0 && !loading && (
        <div style={{ padding: '32px 24px', color: C.text2, font: '400 14px/22px Inter', textAlign: 'center' }}>
          Standings will appear when scoring begins for {tournament.name}.
        </div>
      )}

      <div style={{ padding: '0 0 4px' }}>
        {rows.map((row, i) => {
          const m = row.member || {};
          const isYou = m.id === me?.id;
          return (
            <StandingsRow
              key={m.id || i}
              rank={row.rank ?? (i + 1)}
              name={m.display_name || m.handle || '—'}
              handle={m.handle || ''}
              phr={0}
              points={Number(row.fantasy_pts || 0)}
              status={tournament?.status === 'live' ? 'Playing' : tournament?.status === 'final' ? 'Final' : 'Upcoming'}
              tone={m.avatar_tone}
              you={isYou}
              champion={!!m.champion}
              memberId={m.id}
              leaderPts={leaderPts}
            />
          );
        })}
      </div>
    </Screen>
  );
}

function StandingsRow({ rank, name, handle, phr, points, status, tone, you, leaderPts, champion, memberId }) {
  const pct = leaderPts > 0 ? Math.max(0, Math.min(1, points / leaderPts)) : 0;
  const open = () => {
    if (window.appNav) window.appNav.openSheet('member-lineup', { rank, name, handle, phr, points, status, tone, you, champion, memberId });
  };
  return (
    <div
      role="button" tabIndex={0} onClick={open}
      onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') open(); }}
      style={{
        padding: '12px 16px 14px',
        background: you ? 'rgba(31, 138, 91,0.04)' : 'transparent',
        position: 'relative', cursor: 'pointer',
      }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
        <div className="tnum" style={{
          font: '700 22px/26px Inter', color: you ? C.emerald : C.text, width: 28, textAlign: 'center',
        }}>{rank}</div>
        <Avatar name={name} size={40} tone={tone} ring={you} champion={champion} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ font: '600 16px/22px Inter', color: C.text,
            display: 'flex', alignItems: 'center', gap: 6,
          }}>
            {name}
            {you && <span style={{
              font: '500 10px/14px Inter', textTransform: 'uppercase', letterSpacing: 0.04 * 10,
              color: C.emerald, background: 'rgba(31, 138, 91,0.15)',
              padding: '1px 6px', borderRadius: 999,
            }}>You</span>}
          </div>
          <div style={{ font: '400 13px/18px Inter', color: C.text2, marginTop: 1 }}>
            {handle} · {status}
          </div>
        </div>
        <div style={{ textAlign: 'right', display: 'flex', gap: 18 }}>
          <div>
            <div style={{
              font: '500 11px/14px Inter', textTransform: 'uppercase', letterSpacing: 0.04 * 11,
              color: C.text3,
            }}>PHR</div>
            <div className="tnum" style={{ font: '500 14px/18px Inter', color: C.text2, marginTop: 1 }}>{phr.toFixed(1)}</div>
          </div>
          <div style={{ minWidth: 56, textAlign: 'right' }}>
            <div style={{
              font: '500 11px/14px Inter', textTransform: 'uppercase', letterSpacing: 0.04 * 11,
              color: C.text3,
            }}>Pts</div>
            <div className="tnum" style={{ font: '700 18px/22px Inter', color: C.text, marginTop: 1 }}>{points.toFixed(1)}</div>
          </div>
        </div>
      </div>
      <div style={{ marginTop: 10, marginLeft: 40 }}>
        <Progress value={pct} height={2} />
      </div>
    </div>
  );
}

Object.assign(window, { PGALineupScreen, PGAStandingsScreen });

// Reserved for future use: a per-round CutTracker tied to real
// lineup_golfers + golfer_scores once round 2 scoring lands.
