// Responses & analytics screen — list, detail, CSV export

function ResponsesScreen({ survey, onBack, onOpenPublic }) {
  const [responses, setResponses] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [sel, setSel] = React.useState(null);
  const [query, setQuery] = React.useState('');
  const [filter, setFilter] = React.useState('all');

  React.useEffect(() => {
    let cancelled = false;
    setLoading(true);
    fetch('/api/surveys/' + survey.id + '/responses', { credentials: 'same-origin' })
      .then(r => r.json())
      .then(list => {
        if (cancelled) return;
        setResponses(list.map(r => ({ ...r, submittedAt: new Date(r.submittedAt) })));
      })
      .finally(() => { if (!cancelled) setLoading(false); });
    return () => { cancelled = true; };
  }, [survey.id]);

  const cols = React.useMemo(() => {
    const qs = survey.questions || [];
    const firstOfType = (...types) => qs.find(q => types.includes(q.type));
    return {
      primary: firstOfType('short', 'single', 'dropdown'),
      secondary: firstOfType('long') || firstOfType('multi'),
      score: firstOfType('scale'),
    };
  }, [survey]);

  const filtered = responses.filter(r => {
    if (filter === 'complete' && !r.complete) return false;
    if (filter === 'partial' && r.complete) return false;
    if (query) {
      const q = query.toLowerCase();
      const hay = JSON.stringify(r.answers).toLowerCase();
      if (!hay.includes(q)) return false;
    }
    return true;
  });

  const stats = React.useMemo(() => {
    const total = responses.length;
    if (total === 0) return { total: 0, complete: 0, completionRate: 0, avgDur: 0, goalPct: 0 };
    const complete = responses.filter(r => r.complete).length;
    const avgDur = Math.round(responses.reduce((s, r) => s + (r.durationSec || 0), 0) / total);
    return {
      total, complete, avgDur,
      completionRate: Math.round((complete / total) * 100),
      goalPct: survey.goal > 0 ? Math.round((total / survey.goal) * 100) : 0,
    };
  }, [responses, survey.goal]);

  const exportCSV = () => {
    window.location.href = '/api/surveys/' + survey.id + '/export.csv';
  };

  return (
    <div style={{ minHeight: '100vh', background: 'var(--paper)' }}>
      <AdminTopbar active="surveys" onLogout={() => {}} />

      <div style={{ borderBottom: '1px solid var(--line)', background: 'var(--paper)', position: 'sticky', top: 69, zIndex: 9 }}>
        <div style={{ maxWidth: 1400, margin: '0 auto', padding: '16px 40px', display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap' }}>
          <button className="btn btn-text" onClick={onBack} style={{ color: 'var(--muted)' }}>
            {Icon.back(14)} Surveys
          </button>
          <span style={{ color: 'var(--line-2)' }}>/</span>
          <span style={{ fontFamily: 'var(--font-display)', fontSize: 22 }}>{survey.title}</span>
          <span style={{ color: 'var(--line-2)' }}>/</span>
          <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.16em', textTransform: 'uppercase', color: 'var(--red)' }}>
            Responses
          </span>

          <div style={{ flex: 1 }} />

          {survey.status === 'live' && (
            <button className="btn btn-ghost" onClick={onOpenPublic}>{Icon.eye(14)} Open public link</button>
          )}
          <button className="btn btn-red" onClick={exportCSV} disabled={responses.length === 0} style={{ opacity: responses.length === 0 ? 0.5 : 1 }}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
              <path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M7 10l5 5 5-5M12 15V3"/>
            </svg>
            Export CSV ({responses.length})
          </button>
        </div>
      </div>

      <div style={{ maxWidth: 1400, margin: '0 auto', padding: '32px 40px 80px' }}>
        <div style={{
          display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 0,
          border: '1px solid var(--line)', borderRadius: 2, marginBottom: 32, background: 'var(--paper)',
        }}>
          <StatCell label="Total responses" value={stats.total.toLocaleString()} sub={loading ? 'loading…' : 'updated just now'}/>
          <StatCell label="Completion rate" value={stats.completionRate + '%'} sub={stats.complete + ' complete · ' + (stats.total - stats.complete) + ' partial'} accent/>
          <StatCell label="Avg. duration" value={stats.avgDur > 0 ? (Math.floor(stats.avgDur / 60) + 'm ' + (stats.avgDur % 60) + 's') : '—'} sub="time to submit"/>
          <StatCell label="Goal" value={stats.goalPct + '%'} sub={stats.total + ' of ' + (survey.goal || 0)} last/>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 560px', gap: 32, alignItems: 'flex-start' }}>
          <div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 16, flexWrap: 'wrap' }}>
              <Eyebrow>Stream</Eyebrow>
              <div style={{ flex: 1 }}/>
              {[['all', 'All'], ['complete', 'Complete'], ['partial', 'Partial']].map(([id, label]) => (
                <button key={id} onClick={() => setFilter(id)} style={{
                  border: '1px solid ' + (filter === id ? 'var(--ink)' : 'var(--line)'),
                  background: filter === id ? 'var(--ink)' : 'transparent',
                  color: filter === id ? 'var(--paper)' : 'var(--ink)',
                  padding: '6px 12px', borderRadius: 2, cursor: 'pointer',
                  fontFamily: 'var(--font-ui)', fontSize: 12,
                }}>{label}</button>
              ))}
              <div style={{
                display: 'flex', alignItems: 'center', gap: 8,
                border: '1px solid var(--line)', borderRadius: 2, padding: '6px 10px',
                width: 220, background: 'var(--paper-2)',
              }}>
                <span style={{ color: 'var(--muted)', display: 'flex' }}>{Icon.search(12)}</span>
                <input value={query} onChange={e => setQuery(e.target.value)} placeholder="Search answers…"
                  style={{ border: 0, background: 'transparent', outline: 'none', flex: 1, fontFamily: 'var(--font-ui)', fontSize: 12 }}/>
              </div>
            </div>

            <div style={{ border: '1px solid var(--line)', borderRadius: 2, background: 'var(--paper)' }}>
              <div style={{
                display: 'grid', gridTemplateColumns: '40px 1.3fr 1.3fr 1fr 70px 40px',
                padding: '12px 18px', background: 'var(--paper-2)', borderBottom: '1px solid var(--line)',
                fontFamily: 'var(--font-mono)', fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.14em', color: 'var(--muted)',
              }}>
                <div>№</div>
                <div>Submitted</div>
                <div>{cols.primary ? truncate(cols.primary.title, 20) : 'Preview'}</div>
                <div>{cols.secondary ? truncate(cols.secondary.title, 20) : ''}</div>
                <div>{cols.score ? 'Score' : ''}</div>
                <div></div>
              </div>
              <div style={{ maxHeight: 560, overflow: 'auto' }}>
                {loading && (
                  <div style={{ padding: 40, textAlign: 'center', color: 'var(--muted)', fontSize: 13 }}>Loading…</div>
                )}
                {!loading && filtered.map((r, i) => (
                  <ResponseRow key={r.id} r={r} idx={i + 1} cols={cols}
                    active={sel?.id === r.id} onClick={() => setSel(r)}/>
                ))}
                {!loading && filtered.length === 0 && (
                  <div style={{ padding: 40, textAlign: 'center', color: 'var(--muted)', fontSize: 13 }}>
                    {responses.length === 0 ? 'No responses yet.' : 'No responses match.'}
                  </div>
                )}
              </div>
            </div>
          </div>

          <div style={{ position: 'sticky', top: 150 }}>
            {sel ? (
              <ResponseDetail r={sel} survey={survey} onClose={() => setSel(null)}/>
            ) : (
              <div style={{
                border: '1px dashed var(--line)', borderRadius: 2, padding: 48,
                textAlign: 'center', color: 'var(--muted)', fontSize: 13, lineHeight: 1.6,
              }}>
                <div style={{ marginBottom: 12 }}>{Icon.eye(20)}</div>
                Select a response to read the full submission.
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

function truncate(s, n) {
  if (!s) return '';
  return s.length > n ? s.slice(0, n - 1) + '…' : s;
}

function previewAnswer(v) {
  if (v === undefined || v === null || v === '') return <span style={{ color: 'var(--muted-2)' }}>—</span>;
  if (Array.isArray(v)) return v.join(', ');
  const s = String(v);
  return s.length > 48 ? s.slice(0, 46) + '…' : s;
}

function StatCell({ label, value, sub, accent, last }) {
  return (
    <div style={{
      padding: '20px 22px', borderRight: last ? 'none' : '1px solid var(--line)',
    }}>
      <div style={{ fontFamily: 'var(--font-mono)', fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.16em', color: 'var(--muted)' }}>
        {label}
      </div>
      <div style={{ fontFamily: 'var(--font-display)', fontSize: 40, lineHeight: 1, margin: '12px 0 8px', color: accent ? 'var(--red)' : 'var(--ink)' }}>
        {value}
      </div>
      <div style={{ fontSize: 11, color: 'var(--muted)' }}>{sub}</div>
    </div>
  );
}

function ResponseRow({ r, idx, cols, active, onClick }) {
  const primary = cols.primary ? r.answers[cols.primary.id] : undefined;
  const secondary = cols.secondary ? r.answers[cols.secondary.id] : undefined;
  const score = cols.score ? r.answers[cols.score.id] : undefined;
  return (
    <div onClick={onClick} style={{
      display: 'grid', gridTemplateColumns: '40px 1.3fr 1.3fr 1fr 70px 40px',
      padding: '14px 18px', borderBottom: '1px solid var(--line)',
      alignItems: 'center', cursor: 'pointer', fontSize: 13,
      background: active ? 'var(--paper-2)' : 'transparent',
      borderLeft: active ? '2px solid var(--red)' : '2px solid transparent',
      transition: 'background .12s',
    }}
    onMouseEnter={e => { if (!active) e.currentTarget.style.background = 'var(--paper-2)'; }}
    onMouseLeave={e => { if (!active) e.currentTarget.style.background = 'transparent'; }}
    >
      <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--muted)' }}>
        {String(idx).padStart(3, '0')}
      </div>
      <div style={{ minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, lineHeight: 1.2 }}>
          <span className="dot" style={{ background: r.complete ? 'var(--red)' : 'var(--muted-2)' }}/>
          <span style={{ fontFamily: 'var(--font-mono)', fontSize: 12 }}>{formatRelative(r.submittedAt)}</span>
        </div>
        <div style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--muted)', marginTop: 6, lineHeight: 1.3, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
          {r.id}{r.durationSec ? ` · ${Math.floor(r.durationSec / 60)}m${r.durationSec % 60}s` : ''}
        </div>
      </div>
      <div style={{ fontSize: 13, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
        {previewAnswer(primary)}
      </div>
      <div style={{ fontSize: 13, color: 'var(--muted)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
        {previewAnswer(secondary)}
      </div>
      <div style={{ fontFamily: 'var(--font-display)', fontSize: 18 }}>
        {score !== undefined && score !== null && score !== '' ? score : ''}
      </div>
      <div style={{ textAlign: 'right', color: 'var(--muted)' }}>{Icon.arrow(14)}</div>
    </div>
  );
}

function ResponseDetail({ r, survey, onClose }) {
  return (
    <div className="fade-in" key={r.id} style={{
      background: 'var(--paper)', border: '1px solid var(--line)', borderRadius: 2,
      maxHeight: 'calc(100vh - 180px)', overflow: 'auto',
    }}>
      <div style={{
        padding: '20px 24px', borderBottom: '1px solid var(--line)',
        display: 'flex', alignItems: 'center', gap: 10,
        position: 'sticky', top: 0, background: 'var(--paper)', zIndex: 2,
      }}>
        <span className="dot" style={{ background: r.complete ? 'var(--red)' : 'var(--muted-2)' }}/>
        <div style={{ flex: 1 }}>
          <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--muted)' }}>{r.id}</div>
          <div style={{ fontSize: 13, marginTop: 2 }}>{r.submittedAt.toLocaleString('en-GB', { dateStyle: 'medium', timeStyle: 'short' })}</div>
        </div>
        <button className="btn btn-text" onClick={onClose} style={{ color: 'var(--muted)' }}>{Icon.x(14)}</button>
      </div>

      <div style={{ padding: '4px 24px', display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 0, borderBottom: '1px solid var(--line)' }}>
        <MiniStat label="Status" value={r.complete ? 'Complete' : 'Partial'}/>
        <MiniStat label="Duration" value={r.durationSec > 0 ? (Math.floor(r.durationSec / 60) + 'm ' + (r.durationSec % 60) + 's') : '—'}/>
        <MiniStat label="Source" value={r.source} last/>
      </div>

      <div style={{ padding: '8px 24px 24px' }}>
        {survey.questions.map((q, i) => {
          const v = r.answers[q.id];
          return (
            <div key={q.id} style={{ padding: '20px 0', borderBottom: '1px solid var(--line)' }}>
              <div style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--muted)', letterSpacing: '0.14em', marginBottom: 6 }}>
                Q {String(i + 1).padStart(2, '0')}
                {q.required && <span style={{ color: 'var(--red)', marginLeft: 8 }}>required</span>}
              </div>
              <div style={{ fontFamily: 'var(--font-display)', fontSize: 17, lineHeight: 1.3, marginBottom: 10, color: 'var(--ink)' }}>
                {q.title}
              </div>
              <AnswerRender q={q} v={v}/>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function MiniStat({ label, value, last }) {
  return (
    <div style={{ padding: '14px 0', borderRight: last ? 'none' : '1px solid var(--line)', paddingRight: 14 }}>
      <div style={{ fontFamily: 'var(--font-mono)', fontSize: 9, textTransform: 'uppercase', letterSpacing: '0.14em', color: 'var(--muted)' }}>{label}</div>
      <div style={{ fontSize: 14, marginTop: 4, textTransform: 'capitalize' }}>{value}</div>
    </div>
  );
}

function AnswerRender({ q, v }) {
  if (v === undefined || v === '' || v === null || (Array.isArray(v) && v.length === 0)) {
    return <div style={{ fontSize: 13, color: 'var(--muted-2)', fontStyle: 'italic' }}>— no answer —</div>;
  }
  if (q.type === 'multi' || Array.isArray(v)) {
    return (
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
        {v.map((x, i) => (
          <span key={i} style={{
            padding: '4px 10px', background: 'var(--paper-2)', border: '1px solid var(--line)',
            borderRadius: 2, fontSize: 12,
          }}>{x}</span>
        ))}
      </div>
    );
  }
  if (q.type === 'scale') {
    return (
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 10 }}>
        <span style={{ fontFamily: 'var(--font-display)', fontSize: 28 }}>{v}</span>
        <span style={{ fontSize: 12, color: 'var(--muted)' }}>/ {q.scaleMax}</span>
      </div>
    );
  }
  if (q.type === 'long') {
    return (
      <div style={{
        fontSize: 14, lineHeight: 1.6, color: 'var(--ink)',
        borderLeft: '2px solid var(--red)', paddingLeft: 14,
        fontFamily: 'var(--font-display)', fontStyle: 'italic', whiteSpace: 'pre-wrap',
      }}>
        "{v}"
      </div>
    );
  }
  return <div style={{ fontSize: 14 }}>{v}</div>;
}

function formatRelative(d) {
  const diff = (Date.now() - d.getTime()) / 1000;
  if (diff < 60) return 'just now';
  if (diff < 3600) return Math.floor(diff / 60) + 'm ago';
  if (diff < 86400) return Math.floor(diff / 3600) + 'h ago';
  const days = Math.floor(diff / 86400);
  if (days < 30) return days + 'd ago';
  return d.toLocaleDateString('en-GB', { day: '2-digit', month: 'short' });
}

window.ResponsesScreen = ResponsesScreen;
