/* sasongsplan.jsx — the multi-year planning surface.
   Per-member: dream → 3-year vision → 1-year target → 5 key tests → 4-season
   target matrix. All inline-editable. Saves to Supabase on blur. */
/* global React, MEMBERS, TESTS, Eyebrow, Avatar, Card, Pill, Button, Input,
   SectionHeader, getGoalTrack, saveGoalTrack, getSeasonTargets, getKeyTestIds,
   getSeasonTarget, addKeyTest, removeKeyTest, saveSeasonTarget,
   nextFourSeasons, getTest, latestAttempt, getMemberChallenges */
const { useState, useMemo, useEffect } = React;

// ============================================================================
// SasongsplanView — main view, rendered when Tester is toggled to "Säsongsplan"
// ============================================================================
function SasongsplanView({ memberId, isMobile }) {
  const [, bump] = useState(0);
  const refresh = () => bump(b => b + 1);
  const member = MEMBERS.find(m => m.id === memberId);
  const canEdit = !!(window.canEdit && window.canEdit(memberId));

  const track = window.getGoalTrack(memberId);
  const keyTestIds = window.getKeyTestIds(memberId);
  const seasons = window.nextFourSeasons();

  if (!member) return null;

  return (
    <div style={{ padding: '24px 16px 80px', maxWidth: 1280, margin: '0 auto' }}>
      {/* Header */}
      <div style={{ marginBottom: 24 }}>
        <Eyebrow style={{ marginBottom: 8 }}>Säsongsplan</Eyebrow>
        <h1 style={{ margin: 0, fontFamily: 'var(--font-sans)', fontSize: 32, fontWeight: 500, letterSpacing: '-0.02em', lineHeight: 1.15 }}>
          <span style={{ color: member.color }}>{member.name}</span>s plan
        </h1>
        <p style={{ margin: '8px 0 0', maxWidth: 620, fontSize: 13, color: 'var(--fg-muted)', lineHeight: 1.55 }}>
          Drömmen ger riktningen. 3-årsvisionen sätter ribban. 1-årsmålet är var du
          behöver vara om 12 månader. Och säsongsmålen är de konkreta milstolparna
          längs vägen.
        </p>
      </div>

      {/* Narrative layer */}
      <GoalTrackEditor memberId={memberId} member={member} track={track} canEdit={canEdit} onChange={refresh} />

      {/* Key tests + target matrix */}
      <div style={{ marginTop: 28 }}>
        <SectionHeader eyebrow="Nyckel-tester" title="5 viktigaste testerna" />
        <KeyTestsPicker
          memberId={memberId}
          keyTestIds={keyTestIds}
          canEdit={canEdit}
          onChange={refresh}
        />
      </div>

      <div style={{ marginTop: 28 }}>
        <SectionHeader
          eyebrow="Säsongsmål"
          title={`Nästa ${seasons.length} säsonger`}
        />
        {keyTestIds.length === 0 ? (
          <Card pad={24} style={{ textAlign: 'center', color: 'var(--fg-muted)' }}>
            <div style={{ fontSize: 14, marginBottom: 8 }}>Inga nyckel-tester valda än.</div>
            <div style={{ fontSize: 12, color: 'var(--fg-subtle)' }}>
              Lägg till tester ovan, sedan kan du sätta säsongsmål här.
            </div>
          </Card>
        ) : (
          <TargetMatrix
            memberId={memberId}
            keyTestIds={keyTestIds}
            seasons={seasons}
            canEdit={canEdit}
            onChange={refresh}
            isMobile={isMobile}
          />
        )}
      </div>
    </div>
  );
}

// ============================================================================
// GoalTrackEditor — dream + 3yr vision + 1yr target editable text areas
// ============================================================================
function GoalTrackEditor({ memberId, member, track, canEdit, onChange }) {
  const t = track || { dream: '', three_year_vision: '', one_year_target: '' };
  const save = (patch) => {
    window.saveGoalTrack(memberId, patch);
    onChange();
  };
  return (
    <Card pad={0} style={{ marginTop: 12 }}>
      <NarrativeField
        eyebrow="Dröm"
        hint="Vad är drömmen? T.ex. 'Top-10 NHL-spelare', 'Världselit i handboll', 'Stark och hälsosam livet ut'."
        value={t.dream}
        onSave={(v) => save({ dream: v })}
        canEdit={canEdit}
        memberColor={member.color}
      />
      <Hr />
      <NarrativeField
        eyebrow="3-årsvision"
        hint="Var vill du vara om 3 år? Konkret. T.ex. 'Topp av U13 regionalt, vertikal 40cm, NHL Combine-nivå för åldern'."
        value={t.three_year_vision}
        onSave={(v) => save({ three_year_vision: v })}
        canEdit={canEdit}
        memberColor={member.color}
      />
      <Hr />
      <NarrativeField
        eyebrow="1-årsmål"
        hint="Var behöver du vara om 12 månader för att vara på spår? T.ex. 'Regional U11-utvecklingstrupp, Cooper 2400m, 6 pull-ups'."
        value={t.one_year_target}
        onSave={(v) => save({ one_year_target: v })}
        canEdit={canEdit}
        memberColor={member.color}
      />
    </Card>
  );
}

function Hr() {
  return <div style={{ height: 1, background: 'var(--border-faint)' }} />;
}

function NarrativeField({ eyebrow, hint, value, onSave, canEdit, memberColor }) {
  const [draft, setDraft] = useState(value || '');
  const [editing, setEditing] = useState(false);

  // Keep draft in sync if the underlying value changes (e.g. async load)
  useEffect(() => { setDraft(value || ''); }, [value]);

  const onBlur = () => {
    setEditing(false);
    if ((draft || '') !== (value || '')) {
      onSave(draft);
    }
  };

  return (
    <div style={{ padding: '18px 22px' }}>
      <Eyebrow style={{ marginBottom: 6 }}>{eyebrow}</Eyebrow>
      {!editing && !draft && (
        <div
          onClick={() => canEdit && setEditing(true)}
          style={{
            fontSize: 13, color: 'var(--fg-subtle)', fontStyle: 'italic',
            cursor: canEdit ? 'text' : 'default',
            padding: '8px 0', lineHeight: 1.5,
          }}
        >
          {canEdit ? hint : '(inget angivet)'}
        </div>
      )}
      {(editing || draft) && (
        <textarea
          value={draft}
          readOnly={!canEdit}
          onChange={e => setDraft(e.target.value)}
          onFocus={() => setEditing(true)}
          onBlur={onBlur}
          placeholder={hint}
          rows={Math.max(2, Math.min(6, draft.split('\n').length + 1))}
          style={{
            width: '100%', resize: 'vertical',
            fontFamily: 'var(--font-sans)', fontSize: 15, lineHeight: 1.55,
            color: 'var(--fg)', background: 'transparent',
            border: 'none', outline: 'none', padding: '6px 0',
            borderLeft: editing ? `3px solid ${memberColor || 'var(--signal)'}` : '3px solid transparent',
            paddingLeft: 10, marginLeft: -10,
            transition: 'border-color 120ms',
            boxSizing: 'border-box',
          }}
        />
      )}
    </div>
  );
}

// ============================================================================
// KeyTestsPicker — pick the 5 (or so) "north-star" tests for this member
// ============================================================================
function KeyTestsPicker({ memberId, keyTestIds, canEdit, onChange }) {
  const [picking, setPicking] = useState(false);
  const allTests = TESTS.filter(t => !t.archived);
  const keyTests = keyTestIds.map(id => allTests.find(t => t.id === id)).filter(Boolean);
  const availableToAdd = allTests.filter(t => !keyTestIds.includes(t.id));

  return (
    <Card pad={16}>
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center' }}>
        {keyTests.map(t => (
          <Pill
            key={t.id}
            bg="var(--ink-50)"
            color="var(--fg)"
            style={{ padding: '6px 12px', fontSize: 12, textTransform: 'none', letterSpacing: 0, gap: 8 }}
          >
            <span style={{ fontWeight: 500 }}>{t.name}</span>
            <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--fg-subtle)' }}>{t.unit}</span>
            {canEdit && (
              <button
                onClick={() => { window.removeKeyTest(memberId, t.id); onChange(); }}
                style={{ background: 'none', border: 'none', color: 'var(--fg-muted)', cursor: 'pointer', padding: 0, marginLeft: 4, fontSize: 13, lineHeight: 1 }}
                title="Ta bort"
              >×</button>
            )}
          </Pill>
        ))}

        {canEdit && (
          <button
            onClick={() => setPicking(p => !p)}
            disabled={availableToAdd.length === 0}
            style={{
              fontFamily: 'var(--font-sans)', fontSize: 12, fontWeight: 500,
              padding: '6px 12px', borderRadius: 4,
              border: '1px dashed var(--border-strong)', background: 'var(--bg-raised)',
              color: 'var(--fg-muted)', cursor: availableToAdd.length === 0 ? 'not-allowed' : 'pointer',
              opacity: availableToAdd.length === 0 ? 0.4 : 1,
            }}
          >+ Lägg till test</button>
        )}
      </div>

      {picking && (
        <div style={{ marginTop: 12, padding: 12, background: 'var(--ink-25)', borderRadius: 4 }}>
          <Eyebrow style={{ marginBottom: 8 }}>Välj test att lägga till</Eyebrow>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(220px, 1fr))', gap: 6 }}>
            {availableToAdd.map(t => (
              <button
                key={t.id}
                onClick={() => { window.addKeyTest(memberId, t.id); setPicking(false); onChange(); }}
                style={{
                  textAlign: 'left', padding: '8px 10px',
                  background: 'var(--bg-raised)', border: '1px solid var(--border)', borderRadius: 4,
                  cursor: 'pointer', fontFamily: 'var(--font-sans)',
                }}
              >
                <div style={{ fontSize: 13, fontWeight: 500 }}>{t.name}</div>
                <div style={{ fontSize: 11, fontFamily: 'var(--font-mono)', color: 'var(--fg-subtle)', marginTop: 2 }}>
                  {t.cat} · {t.unit} · {t.dir === 'lower' ? 'lägre = bättre' : 'högre = bättre'}
                </div>
              </button>
            ))}
          </div>
        </div>
      )}

      {!canEdit && keyTests.length === 0 && (
        <div style={{ fontSize: 12, color: 'var(--fg-subtle)', fontStyle: 'italic' }}>
          Inga nyckel-tester valda.
        </div>
      )}
    </Card>
  );
}

// ============================================================================
// TargetMatrix — 5 tests × 4 seasons grid with inline-editable target values
// ============================================================================
function TargetMatrix({ memberId, keyTestIds, seasons, canEdit, onChange, isMobile }) {
  const tests = keyTestIds.map(id => window.getTest(id)).filter(Boolean);
  if (isMobile) {
    return <TargetMatrixMobile memberId={memberId} tests={tests} seasons={seasons} canEdit={canEdit} onChange={onChange} />;
  }
  return <TargetMatrixDesktop memberId={memberId} tests={tests} seasons={seasons} canEdit={canEdit} onChange={onChange} />;
}

function TargetMatrixDesktop({ memberId, tests, seasons, canEdit, onChange }) {
  // Grid: first column = test name + current baseline, then one column per season.
  const grid = `minmax(180px, 1.6fr) repeat(${seasons.length}, minmax(110px, 1fr))`;

  // Compute "current" value per test for the baseline column (from active challenge, if any)
  const currentValueForTest = (testId) => {
    const challenges = window.getMemberChallenges ? window.getMemberChallenges(memberId) : [];
    const c = challenges.find(x => x.testId === testId);
    if (!c) return null;
    const att = window.latestAttempt ? window.latestAttempt(c) : null;
    return att ? att.value : c.baseline;
  };

  return (
    <Card pad={0} style={{ overflow: 'hidden' }}>
      {/* Header row */}
      <div style={{
        display: 'grid', gridTemplateColumns: grid, gap: 0,
        padding: '12px 16px',
        borderBottom: '1px solid var(--border)',
        background: 'var(--ink-25)',
        alignItems: 'center',
      }}>
        <div><Eyebrow>Test · nuläge</Eyebrow></div>
        {seasons.map(s => (
          <div key={s.id} style={{ textAlign: 'right' }}>
            <Eyebrow>{s.name}</Eyebrow>
          </div>
        ))}
      </div>

      {/* Rows */}
      {tests.map((t, i) => {
        const current = currentValueForTest(t.id);
        return (
          <div key={t.id} style={{
            display: 'grid', gridTemplateColumns: grid, gap: 0,
            padding: '14px 16px',
            alignItems: 'center',
            borderBottom: i < tests.length - 1 ? '1px solid var(--border-faint)' : 'none',
          }}>
            {/* Test name + current */}
            <div>
              <div style={{ fontSize: 14, fontWeight: 500 }}>{t.name}</div>
              <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--fg-subtle)', marginTop: 2 }}>
                {t.cat} · {t.unit} · {t.dir === 'lower' ? 'lägre = bättre' : 'högre = bättre'}
              </div>
              <div style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--fg-muted)', marginTop: 4, fontVariantNumeric: 'tabular-nums' }}>
                Nu: {current != null ? current : '—'}
              </div>
            </div>

            {/* Per-season target cells */}
            {seasons.map(s => {
              const target = window.getSeasonTarget(memberId, t.id, s.id);
              return (
                <div key={s.id} style={{ textAlign: 'right' }}>
                  <TargetCell
                    value={target ? target.target_value : null}
                    unit={t.unit}
                    onChange={(v) => { window.saveSeasonTarget(memberId, t.id, s.id, v); onChange(); }}
                    canEdit={canEdit}
                  />
                </div>
              );
            })}
          </div>
        );
      })}
    </Card>
  );
}

function TargetMatrixMobile({ memberId, tests, seasons, canEdit, onChange }) {
  // On mobile: one season at a time with a pager.
  const [seasonIdx, setSeasonIdx] = useState(0);
  const season = seasons[seasonIdx];
  if (!season) return null;
  const currentValueForTest = (testId) => {
    const challenges = window.getMemberChallenges ? window.getMemberChallenges(memberId) : [];
    const c = challenges.find(x => x.testId === testId);
    if (!c) return null;
    const att = window.latestAttempt ? window.latestAttempt(c) : null;
    return att ? att.value : c.baseline;
  };

  return (
    <Card pad={0} style={{ overflow: 'hidden' }}>
      {/* Pager */}
      <div style={{
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        padding: '10px 14px', borderBottom: '1px solid var(--border)', background: 'var(--ink-25)',
      }}>
        <button
          onClick={() => setSeasonIdx(i => Math.max(0, i - 1))}
          disabled={seasonIdx === 0}
          style={pagerBtnStyle(seasonIdx === 0)}
        >‹</button>
        <div style={{ textAlign: 'center' }}>
          <Eyebrow>Säsong {seasonIdx + 1} av {seasons.length}</Eyebrow>
          <div style={{ fontSize: 14, fontWeight: 500, marginTop: 2 }}>{season.name}</div>
        </div>
        <button
          onClick={() => setSeasonIdx(i => Math.min(seasons.length - 1, i + 1))}
          disabled={seasonIdx === seasons.length - 1}
          style={pagerBtnStyle(seasonIdx === seasons.length - 1)}
        >›</button>
      </div>

      {/* Per-test rows */}
      {tests.map((t, i) => {
        const current = currentValueForTest(t.id);
        const target = window.getSeasonTarget(memberId, t.id, season.id);
        return (
          <div key={t.id} style={{
            display: 'grid', gridTemplateColumns: '1fr 80px', gap: 12,
            padding: '12px 14px', alignItems: 'center',
            borderBottom: i < tests.length - 1 ? '1px solid var(--border-faint)' : 'none',
          }}>
            <div>
              <div style={{ fontSize: 13, fontWeight: 500 }}>{t.name}</div>
              <div style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--fg-subtle)', marginTop: 2 }}>
                Nu: {current != null ? current : '—'} {t.unit}
              </div>
            </div>
            <div style={{ textAlign: 'right' }}>
              <TargetCell
                value={target ? target.target_value : null}
                unit={t.unit}
                onChange={(v) => { window.saveSeasonTarget(memberId, t.id, season.id, v); onChange(); }}
                canEdit={canEdit}
              />
            </div>
          </div>
        );
      })}
    </Card>
  );
}

function pagerBtnStyle(disabled) {
  return {
    width: 36, height: 36, borderRadius: 4,
    border: '1px solid var(--border-strong)', background: 'var(--bg-raised)',
    color: disabled ? 'var(--fg-faint)' : 'var(--fg)',
    cursor: disabled ? 'not-allowed' : 'pointer',
    fontSize: 18, fontWeight: 500,
    display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
  };
}

// ============================================================================
// TargetCell — inline-editable number cell
// ============================================================================
function TargetCell({ value, unit, onChange, canEdit }) {
  const [editing, setEditing] = useState(false);
  const [draft, setDraft] = useState(value != null ? String(value) : '');

  useEffect(() => { setDraft(value != null ? String(value) : ''); }, [value]);

  const commit = () => {
    setEditing(false);
    if (draft === '' && value == null) return;
    const n = draft === '' ? null : Number(draft);
    if (n !== value && (n == null || !isNaN(n))) onChange(n);
  };

  if (!canEdit) {
    return (
      <div style={{ fontFamily: 'var(--font-mono)', fontSize: 13, color: value == null ? 'var(--fg-faint)' : 'var(--fg)', fontVariantNumeric: 'tabular-nums' }}>
        {value == null ? '—' : value}
      </div>
    );
  }

  if (editing) {
    return (
      <input
        type="number"
        step="0.01"
        autoFocus
        value={draft}
        onChange={e => setDraft(e.target.value)}
        onBlur={commit}
        onKeyDown={e => { if (e.key === 'Enter') commit(); if (e.key === 'Escape') { setDraft(value != null ? String(value) : ''); setEditing(false); } }}
        style={{
          fontFamily: 'var(--font-mono)', fontSize: 13, fontVariantNumeric: 'tabular-nums',
          width: 80, textAlign: 'right',
          padding: '4px 6px', border: '1px solid var(--signal)', borderRadius: 3,
          outline: 'none', background: '#fff', color: 'var(--fg)',
          boxShadow: '0 0 0 3px rgba(14,133,67,0.18)',
        }}
      />
    );
  }

  return (
    <button
      onClick={() => setEditing(true)}
      style={{
        fontFamily: 'var(--font-mono)', fontSize: 13, fontVariantNumeric: 'tabular-nums',
        background: 'none', border: 'none', cursor: 'pointer',
        color: value == null ? 'var(--fg-faint)' : 'var(--fg)',
        padding: '4px 6px', borderRadius: 3,
      }}
      onMouseEnter={e => e.currentTarget.style.background = 'var(--ink-25)'}
      onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
    >
      {value == null ? '—' : value}
    </button>
  );
}

window.SasongsplanView = SasongsplanView;
