/* Review screen: the player on the left, the notes on the right.

   A note always carries the exact moment it was written at. Optionally it also
   carries a pin or a drawing on the frame — click the picture with the pin tool,
   or scribble with the pen. */

function CommentItem({ comment, replies, author, directory, active, onActivate, onResolve, onDelete, me, index }) {
  return (
    <div className={'comment' + (active ? ' active' : '') + (comment.resolved ? ' resolved' : '')}
         onClick={() => onActivate(comment)}>
      <div className="head">
        <Avatar user={author} />
        <strong className="small">{author ? (author.name || author.email) : 'Someone'}</strong>
        <span className="stamp">{timecode(comment.timestamp_ms)}{comment.frame != null ? ` · f${comment.frame}` : ''}</span>
        {comment.kind === 'client' && <span className="chip">client</span>}
        {(comment.x != null || comment.drawing) && <span className="chip">#{index}</span>}
        <span className="spacer" />
        <button className="btn ghost sm" title={comment.resolved ? 'Reopen' : 'Mark done'}
                onClick={(e) => { e.stopPropagation(); onResolve(comment); }}>
          <Icon name="check" size={14} color={comment.resolved ? 'var(--green)' : 'var(--text-dim)'} />
        </button>
        {(comment.author_id === me.id || me.role === 'admin') && (
          <button className="btn ghost sm" title="Delete"
                  onClick={(e) => { e.stopPropagation(); onDelete(comment); }}>
            <Icon name="x" size={14} />
          </button>
        )}
      </div>
      <div className="body">{comment.body}</div>
      {replies.map((r) => {
        const who = directory.byId[r.author_id];
        return (
          <div key={r.id} style={{ marginTop: 8, paddingLeft: 10, borderLeft: '2px solid var(--border)' }}>
            <div className="small" style={{ fontWeight: 600 }}>{who ? (who.name || who.email) : 'Someone'}</div>
            <div className="small" style={{ whiteSpace: 'pre-wrap' }}>{r.body}</div>
          </div>
        );
      })}
    </div>
  );
}

function ReviewScreen({ versionId, go, me, directory }) {
  const [version, setVersion] = React.useState(null);
  const [task, setTask] = React.useState(null);
  const [versions, setVersions] = React.useState([]);
  const [comments, setComments] = React.useState([]);
  const [activeId, setActiveId] = React.useState(null);
  const [tool, setTool] = React.useState('none');
  const [draft, setDraft] = React.useState(null);
  const [text, setText] = React.useState('');
  const [replyTo, setReplyTo] = React.useState(null);
  const [showResolved, setShowResolved] = React.useState(false);
  const [nowMs, setNowMs] = React.useState(0);
  const playerRef = React.useRef(null);

  const loadComments = React.useCallback((id) => {
    api.get(`/api/versions/${id}/comments`).then(setComments).catch((e) => toast(e.message, 'error'));
  }, []);

  React.useEffect(() => {
    setDraft(null);
    setTool('none');
    api.get(`/api/videos/${versionId}`)
      .then((v) => {
        setVersion(v);
        loadComments(v.id);
        return api.get(`/api/tasks/${v.task_id}`);
      })
      .then((d) => { setTask(d.task); setVersions(d.versions); })
      .catch((e) => toast(e.message, 'error'));
  }, [versionId, loadComments]);

  if (!version) return <div className="empty">Loading…</div>;
  if (version.status !== 'ready') {
    return (
      <EmptyState
        title={version.status === 'processing' ? 'Still preparing this cut' : 'This cut could not be prepared'}
        hint={version.error || 'Come back in a moment.'}
        action={<button className="btn" onClick={() => go('task', version.task_id)}>Back to task</button>}
      />
    );
  }

  const client = task ? directory.byId[task.client_id] : null;
  const roots = comments.filter((c) => !c.parent_id)
    .filter((c) => showResolved || !c.resolved)
    .sort((a, b) => a.timestamp_ms - b.timestamp_ms);
  const repliesOf = (id) => comments.filter((c) => c.parent_id === id);
  const pinIndex = {};
  comments.filter((c) => c.x != null || c.drawing).forEach((c, i) => { pinIndex[c.id] = i + 1; });

  const startDraft = () => {
    const ms = playerRef.current ? playerRef.current.currentMs() : nowMs;
    playerRef.current && playerRef.current.pause();
    setDraft((d) => d || { timestamp_ms: ms, frame: frameAt(ms, version.fps || 25) });
  };

  const onAnnotate = (payload) => {
    const ms = playerRef.current ? playerRef.current.currentMs() : nowMs;
    setDraft((d) => {
      const base = d || { timestamp_ms: ms, frame: frameAt(ms, version.fps || 25) };
      if (payload.pin) return { ...base, x: payload.pin.x, y: payload.pin.y };
      if (payload.stroke) {
        const strokes = (base.drawing && base.drawing.strokes) || [];
        return { ...base, drawing: { strokes: [...strokes, payload.stroke] } };
      }
      return base;
    });
  };

  const submit = () => {
    if (!text.trim()) return;
    const ms = draft ? draft.timestamp_ms : (playerRef.current ? playerRef.current.currentMs() : nowMs);
    const payload = {
      body: text,
      timestamp_ms: replyTo ? replyTo.timestamp_ms : ms,
      frame: draft ? draft.frame : frameAt(ms, version.fps || 25),
      x: draft ? draft.x : null,
      y: draft ? draft.y : null,
      drawing: draft ? draft.drawing : null,
      parent_id: replyTo ? replyTo.id : null,
    };
    api.post(`/api/versions/${version.id}/comments`, payload)
      .then(() => {
        setText(''); setDraft(null); setReplyTo(null); setTool('none');
        loadComments(version.id);
      })
      .catch((e) => toast(e.message, 'error'));
  };

  const activate = (comment) => {
    setActiveId(comment.id);
    if (playerRef.current) playerRef.current.seekMs(comment.timestamp_ms);
  };

  return (
    <>
      <div className="row" style={{ marginBottom: 12, flexWrap: 'wrap' }}>
        <button className="btn ghost sm" onClick={() => go('task', version.task_id)}>
          <Icon name="back" size={15} />Task
        </button>
        {client && <span className="chip"><span className="dot" style={{ background: client.color || 'var(--border-strong)' }} />{client.name}</span>}
        <strong>{task ? task.title : ''}</strong>
        {version.label && <span className="chip blue">{version.label}</span>}
        {task && <StatusPill status={task.status} />}
        <span className="spacer" />
        {versions.length > 1 && (
          <select className="select" style={{ width: 'auto' }} value={version.id}
                  onChange={(e) => go('review', e.target.value)}>
            {versions.map((v) => (
              <option key={v.id} value={v.id} disabled={v.status !== 'ready'}>
                v{v.version_number}{v.label ? ` · ${v.label}` : ''}{v.status !== 'ready' ? ' (preparing)' : ''}
              </option>
            ))}
          </select>
        )}
      </div>

      <div className="review">
        <VideoPlayer
          ref={playerRef}
          version={version}
          comments={comments}
          activeId={activeId}
          tool={tool}
          draft={draft}
          onActivate={setActiveId}
          onAnnotate={onAnnotate}
          onTimeChange={(ms) => setNowMs(ms)}
        />

        <div className="card" style={{ display: 'flex', flexDirection: 'column', maxHeight: '80vh' }}>
          <div className="row" style={{ padding: '12px 14px', borderBottom: '1px solid var(--border)' }}>
            <strong>Notes</strong>
            <span className="chip">{roots.length}</span>
            <span className="spacer" />
            <label className="row small muted" style={{ gap: 5, cursor: 'pointer' }}>
              <input type="checkbox" checked={showResolved} onChange={(e) => setShowResolved(e.target.checked)} />
              done
            </label>
          </div>

          <div className="stack" style={{ padding: 12, overflowY: 'auto', flex: 1, gap: 8 }}>
            {roots.length === 0 && (
              <p className="small muted" style={{ textAlign: 'center', padding: '20px 0' }}>
                No notes yet. Pause where something is wrong and write one.
              </p>
            )}
            {roots.map((c) => (
              <CommentItem
                key={c.id}
                comment={c}
                replies={repliesOf(c.id)}
                author={directory.byId[c.author_id]}
                directory={directory}
                index={pinIndex[c.id]}
                active={activeId === c.id}
                me={me}
                onActivate={activate}
                onResolve={(cm) => api.patch(`/api/comments/${cm.id}`, { resolved: !cm.resolved })
                  .then(() => loadComments(version.id)).catch((e) => toast(e.message, 'error'))}
                onDelete={(cm) => api.del(`/api/comments/${cm.id}`)
                  .then(() => loadComments(version.id)).catch((e) => toast(e.message, 'error'))}
              />
            ))}
          </div>

          <div style={{ borderTop: '1px solid var(--border)', padding: 12 }}>
            {replyTo && (
              <div className="row small muted" style={{ marginBottom: 8 }}>
                Replying at {timecode(replyTo.timestamp_ms)}
                <button className="btn ghost sm" onClick={() => setReplyTo(null)}><Icon name="x" size={13} /></button>
              </div>
            )}
            <div className="row" style={{ marginBottom: 8, gap: 6 }}>
              <button className={'btn sm' + (tool === 'pin' ? ' primary' : '')}
                      onClick={() => { setTool(tool === 'pin' ? 'none' : 'pin'); startDraft(); }}
                      title="Click the frame to drop a pin">
                <Icon name="plus" size={13} />Pin
              </button>
              <button className={'btn sm' + (tool === 'draw' ? ' primary' : '')}
                      onClick={() => { setTool(tool === 'draw' ? 'none' : 'draw'); startDraft(); }}
                      title="Draw on the frame">
                <Icon name="pen" size={13} />Draw
              </button>
              <span className="spacer" />
              <span className="small muted">
                {draft ? `at ${timecode(draft.timestamp_ms, version.fps)}` : `at ${timecode(nowMs, version.fps)}`}
              </span>
              {draft && (draft.x != null || draft.drawing) && (
                <button className="btn ghost sm" onClick={() => setDraft({ timestamp_ms: draft.timestamp_ms, frame: draft.frame })}
                        title="Clear the annotation">
                  <Icon name="x" size={13} />
                </button>
              )}
            </div>
            <textarea
              className="input"
              style={{ minHeight: 62 }}
              placeholder="Cut 3 frames earlier, the logo pops too late…"
              value={text}
              onFocus={startDraft}
              onChange={(e) => setText(e.target.value)}
              onKeyDown={(e) => { if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) submit(); }}
            />
            <div className="row" style={{ marginTop: 8 }}>
              <button className="btn primary" disabled={!text.trim()} onClick={submit}>Add note</button>
              <span className="spacer" />
              <span className="small muted">← → step a frame · space plays</span>
            </div>
          </div>
        </div>
      </div>
    </>
  );
}
