/* Task detail: the brief, the pipeline stepper, and whatever the deliverable is
   — uploaded cuts for a video ad, a Figma link for a static. */

const MEMBER_STATUSES = ['AD ASSIGNED', 'AD IN PROGRESS', 'AD SENT INTERNALLY', 'AD REVISION'];

function Stepper({ status, canSet, onSet }) {
  const current = STATUS_ORDER.indexOf(status);
  return (
    <div className="stepper">
      {STATUS_ORDER.map((s, i) => {
        const color = STATUS_COLORS[s];
        const isCurrent = i === current;
        const allowed = canSet(s);
        return (
          <button
            key={s}
            className={'step' + (isCurrent ? ' current' : i < current ? ' done' : '') + (allowed ? '' : ' disabled')}
            style={isCurrent ? { background: color } : i < current ? { borderColor: color + '66' } : undefined}
            onClick={() => allowed && !isCurrent && onSet(s)}
            title={allowed ? `Move to ${s}` : 'Only an admin can set this'}
          >
            {!isCurrent && <span className="dot" style={{ background: i < current ? color : 'var(--border-strong)' }} />}
            {STATUS_SHORT[s]}
          </button>
        );
      })}
    </div>
  );
}

function VersionRow({ version, onOpen, onRetry }) {
  const processing = version.status === 'processing';
  return (
    <div className="card card-pad" style={{ marginBottom: 10 }}>
      <div className="row">
        {version.poster_url
          ? <img src={version.poster_url} alt="" style={{ width: 54, height: 76, objectFit: 'cover', borderRadius: 6, background: '#0b1220' }} />
          : <div style={{ width: 54, height: 76, borderRadius: 6, background: '#0b1220', display: 'grid', placeItems: 'center' }}>
              <Icon name="video" size={18} color="#64748b" />
            </div>}
        <div style={{ flex: 1, minWidth: 0 }}>
          <div className="row" style={{ gap: 8 }}>
            <strong>v{version.version_number}</strong>
            {version.label && <span className="chip blue">{version.label}</span>}
            {version.status === 'ready' && version.duration_ms != null && (
              <span className="small muted">{timecode(version.duration_ms)} · {version.width}×{version.height}
                {version.fps ? ` · ${version.fps.toFixed(2)} fps` : ''}</span>
            )}
            {version.status === 'failed' && <span className="chip red">failed</span>}
            {version.drive_file_url && <span className="chip green"><Icon name="check" size={11} />on Drive</span>}
            {version.original_deleted && !version.drive_file_url && <span className="chip">source cleared</span>}
          </div>
          <div className="small muted" style={{ marginTop: 3 }}>
            {version.original_filename} · {bytes(version.original_size_bytes)} · {ago(version.created_at)}
          </div>
          {processing && (
            <div style={{ marginTop: 8 }}>
              <div className="progress"><div style={{ width: `${version.processing_progress || 3}%` }} /></div>
              <div className="small muted" style={{ marginTop: 4 }}>
                Preparing for review… {version.processing_progress || 0}%
              </div>
            </div>
          )}
          {version.status === 'failed' && (
            <div className="small" style={{ color: 'var(--red)', marginTop: 6, wordBreak: 'break-word' }}>
              {version.error}
            </div>
          )}
        </div>
        {version.status === 'ready' && (
          <button className="btn primary sm" onClick={() => onOpen(version.id)}>Review</button>
        )}
        {version.status === 'failed' && !version.original_deleted && (
          <button className="btn sm" onClick={() => onRetry(version.id)}>Retry</button>
        )}
      </div>
    </div>
  );
}

function UploadZone({ taskId, batch, onDone }) {
  const [busy, setBusy] = React.useState(false);
  const [progress, setProgress] = React.useState(0);
  const [over, setOver] = React.useState(false);
  const [label, setLabel] = React.useState('');
  const inputRef = React.useRef(null);

  const start = (file) => {
    if (!file) return;
    if (!/^video\//.test(file.type) && !/\.(mp4|mov|m4v|webm|avi|mkv)$/i.test(file.name)) {
      toast('That is not a video file', 'error');
      return;
    }
    setBusy(true);
    setProgress(0);
    uploadVideo(taskId, file, { onProgress: setProgress, label: label.trim() || null })
      .then((version) => { toast(`v${version.version_number} uploaded, preparing for review`); setLabel(''); onDone(version); })
      .catch((e) => toast(e.message || 'Upload failed', 'error'))
      .finally(() => { setBusy(false); setProgress(0); });
  };

  if (busy) {
    return (
      <div className="card card-pad">
        <div className="row" style={{ marginBottom: 8 }}>
          <Icon name="upload" size={16} />
          <strong>Uploading… {progress}%</strong>
          <span className="spacer" />
          <span className="small muted">Safe to keep working — a dropped connection resumes.</span>
        </div>
        <div className="progress"><div style={{ width: `${progress}%` }} /></div>
      </div>
    );
  }

  return (
    <>
    {batch > 1 && (
      <div className="row" style={{ marginBottom: 8 }}>
        <input className="input" style={{ maxWidth: 320 }} value={label}
               placeholder="Name this cut (e.g. Caviar, Hook B)"
               onChange={(e) => setLabel(e.target.value)} />
        <span className="small muted">This task covers {batch} ads — naming each cut keeps the notes apart.</span>
      </div>
    )}
    <div
      className={'dropzone' + (over ? ' over' : '')}
      onClick={() => inputRef.current.click()}
      onDragOver={(e) => { e.preventDefault(); setOver(true); }}
      onDragLeave={() => setOver(false)}
      onDrop={(e) => { e.preventDefault(); setOver(false); start(e.dataTransfer.files[0]); }}
    >
      <input ref={inputRef} type="file" accept="video/*" style={{ display: 'none' }}
             onChange={(e) => { start(e.target.files[0]); e.target.value = ''; }} />
      <Icon name="upload" size={22} />
      <div style={{ marginTop: 8, fontWeight: 600 }}>Drop a cut here, or click to choose</div>
      <div className="small" style={{ marginTop: 4 }}>Uploads resume by themselves if the connection drops</div>
    </div>
    </>
  );
}

function DetailRow({ label, children }) {
  return (
    <div className="detail-row">
      <span className="detail-label">{label}</span>
      <div className="detail-value">{children}</div>
    </div>
  );
}

function TaskScreen({ taskId, go, me, directory }) {
  const [data, setData] = React.useState(null);
  const [editing, setEditing] = React.useState(false);
  const [form, setForm] = React.useState({});

  const load = React.useCallback(() => {
    api.get(`/api/tasks/${taskId}`)
      .then((d) => { setData(d); setForm({ ...d.task }); })
      .catch((e) => toast(e.message, 'error'));
  }, [taskId]);

  React.useEffect(load, [load]);

  // While a version is transcoding, poll so the bar actually moves.
  React.useEffect(() => {
    if (!data) return;
    const processing = data.versions.filter((v) => v.status === 'processing');
    if (!processing.length) return;
    const t = setInterval(() => {
      Promise.all(processing.map((v) => api.get(`/api/videos/${v.id}`).catch(() => null)))
        .then((rows) => {
          const fresh = rows.filter(Boolean);
          if (!fresh.length) return;
          setData((d) => ({
            ...d,
            versions: d.versions.map((v) => fresh.find((f) => f.id === v.id) || v),
          }));
        });
    }, 2500);
    return () => clearInterval(t);
  }, [data]);

  if (!data) return <div className="empty">Loading…</div>;

  const task = data.task;
  const client = directory.byId[task.client_id];
  const people = (task.assignee_ids || []).map((id) => directory.byId[id]).filter(Boolean);
  const isMine = (task.assignee_ids || []).includes(me.id);
  const canEdit = me.role === 'admin' || isMine;
  const canSet = (s) => me.role === 'admin' || (isMine && MEMBER_STATUSES.includes(s));
  const due = dueLabel(task.due_date);
  const isStatic = task.type === 'static';

  const setStatus = (status) => {
    api.post(`/api/tasks/${taskId}/status`, { status })
      .then(() => {
        if (status === 'AD CONFIRMED') toast('Confirmed — publishing the final cut to Drive');
        load();
      })
      .catch((e) => toast(e.message, 'error'));
  };

  const save = () => {
    const patch = {
      title: form.title,
      video_length: task.type === 'video' ? (form.video_length || 'short') : null,
      description: form.description,
      script: form.script,
      angle: form.angle || null,
      format: form.format || null,
      delivery_url: form.delivery_url || null,
      source_url: form.source_url || null,
      due_date: form.due_date || null,
      delivery_month: form.delivery_month || null,
      drive_target_folder_url: (form.drive_target_folder_url || '').trim() || null,
    };
    if (me.role === 'admin') {
      patch.assignee_ids = form.assignee_ids || [];
      patch.client_id = form.client_id;
      patch.type = form.type;
    }
    api.patch(`/api/tasks/${taskId}`, patch)
      .then(() => { toast('Saved'); setEditing(false); load(); })
      .catch((e) => toast(e.message, 'error'));
  };

  if (editing) {
    return (
      <>
        <h2 style={{ margin: '0 0 16px', fontSize: 20 }}>Edit task</h2>
        <div className="card card-pad" style={{ maxWidth: 620 }}>
          <TaskForm
            form={form}
            set={(k, v) => setForm((f) => ({ ...f, [k]: v }))}
            clients={directory.clients}
            users={directory.users}
          />
          <div className="row">
            <button className="btn primary" onClick={save}>Save changes</button>
            <button className="btn" onClick={() => { setEditing(false); setForm({ ...task }); }}>Cancel</button>
          </div>
        </div>
      </>
    );
  }

  return (
    <>
      <div className="row wrap" style={{ marginBottom: 6 }}>
        <span className="chip" style={{ borderColor: (client && client.color) || undefined }}>
          <span className="dot" style={{ background: (client && client.color) || 'var(--border-strong)' }} />
          {client ? client.name : '—'}
        </span>
        <span className="chip"><Icon name={isStatic ? 'image' : 'video'} size={12} />
          {isStatic ? 'Static ad' : 'Video ad'}</span>
        {task.quantity > 1 && <span className="chip">×{task.quantity} ads</span>}
        {task.angle && <span className="chip">{task.angle}</span>}
        {task.format && <span className="chip">{task.format}</span>}
        {due && <span className={'chip ' + due.tone}><Icon name="clock" size={11} />{due.text}</span>}
        {task.clickup_url && (
          <a className="chip" href={task.clickup_url} target="_blank" rel="noreferrer">
            <Icon name="external" size={11} />ClickUp
          </a>
        )}
      </div>

      <div className="row" style={{ marginBottom: 16 }}>
        <h2 style={{ margin: 0, fontSize: 22, letterSpacing: '-0.02em' }}>{task.title}</h2>
        <span className="spacer" />
        {canEdit && <button className="btn sm" onClick={() => setEditing(true)}>Edit task</button>}
      </div>

      <div style={{ marginBottom: 20 }}>
        <Stepper status={task.status} canSet={canSet} onSet={setStatus} />
      </div>

      <div className="grid-2">
        <div className="stack">
          {!isStatic ? (
            <>
              <div className="card card-pad">
                <div className="row" style={{ marginBottom: 12 }}>
                  <strong>Cuts</strong>
                  <span className="spacer" />
                  <span className="small muted">{data.versions.length} version{data.versions.length === 1 ? '' : 's'}</span>
                </div>
                {data.versions.length === 0 && (
                  <p className="small muted" style={{ margin: '0 0 12px' }}>No cut uploaded yet.</p>
                )}
                {data.versions.map((v) => (
                  <VersionRow
                    key={v.id}
                    version={v}
                    onOpen={(id) => go('review', id)}
                    onRetry={(id) => api.post(`/api/videos/${id}/retry`).then(load).catch((e) => toast(e.message, 'error'))}
                  />
                ))}
              </div>
              <UploadZone taskId={taskId} batch={task.quantity} onDone={load} />
            </>
          ) : (
            <div className="card card-pad">
              <div className="row" style={{ marginBottom: 12 }}><strong>Figma deliverable</strong></div>
              {task.delivery_url ? (
                <>
                  <a className="btn primary" href={task.delivery_url} target="_blank" rel="noreferrer">
                    <Icon name="external" size={15} />Open in Figma
                  </a>
                  <p className="small muted" style={{ marginTop: 10, marginBottom: 0, wordBreak: 'break-all' }}>
                    {task.delivery_url}
                  </p>
                  <p className="small muted" style={{ marginTop: 10, marginBottom: 0 }}>
                    Review comments stay in Figma. Move the task along the pipeline here.
                  </p>
                </>
              ) : (
                <div className="stack">
                  <p className="small muted" style={{ margin: 0 }}>No Figma link yet.</p>
                  {canEdit && (
                    <div className="row">
                      <input className="input" placeholder="https://figma.com/design/…"
                             value={form.delivery_url || ''}
                             onChange={(e) => setForm((f) => ({ ...f, delivery_url: e.target.value }))} />
                      <button className="btn primary" onClick={save}>Save</button>
                    </div>
                  )}
                </div>
              )}
            </div>
          )}

          <div className="card card-pad">
            <div className="row" style={{ marginBottom: 10 }}><strong>Instructions</strong></div>
            <p style={{ margin: 0, whiteSpace: 'pre-wrap', lineHeight: 1.55, color: task.description ? undefined : 'var(--text-dim)' }}>
              {task.description || 'No instructions written.'}
            </p>
          </div>

          {task.script && (
            <div className="card card-pad">
              <div className="row" style={{ marginBottom: 10 }}><strong>Script / copy</strong></div>
              <p style={{ margin: 0, whiteSpace: 'pre-wrap', lineHeight: 1.6 }}>{task.script}</p>
            </div>
          )}
        </div>

        <div className="stack">
          <div className="card card-pad">
            <DetailRow label="Assigned to">
              {people.length ? (
                <div className="stack" style={{ gap: 7 }}>
                  {people.map((u) => (
                    <div className="row" key={u.id} style={{ gap: 8 }}>
                      <Avatar user={u} />
                      <div>
                        <div style={{ fontWeight: 600, fontSize: 13 }}>{u.name || u.email}</div>
                        <div className="small muted">{u.job_title || u.role}</div>
                      </div>
                    </div>
                  ))}
                </div>
              ) : <span className="muted">Nobody yet</span>}
            </DetailRow>

            <DetailRow label="Deadline">
              {task.due_date
                ? <span className={due.tone ? 'chip ' + due.tone : ''}>
                    {new Date(task.due_date + 'T00:00:00').toLocaleDateString('en-GB', { day: 'numeric', month: 'long', year: 'numeric' })}
                    {due.tone ? ` · ${due.text}` : ''}
                  </span>
                : <span className="muted">Not set</span>}
            </DetailRow>

            {task.effort_days > 0 && (
              <DetailRow label="Editing load">
                {task.effort_days} {task.effort_days === 1 ? 'day' : 'days'}
                <span className="muted"> · {task.quantity}× {task.video_length === 'long' ? 'long' : 'short'}</span>
              </DetailRow>
            )}

            <DetailRow label="Delivery month">
              {task.delivery_month ? monthLabel(task.delivery_month) : <span className="muted">Not set</span>}
            </DetailRow>

            <DetailRow label="Created">
              {new Date(task.created_at).toLocaleDateString('en-GB', { day: 'numeric', month: 'long', year: 'numeric' })}
              <span className="muted"> · {ago(task.created_at)}</span>
            </DetailRow>

            <DetailRow label={isStatic ? 'Figma link' : 'Delivery link'}>
              {task.delivery_url
                ? <a href={task.delivery_url} target="_blank" rel="noreferrer">
                    {isStatic ? 'Open in Figma' : 'Open on Drive'}
                  </a>
                : <span className="muted">{isStatic ? 'Not delivered yet' : 'Filled when the ad is confirmed'}</span>}
            </DetailRow>

            <DetailRow label="Cartella su Drive">
              {task.drive_target_folder_url
                ? <a href={task.drive_target_folder_url} target="_blank" rel="noreferrer">Cartella scelta a mano</a>
                : <span className="mono">{task.drive_path}</span>}
              <div className="small muted" style={{ marginTop: 3 }}>
                Ci finisce quando approvi, non prima: fino ad allora il file sta solo qui.
              </div>
            </DetailRow>

            <DetailRow label="Source material">
              {task.source_url
                ? <a href={task.source_url} target="_blank" rel="noreferrer">Open folder</a>
                : <span className="muted">Not set</span>}
            </DetailRow>
          </div>

          {task.drive_folder_url && (
            <div className="card card-pad">
              <div className="row" style={{ marginBottom: 10 }}><strong>Published</strong></div>
              <a className="btn" href={task.drive_folder_url} target="_blank" rel="noreferrer">
                <Icon name="drive" size={15} />Open the Drive folder
              </a>
            </div>
          )}

          <div className="card card-pad">
            <div className="row" style={{ marginBottom: 12 }}><strong>History</strong></div>
            <div className="stack" style={{ gap: 12 }}>
              {data.history.map((h) => {
                const who = directory.byId[h.changed_by_id];
                return (
                  <div key={h.id} className="row" style={{ alignItems: 'flex-start', gap: 8 }}>
                    <span className="dot" style={{ background: STATUS_COLORS[h.to_status], marginTop: 6 }} />
                    <div>
                      <div className="small" style={{ fontWeight: 600 }}>{STATUS_SHORT[h.to_status] || h.to_status}</div>
                      <div className="small muted">
                        {who ? (who.name || who.email) : 'Studio'} · {ago(h.created_at)}
                      </div>
                      {h.note && <div className="small muted" style={{ marginTop: 2 }}>{h.note}</div>}
                    </div>
                  </div>
                );
              })}
            </div>
          </div>

          {me.role === 'admin' && (
            <button className="btn danger" onClick={() => {
              if (!confirm('Delete this task and every cut on it?')) return;
              api.del(`/api/tasks/${taskId}`).then(() => { toast('Task deleted'); go('board'); })
                .catch((e) => toast(e.message, 'error'));
            }}>
              <Icon name="trash" size={15} />Delete task
            </button>
          )}
        </div>
      </div>
    </>
  );
}
