const DEMO_MEDIA_PATH = 'https://upload.wikimedia.org/wikipedia/commons/1/10/Tears_of_Steel_in_4k_-_Official_Blender_Foundation_release.webm';
const DEMO_PROMPT = 'Find an intense scene that makes the viewer heart race in anticipation.';

const INTENT_OPTIONS = [
  { value: 'find_clips', label: 'Find clips' },
  { value: 'strong_quote', label: 'Strong quote' },
  { value: 'funny_moment', label: 'Funny moment' },
  { value: 'quiet_emotional', label: 'Quiet emotional' },
  { value: 'tutorial_step', label: 'Tutorial step' },
  { value: 'product_demo', label: 'Product demo' },
  { value: 'custom', label: 'Custom prompt' },
];

const PROMPT_BY_INTENT = {
  find_clips: 'Find standalone clips that work outside the full video, with clean boundaries and strong signal evidence.',
  strong_quote: 'Find a self-contained strong quote with one clear speaker, semantic weight, and clean start/end pauses.',
  funny_moment: 'Find a funny moment with laughter, a reaction, energy shift, and a natural pause after the payoff.',
  quiet_emotional: 'Find a quiet emotional moment with reflective language, low energy, single-speaker clarity, and clean pauses.',
  tutorial_step: 'Find a coherent tutorial step with instructional language, topic continuity, screen/text evidence, and useful boundaries.',
  product_demo: 'Find a product reveal or demo moment where the action, visual change, or screen text makes the subject clear.',
};

const ADVANCED_SIGNAL_ENDPOINTS = [
  { id: 'audio/detect-energy', label: 'Energy' },
  { id: 'audio/detect-silence', label: 'Silence' },
  { id: 'audio/detect-laughter', label: 'Laughter' },
  { id: 'audio/detect-speakers', label: 'Speakers' },
  { id: 'audio/semantic-chunks', label: 'Semantic chunks' },
  { id: 'audio/topic-segments', label: 'Topics' },
  { id: 'audio/suggest-cut-points', label: 'Cut points' },
  { id: 'audio/detect-music', label: 'Music' },
  { id: 'video/text-frames', label: 'Text frames' },
  { id: 'video/detect-cuts', label: 'Visual cuts' },
];

const DEFAULT_ADVANCED_PLAN = ['audio/detect-energy', 'audio/detect-silence', 'audio/semantic-chunks', 'audio/suggest-cut-points'];

const isFilePreview = () => window.location.protocol === 'file:';
const isLocalHost = () => ['localhost', '127.0.0.1'].includes(window.location.hostname);
const localApiPath = (path) => isFilePreview() ? `http://127.0.0.1:8787${path}` : path;
const demoMediaUrl = () => DEMO_MEDIA_PATH.startsWith('http')
  ? DEMO_MEDIA_PATH
  : new URL(DEMO_MEDIA_PATH, isFilePreview() ? 'http://127.0.0.1:8787/' : window.location.href).href;
const findMomentsRoots = () => (isFilePreview() || isLocalHost())
  ? [localApiPath('/api/find-moments'), localApiPath('/api/momentiq/v1/moments/find'), localApiPath('/api/momentiq/api/find-moments')]
  : ['/api/find-moments'];
const uploadPresignRoots = () => (isFilePreview() || isLocalHost())
  ? [localApiPath('/api/momentiq/v1/uploads/presign'), localApiPath('/api/lab/uploads/presign')]
  : ['/api/momentiq/v1/uploads/presign'];
const renderJobRoots = () => (isFilePreview() || isLocalHost())
  ? [localApiPath('/api/momentiq/v1/jobs'), localApiPath('/api/lab/jobs')]
  : ['/api/momentiq/v1/jobs'];
const RENDER_MAX_SECONDS = 120;
const RENDER_POLL_MS = 1500;
const RENDER_TIMEOUT_MS = 120000;

const fmtTime = (seconds) => {
  const n = Number(seconds);
  if (!Number.isFinite(n)) return '0:00';
  const whole = Math.max(0, Math.round(n));
  const m = Math.floor(whole / 60);
  const s = whole % 60;
  return `${m}:${String(s).padStart(2, '0')}`;
};

const fmtUsd = (value) => `$${Number(value || 0).toFixed(4)}`;
const prettyJson = (value) => JSON.stringify(value || {}, null, 2);

const jsonFetch = async (url, options = {}) => {
  const response = await fetch(url, {
    ...options,
    headers: { 'Content-Type': 'application/json', ...(options.headers || {}) },
  });
  const payload = await response.json().catch(() => ({}));
  if (!response.ok) {
    const err = new Error(payload?.error?.message || response.statusText || 'MomentIQ request failed.');
    err.payload = payload;
    err.status = response.status;
    err.url = url;
    throw err;
  }
  return payload;
};

const presignUpload = async (file) => {
  const body = {
    filename: file.name,
    bytes: file.size,
    content_type: file.type || undefined,
  };
  let lastError = null;
  for (const root of uploadPresignRoots()) {
    try {
      return await jsonFetch(root, { method: 'POST', body: JSON.stringify(body) });
    } catch (err) {
      lastError = err;
    }
  }
  throw lastError || new Error('Upload presign failed.');
};

const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const renderJobStatusUrl = (root, jobId) => `${root.replace(/\/+$/, '')}/${encodeURIComponent(jobId)}`;
const extractRenderResult = (payload) => payload?.job?.result || payload?.results || payload?.result || payload;
const extractRenderUrl = (result) => result?.url || result?.download_url || result?.output_file?.url || result?.output_file?.public_url || '';

const createRenderJob = async (body) => {
  let lastError = null;
  for (const root of renderJobRoots()) {
    try {
      const payload = await jsonFetch(root, { method: 'POST', body: JSON.stringify(body) });
      return { root, payload };
    } catch (err) {
      lastError = err;
    }
  }
  throw lastError || new Error('Render job creation failed.');
};

const pollRenderJob = async (root, jobId, onUpdate) => {
  const started = Date.now();
  while (Date.now() - started < RENDER_TIMEOUT_MS) {
    const payload = await jsonFetch(renderJobStatusUrl(root, jobId));
    const job = payload?.job || {};
    if (typeof onUpdate === 'function') onUpdate(payload);
    if (job.status === 'completed') return payload;
    if (job.status === 'failed') {
      const err = new Error(job.error?.message || 'Render job failed.');
      err.payload = payload;
      throw err;
    }
    await sleep(RENDER_POLL_MS);
  }
  const err = new Error('Render job is still queued. Check the job ID again shortly.');
  err.payload = { job: { id: jobId, status: 'queued' } };
  throw err;
};

const useFindMoments = () => {
  const [form, setForm] = React.useState({
    media_url: demoMediaUrl(),
    intent: 'custom',
    custom_prompt: DEMO_PROMPT,
    target_duration: 45,
    max_moments: 5,
    render: false,
  });
  const [advanced, setAdvanced] = React.useState({
    enabled: false,
    signal_plan: DEFAULT_ADVANCED_PLAN,
    strictness: 'balanced',
    output_goal: 'clip',
    avoid_cutting_speech: true,
  });
  const [state, setState] = React.useState({
    status: 'idle',
    result: null,
    error: null,
    requestId: null,
    rendering: {},
    upload: { status: 'idle', fileName: '', requestId: null, error: null, mediaUrl: '' },
  });

  const setField = (key, value) => setForm(current => ({ ...current, [key]: value }));
  const setAdvancedField = (key, value) => setAdvanced(current => ({ ...current, [key]: value }));
  const toggleAdvancedEndpoint = (endpoint) => setAdvanced(current => {
    const currentPlan = current.signal_plan || [];
    const signal_plan = currentPlan.includes(endpoint)
      ? currentPlan.filter(item => item !== endpoint)
      : [...currentPlan, endpoint];
    return { ...current, signal_plan };
  });
  const updateUpload = (patch) => setState(current => ({ ...current, upload: { ...current.upload, ...patch } }));
  const setMediaUrl = (value) => {
    setForm(current => ({ ...current, media_url: value }));
    updateUpload({ status: 'idle', fileName: '', requestId: null, error: null, mediaUrl: '' });
  };
  const useDemo = () => {
    setField('media_url', demoMediaUrl());
    updateUpload({ status: 'idle', fileName: '', requestId: null, error: null, mediaUrl: '' });
  };

  const uploadMediaFile = async (file) => {
    if (!file) return;
    updateUpload({ status: 'presigning', fileName: file.name, requestId: null, error: null, mediaUrl: '' });
    try {
      const signed = await presignUpload(file);
      const upload = signed.upload;
      if (!upload?.upload_url || !upload?.media_url) {
        const err = new Error('MomentIQ did not return upload instructions.');
        err.payload = signed;
        throw err;
      }
      updateUpload({ status: 'uploading', requestId: signed.request_id || null });
      const response = await fetch(upload.upload_url, {
        method: upload.upload_method || 'PUT',
        headers: upload.upload_headers || { 'Content-Type': upload.content_type || file.type || 'application/octet-stream' },
        body: file,
      });
      if (!response.ok) {
        const text = await response.text().catch(() => '');
        const err = new Error(text || response.statusText || 'Upload failed.');
        err.payload = { error: { code: 'upload_failed', request_id: signed.request_id || null }, upload, status: response.status, body: text };
        throw err;
      }
      setField('media_url', upload.media_url);
      updateUpload({ status: 'uploaded', mediaUrl: upload.media_url, requestId: signed.request_id || null, error: null });
    } catch (err) {
      updateUpload({
        status: 'error',
        error: err,
        requestId: err?.payload?.error?.request_id || err?.payload?.request_id || null,
      });
    }
  };

  const requestFindMoments = async () => {
    const body = {
      media_url: String(form.media_url || '').trim(),
      intent: form.intent,
      target_duration: Number(form.target_duration || 45),
      max_moments: Number(form.max_moments || 5),
      render: false,
    };
    if (form.intent === 'custom') body.custom_prompt = String(form.custom_prompt || '').trim();
    if (advanced.enabled) {
      body.advanced = {
        enabled: true,
        signal_plan: advanced.signal_plan,
        strictness: advanced.strictness,
        output_goal: advanced.output_goal,
        avoid_cutting_speech: advanced.avoid_cutting_speech,
      };
    }
    if (!body.media_url) {
      const err = new Error('Upload a media file or paste a media URL first.');
      err.payload = { error: { code: 'media_required', request_id: null } };
      setState(current => ({ ...current, status: 'error', error: err, requestId: null }));
      return;
    }
    setState(current => ({ ...current, status: 'loading', error: null, requestId: null }));

    let lastError = null;
    for (const root of findMomentsRoots()) {
      try {
        const payload = await jsonFetch(root, { method: 'POST', body: JSON.stringify(body) });
        setState(current => ({ ...current, status: 'success', result: payload, error: null, requestId: payload.request_id, rendering: {} }));
        return;
      } catch (err) {
        lastError = err;
      }
    }
    setState(current => ({
      ...current,
      status: 'error',
      error: lastError,
      requestId: lastError?.payload?.error?.request_id || lastError?.payload?.request_id || null,
    }));
  };

  const updateRender = (index, patch) => {
    setState(current => ({
      ...current,
      rendering: {
        ...current.rendering,
        [index]: { ...(current.rendering[index] || {}), ...patch },
      },
    }));
  };

  const renderMoment = async (moment, index) => {
    const start = Number(moment.start);
    const end = Number(moment.end);
    const mediaUrl = String(form.media_url || '').trim();
    const endpoint = moment.render_action?.endpoint || 'video/clip-window';
    if (!mediaUrl || !Number.isFinite(start) || !Number.isFinite(end) || end <= start) {
      updateRender(index, {
        status: 'error',
        endpoint,
        start,
        end,
        error: { message: 'Render needs a valid media URL plus start and end timestamps.' },
      });
      return;
    }
    if (end - start > RENDER_MAX_SECONDS) {
      updateRender(index, {
        status: 'error',
        endpoint,
        start,
        end,
        error: { message: `Rendered moments are limited to ${RENDER_MAX_SECONDS} seconds during beta.` },
      });
      return;
    }

    updateRender(index, { status: 'creating', endpoint, start, end, error: null, url: '', result: null });
    try {
      const body = { endpoint, media_url: mediaUrl, start, end, format: 'mp4' };
      const created = await createRenderJob(body);
      const createdPayload = created.payload || {};
      const jobId = createdPayload.job_id || createdPayload.job?.id || null;
      updateRender(index, {
        status: jobId ? 'polling' : 'completed',
        endpoint,
        start,
        end,
        job_id: jobId,
        request_id: createdPayload.request_id || null,
        price_usd: createdPayload.price_usd ?? createdPayload.estimated_price_usd ?? null,
      });

      const finalPayload = jobId
        ? await pollRenderJob(created.root, jobId, payload => updateRender(index, {
          status: payload?.job?.status === 'completed' ? 'completed' : 'polling',
          job_id: jobId,
          request_id: payload?.request_id || createdPayload.request_id || null,
        }))
        : createdPayload;
      const result = extractRenderResult(finalPayload);
      const url = extractRenderUrl(result);
      updateRender(index, {
        status: 'completed',
        endpoint,
        start,
        end,
        job_id: jobId,
        request_id: finalPayload?.request_id || createdPayload.request_id || null,
        price_usd: finalPayload?.job?.finalPriceUsd ?? finalPayload?.job?.estimatedPriceUsd ?? createdPayload.price_usd ?? null,
        url,
        result,
        raw: finalPayload,
      });
    } catch (err) {
      const payload = err?.payload || {};
      updateRender(index, {
        status: payload?.job?.status === 'queued' ? 'queued' : 'error',
        endpoint,
        start,
        end,
        job_id: payload?.job?.id || null,
        request_id: payload?.request_id || payload?.error?.request_id || null,
        error: payload?.error || payload?.job?.error || { message: err?.message || 'Render failed.' },
        raw: payload,
      });
    }
  };

  const usingDemoMedia = String(form.media_url || '').trim() === demoMediaUrl() && state.upload.status !== 'uploaded';

  return { form, setField, setMediaUrl, useDemo, uploadMediaFile, requestFindMoments, state, renderMoment, usingDemoMedia, advanced, setAdvancedField, toggleAdvancedEndpoint };
};

const Panel = ({ children, style }) => (
  <section style={{
    background: wf.card,
    border: `1px solid ${wf.line}`,
    borderRadius: 8,
    padding: 18,
    minWidth: 0,
    maxWidth: '100%',
    boxSizing: 'border-box',
    overflow: 'hidden',
    ...style,
  }}>{children}</section>
);

const FieldLabel = ({ children }) => (
  <label style={{ display: 'block', fontFamily: wf.sans, fontSize: 12, fontWeight: 700, color: wf.ink2, marginBottom: 7 }}>{children}</label>
);

const TextInput = ({ value, onChange, placeholder, type = 'text', min, max }) => (
  <input
    value={value}
    type={type}
    min={min}
    max={max}
    placeholder={placeholder}
    onChange={event => onChange(event.target.value)}
    style={{
      width: '100%',
      boxSizing: 'border-box',
      minHeight: 40,
      border: `1px solid ${wf.line}`,
      borderRadius: 7,
      background: wf.cardAlt,
      color: wf.ink,
      fontFamily: type === 'text' ? wf.mono : wf.sans,
      fontSize: 13,
      padding: '9px 11px',
      outline: 'none',
    }}
  />
);

const PromptInput = ({ value, onChange, readOnly }) => (
  <textarea
    value={value}
    readOnly={readOnly}
    onChange={event => onChange(event.target.value)}
    rows={3}
    style={{
      width: '100%',
      boxSizing: 'border-box',
      minHeight: 76,
      resize: 'vertical',
      border: `1px solid ${wf.line}`,
      borderRadius: 7,
      background: readOnly ? '#eef1f4' : wf.cardAlt,
      color: wf.ink,
      fontFamily: wf.sans,
      fontSize: 13,
      lineHeight: 1.45,
      padding: '9px 11px',
      outline: 'none',
    }}
  />
);

const DemoAttribution = () => (
  <div style={{ fontFamily: wf.sans, fontSize: 11.5, color: wf.ink3, lineHeight: 1.45, marginTop: 8 }}>
    Demo video: <a href="https://commons.wikimedia.org/wiki/File:Tears_of_Steel_in_4k_-_Official_Blender_Foundation_release.webm" target="_blank" rel="noreferrer" style={{ color: 'var(--accent)', textDecoration: 'none', fontWeight: 700 }}>Blender Foundation</a>, <a href="https://creativecommons.org/licenses/by/3.0" target="_blank" rel="noreferrer" style={{ color: 'var(--accent)', textDecoration: 'none', fontWeight: 700 }}>CC BY 3.0</a>, via Wikimedia Commons.
  </div>
);

const UploadBox = ({ upload, onUpload, onUseDemo, showDemoButton }) => {
  const active = upload.status === 'presigning' || upload.status === 'uploading';
  const hasUploaded = upload.status === 'uploaded';
  const hasError = upload.status === 'error';
  const statusText = ({
    presigning: 'Preparing upload...',
    uploading: 'Uploading media...',
    uploaded: 'Uploaded',
    error: 'Upload failed',
  })[upload.status] || 'No local file selected';
  const errorPayload = upload.error?.payload || {};
  const errorCode = errorPayload?.error?.code || 'upload_failed';
  const errorMessage = errorPayload?.error?.message || upload.error?.message || '';

  return (
    <div style={{ border: `1px solid ${hasError ? 'oklch(0.62 0.16 25)' : wf.line}`, borderRadius: 8, background: wf.cardAlt, padding: 12 }}>
      <div className="miq-upload-row" style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
        <label style={{
          display: 'inline-flex',
          alignItems: 'center',
          justifyContent: 'center',
          minHeight: 34,
          border: `1px solid ${wf.line}`,
          borderRadius: 7,
          background: wf.card,
          color: wf.ink2,
          fontFamily: wf.sans,
          fontSize: 12.5,
          fontWeight: 700,
          padding: '0 10px',
          cursor: active ? 'wait' : 'pointer',
        }}>
          Choose file
          <input type="file" accept="audio/*,video/*" disabled={active} onChange={event => onUpload(event.target.files?.[0])} style={{ display: 'none' }} />
        </label>
        {showDemoButton && <button type="button" onClick={onUseDemo} disabled={active} style={{
          minHeight: 34,
          border: `1px solid ${wf.line}`,
          background: wf.card,
          color: wf.ink2,
          borderRadius: 7,
          padding: '0 10px',
          fontFamily: wf.sans,
          fontSize: 12.5,
          fontWeight: 700,
          cursor: active ? 'wait' : 'pointer',
        }}>Use demo video</button>}
      </div>
      <div style={{ fontFamily: wf.mono, fontSize: 11.5, color: hasError ? 'oklch(0.62 0.16 25)' : hasUploaded ? 'var(--accent)' : wf.ink3, marginTop: 9 }}>
        {statusText}{upload.fileName ? `: ${upload.fileName}` : ''}
      </div>
      {hasError && <div style={{ fontFamily: wf.sans, fontSize: 12.5, color: wf.ink2, lineHeight: 1.45, marginTop: 7 }}>
        {errorCode}: {errorMessage || 'Storage may not be configured for uploads yet.'}
        <div style={{ fontFamily: wf.mono, fontSize: 11, color: wf.ink3, marginTop: 4 }}>request_id: {upload.requestId || errorPayload?.request_id || 'not available'}</div>
      </div>}
    </div>
  );
};

const IntentSelector = ({ value, onChange }) => (
  <div className="miq-intent-grid" style={{ display: 'grid', gridTemplateColumns: 'repeat(3, minmax(0, 1fr))', gap: 8 }}>
    {INTENT_OPTIONS.map(option => (
      <button key={option.value} type="button" onClick={() => onChange(option.value)} style={{
        border: `1px solid ${value === option.value ? 'var(--accent)' : wf.line}`,
        borderBottom: value === option.value ? `2px solid var(--accent)` : `1px solid ${wf.line}`,
        background: value === option.value ? 'var(--accent-soft)' : wf.cardAlt,
        color: value === option.value ? 'var(--accent)' : wf.ink2,
        borderRadius: 7,
        minHeight: 38,
        fontFamily: wf.sans,
        fontSize: 12.5,
        fontWeight: 700,
        cursor: 'pointer',
      }}>{option.label}</button>
    ))}
  </div>
);

const AdvancedSettings = ({ advanced, onField, onToggleEndpoint }) => {
  const safeAdvanced = advanced || { enabled: false, signal_plan: DEFAULT_ADVANCED_PLAN, strictness: 'balanced', output_goal: 'clip', avoid_cutting_speech: true };
  const selected = safeAdvanced.signal_plan || [];
  return (
    <div style={{ border: `1px solid ${safeAdvanced.enabled ? 'var(--accent)' : wf.line}`, borderRadius: 8, background: safeAdvanced.enabled ? 'var(--accent-soft)' : wf.cardAlt, padding: 12 }}>
      <button type="button" onClick={() => onField('enabled', !safeAdvanced.enabled)} style={{
        width: '100%',
        minHeight: 36,
        border: `1px solid ${safeAdvanced.enabled ? 'var(--accent)' : wf.line}`,
        background: safeAdvanced.enabled ? 'var(--accent)' : wf.card,
        color: safeAdvanced.enabled ? '#fff' : wf.ink2,
        borderRadius: 7,
        fontFamily: wf.sans,
        fontSize: 13,
        fontWeight: 800,
        cursor: 'pointer',
      }}>{safeAdvanced.enabled ? 'Advanced settings on' : 'Advanced settings'}</button>
      {safeAdvanced.enabled && <div style={{ display: 'grid', gap: 12, marginTop: 12 }}>
        <div>
          <FieldLabel>Signal endpoint chain</FieldLabel>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, minmax(0, 1fr))', gap: 7 }}>
            {ADVANCED_SIGNAL_ENDPOINTS.map(endpoint => {
              const active = selected.includes(endpoint.id);
              return (
                <button key={endpoint.id} type="button" onClick={() => onToggleEndpoint(endpoint.id)} title={endpoint.id} style={{
                  minHeight: 34,
                  border: `1px solid ${active ? 'var(--accent)' : wf.line}`,
                  background: active ? wf.card : wf.cardAlt,
                  color: active ? 'var(--accent)' : wf.ink2,
                  borderRadius: 7,
                  fontFamily: wf.sans,
                  fontSize: 12,
                  fontWeight: 700,
                  cursor: 'pointer',
                }}>{endpoint.label}</button>
              );
            })}
          </div>
          <div style={{ fontFamily: wf.mono, fontSize: 10.5, color: wf.ink3, lineHeight: 1.45, marginTop: 8 }}>
            {selected.length ? selected.join(' -> ') : 'Select at least one signal endpoint.'}
          </div>
        </div>
        <div className="miq-number-grid" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
          <div>
            <FieldLabel>Strictness</FieldLabel>
            <select value={safeAdvanced.strictness} onChange={event => onField('strictness', event.target.value)} style={selectStyle}>
              <option value="loose">Loose</option>
              <option value="balanced">Balanced</option>
              <option value="strict">Strict</option>
            </select>
          </div>
          <div>
            <FieldLabel>Output goal</FieldLabel>
            <select value={safeAdvanced.output_goal} onChange={event => onField('output_goal', event.target.value)} style={selectStyle}>
              <option value="clip">Clip window</option>
              <option value="search_hit">Search hit</option>
            </select>
          </div>
        </div>
        <label style={{ display: 'flex', gap: 8, alignItems: 'flex-start', fontFamily: wf.sans, fontSize: 12.5, color: wf.ink2, lineHeight: 1.45 }}>
          <input type="checkbox" checked={!!safeAdvanced.avoid_cutting_speech} onChange={event => onField('avoid_cutting_speech', event.target.checked)} style={{ marginTop: 2, accentColor: 'var(--accent)' }} />
          <span>Prefer silence, cut points, and safer boundaries so generated windows avoid cutting people off mid-thought.</span>
        </label>
      </div>}
    </div>
  );
};

const selectStyle = {
  width: '100%',
  minHeight: 40,
  border: `1px solid ${wf.line}`,
  borderRadius: 7,
  background: wf.card,
  color: wf.ink,
  fontFamily: wf.sans,
  fontSize: 13,
  padding: '8px 10px',
  outline: 'none',
};

const CostStrip = ({ result, loading }) => {
  const cost = result?.estimated_cost;
  const items = [
    ['Analysis', cost ? fmtUsd(cost.analysis_usd) : loading ? 'estimating' : '$0.0000'],
    ['Render', cost ? fmtUsd(cost.render_usd) : '$0.0000'],
    ['Total', cost ? fmtUsd(cost.total_usd) : loading ? 'estimating' : '$0.0000'],
  ];
  return (
    <div className="miq-cost-grid" style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 10 }}>
      {items.map(([label, value]) => (
        <div key={label} style={{ border: `1px solid ${wf.line}`, borderRadius: 8, background: wf.cardAlt, padding: 12 }}>
          <div style={{ fontFamily: wf.mono, fontSize: 10.5, textTransform: 'uppercase', letterSpacing: 1, color: wf.ink3 }}>{label}</div>
          <div style={{ fontFamily: wf.mono, fontSize: 16, color: wf.ink, marginTop: 4 }}>{value}</div>
        </div>
      ))}
    </div>
  );
};

const renderButtonLabel = (state) => {
  if (!state) return 'Render this moment';
  if (state.status === 'creating') return 'Starting render...';
  if (state.status === 'polling') return 'Rendering...';
  if (state.status === 'completed') return 'Rendered';
  if (state.status === 'queued') return 'Check job';
  return 'Retry render';
};

const RenderResult = ({ state }) => {
  if (!state) return null;
  const busy = state.status === 'creating' || state.status === 'polling';
  const message = state.error?.message || state.error?.code || '';
  return (
    <div style={{ marginTop: 8, display: 'grid', gap: 7, minWidth: 220 }}>
      {state.job_id && <div style={{ fontFamily: wf.mono, fontSize: 10.5, color: wf.ink3 }}>job_id: {state.job_id}</div>}
      {busy && <div style={{ fontFamily: wf.sans, fontSize: 12.5, color: wf.ink3 }}>Rendering selected range...</div>}
      {state.status === 'queued' && <div style={{ fontFamily: wf.sans, fontSize: 12.5, color: wf.ink3 }}>Still queued. The job ID is saved for follow-up.</div>}
      {state.status === 'error' && <div style={{ fontFamily: wf.sans, fontSize: 12.5, color: 'oklch(0.62 0.16 25)', lineHeight: 1.4 }}>{message || 'Render failed.'}</div>}
      {state.url && <div style={{ display: 'grid', gap: 7 }}>
        <video src={state.url} controls preload="metadata" style={{ width: 220, maxWidth: '100%', borderRadius: 7, border: `1px solid ${wf.line}`, background: '#000' }} />
        <a href={state.url} download style={{ fontFamily: wf.sans, fontSize: 12.5, fontWeight: 700, color: 'var(--accent)', textDecoration: 'none' }}>Open/download rendered clip</a>
      </div>}
      {state.request_id && <div style={{ fontFamily: wf.mono, fontSize: 10.5, color: wf.ink3 }}>request_id: {state.request_id}</div>}
    </div>
  );
};

const SourcePreview = ({ mediaUrl, moments, mediaSeconds, selectedIndex, onPreview }) => {
  const url = String(mediaUrl || '').trim();
  const items = Array.isArray(moments) ? moments : [];
  const duration = Number(mediaSeconds || 0);
  if (!url) return null;
  return (
    <Panel>
      <div style={{ display: 'grid', gap: 10, minWidth: 0 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
          <div>
            <div style={{ fontFamily: wf.mono, fontSize: 11, textTransform: 'uppercase', letterSpacing: 1, color: 'var(--accent)' }}>Source preview</div>
            <h2 style={{ fontFamily: wf.sans, fontSize: 22, margin: '5px 0 0', color: wf.ink }}>Watch the matched moments</h2>
          </div>
          <span style={{ fontFamily: wf.mono, fontSize: 11.5, color: wf.ink3 }}>{items.length ? 'Click a timestamp to jump the player.' : 'Run Find Moments to create clickable timestamps.'}</span>
        </div>
        <div style={{ width: '100%', minWidth: 0, maxWidth: '100%', overflow: 'hidden', borderRadius: 8, background: '#000', border: `1px solid ${wf.line}` }}>
          <video id="miq-source-player" src={url} controls preload="metadata" playsInline style={{ display: 'block', width: '100%', maxWidth: '100%', height: 'auto', maxHeight: 420, aspectRatio: '16 / 9', objectFit: 'contain', background: '#000' }} />
        </div>
        {items.length > 0 && duration > 0 && <div aria-label="Clickable moment timeline" style={{ position: 'relative', height: 32, borderRadius: 999, border: `1px solid ${wf.line}`, background: wf.cardAlt, overflow: 'hidden' }}>
          {items.map((moment, index) => {
            const active = selectedIndex === index;
            const start = Math.max(0, Math.min(100, (Number(moment.start || 0) / duration) * 100));
            const width = Math.max(2, Math.min(100 - start, ((Number(moment.end || 0) - Number(moment.start || 0)) / duration) * 100));
            return (
              <button key={`marker-${moment.start}-${index}`} type="button" title={`Jump to ${fmtTime(moment.start)} - ${fmtTime(moment.end)}`} onClick={() => onPreview(moment, index)} style={{ position: 'absolute', left: `${start}%`, top: 5, width: `${width}%`, minWidth: 16, height: 20, border: `1px solid ${active ? 'var(--accent)' : 'color-mix(in oklch, var(--accent) 55%, white)'}`, borderRadius: 999, background: active ? 'var(--accent)' : 'color-mix(in oklch, var(--accent) 22%, white)', cursor: 'pointer' }} />
            );
          })}
        </div>}
        {items.length > 0 && <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, minWidth: 0 }}>
          {items.map((moment, index) => {
            const active = selectedIndex === index;
            return (
              <button key={`${moment.start}-${index}`} type="button" onClick={() => onPreview(moment, index)} style={{ border: `1px solid ${active ? 'var(--accent)' : wf.line}`, borderRadius: 999, background: active ? 'var(--accent-soft)' : wf.cardAlt, color: active ? 'var(--accent)' : wf.ink2, fontFamily: wf.mono, fontSize: 11.5, fontWeight: 800, padding: '7px 10px', cursor: 'pointer' }}>
                {fmtTime(moment.start)} - {fmtTime(moment.end)}
              </button>
            );
          })}
        </div>}
        <div style={{ fontFamily: wf.sans, fontSize: 12.5, color: wf.ink3, lineHeight: 1.45 }}>If the source allows browser playback, timestamp buttons jump directly to the selected moment.</div>
      </div>
    </Panel>
  );
};

const MomentTable = ({ result, rendering, onRender, onPreview, selectedIndex }) => {
  const moments = result?.moments || [];
  const nearMisses = result?.near_misses || [];
  if (!moments.length) {
    return <div style={{ fontFamily: wf.sans, fontSize: 13, color: wf.ink3, padding: '16px 0', lineHeight: 1.5 }}>{nearMisses.length ? 'No accepted moments matched this intent. Reviewable near-miss timestamps are available under the source video.' : 'No moments returned yet.'}</div>;
  }
  return (
    <div style={{ border: `1px solid ${wf.line}`, borderRadius: 8, overflowX: 'auto', background: wf.card }}>
      <table style={{ width: '100%', borderCollapse: 'collapse', minWidth: 860 }}>
        <thead>
          <tr style={{ background: wf.cardAlt, borderBottom: `1px solid ${wf.line}` }}>
            {['Start', 'End', 'Score', 'Moment type', 'Why this matched', 'Evidence', 'Render action'].map(label => (
              <th key={label} style={{ textAlign: 'left', fontFamily: wf.mono, fontSize: 10.5, letterSpacing: 0.8, textTransform: 'uppercase', color: wf.ink3, padding: '10px 12px' }}>{label}</th>
            ))}
          </tr>
        </thead>
        <tbody>
          {moments.map((moment, index) => {
            const renderState = rendering[index];
            const active = selectedIndex === index;
            return (
              <tr key={`${moment.start}-${moment.end}-${index}`} style={{ borderBottom: index < moments.length - 1 ? `1px solid ${wf.line2}` : 'none', background: active ? 'var(--accent-soft)' : 'transparent' }}>
                <td style={cellMono}>
                  <button type="button" onClick={() => onPreview(moment, index)} title="Jump source preview to this timestamp" style={{ border: `1px solid ${active ? 'var(--accent)' : wf.line}`, borderRadius: 7, background: active ? '#fff' : wf.cardAlt, color: active ? 'var(--accent)' : wf.ink, fontFamily: wf.mono, fontSize: 12.5, fontWeight: 800, padding: '7px 9px', cursor: 'pointer', whiteSpace: 'nowrap' }}>{fmtTime(moment.start)}</button>
                </td>
                <td style={cellMono}>{fmtTime(moment.end)}</td>
                <td style={cellMono}>{Number(moment.score || 0).toFixed(2)}</td>
                <td style={cellText}>{String(moment.moment_type || '').replace(/_/g, ' ')}</td>
                <td style={{ ...cellText, maxWidth: 310 }}>{moment.why}</td>
                <td style={cellText}>{(moment.signals || []).slice(0, 3).map(signal => String(signal.type || '').replace(/_/g, ' ')).join(', ') || 'signal evidence'}</td>
                <td style={cellText}>
                  <button type="button" disabled={renderState?.status === 'creating' || renderState?.status === 'polling'} onClick={() => onRender(moment, index)} title="Render this selected moment with video/clip-window." style={{
                    border: `1px solid ${wf.line}`,
                    borderRadius: 7,
                    background: renderState ? 'var(--accent-soft)' : wf.cardAlt,
                    color: renderState ? 'var(--accent)' : wf.ink2,
                    fontFamily: wf.sans,
                    fontSize: 12.5,
                    fontWeight: 700,
                    padding: '7px 10px',
                    cursor: (renderState?.status === 'creating' || renderState?.status === 'polling') ? 'wait' : 'pointer',
                    whiteSpace: 'nowrap',
                  }}>{renderButtonLabel(renderState)}</button>
                  <RenderResult state={renderState} />
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
};

const cellMono = { fontFamily: wf.mono, fontSize: 12.5, color: wf.ink, padding: '12px', verticalAlign: 'top', whiteSpace: 'nowrap' };
const cellText = { fontFamily: wf.sans, fontSize: 13, lineHeight: 1.45, color: wf.ink2, padding: '12px', verticalAlign: 'top' };

const ErrorBox = ({ error, requestId }) => {
  if (!error) return null;
  const payload = error.payload || {};
  const code = payload?.error?.code || 'request_failed';
  const message = payload?.error?.message || error.message || 'The request failed.';
  return (
    <div style={{ border: '1px solid oklch(0.62 0.16 25)', background: 'color-mix(in oklch, oklch(0.62 0.16 25) 9%, transparent)', borderRadius: 8, padding: 14 }}>
      <div style={{ fontFamily: wf.mono, fontSize: 11, textTransform: 'uppercase', letterSpacing: 1, color: 'oklch(0.62 0.16 25)' }}>{code}</div>
      <div style={{ fontFamily: wf.sans, fontSize: 14, color: wf.ink, marginTop: 5 }}>{message}</div>
      <div style={{ fontFamily: wf.mono, fontSize: 11.5, color: wf.ink3, marginTop: 8 }}>request_id: {requestId || payload?.error?.request_id || 'not available'}</div>
    </div>
  );
};

const JsonViewer = ({ result }) => {
  const [copyState, setCopyState] = React.useState('idle');
  const jsonText = prettyJson(result || { status: 'idle', endpoint: '/v1/moments/find' });

  const copyJson = async () => {
    try {
      if (navigator.clipboard && window.isSecureContext) {
        await navigator.clipboard.writeText(jsonText);
      } else {
        const textarea = document.createElement('textarea');
        textarea.value = jsonText;
        textarea.setAttribute('readonly', '');
        textarea.style.position = 'fixed';
        textarea.style.left = '-9999px';
        document.body.appendChild(textarea);
        textarea.select();
        document.execCommand('copy');
        document.body.removeChild(textarea);
      }
      setCopyState('copied');
      window.setTimeout(() => setCopyState('idle'), 1600);
    } catch (_error) {
      setCopyState('error');
      window.setTimeout(() => setCopyState('idle'), 2200);
    }
  };

  const label = copyState === 'copied' ? 'Copied' : copyState === 'error' ? 'Copy failed' : 'Copy JSON';

  return (
    <div style={{ display: 'grid', gap: 8 }}>
      <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
        <button type="button" onClick={copyJson} style={{
          minHeight: 34,
          border: `1px solid ${copyState === 'error' ? 'oklch(0.62 0.16 25)' : wf.line}`,
          background: copyState === 'copied' ? 'color-mix(in oklch, var(--accent) 12%, #fff)' : '#fff',
          color: copyState === 'error' ? 'oklch(0.62 0.16 25)' : wf.ink,
          borderRadius: 8,
          padding: '0 12px',
          fontFamily: wf.sans,
          fontSize: 13,
          fontWeight: 800,
          cursor: 'pointer',
        }}>{label}</button>
      </div>
      <pre style={{
        margin: 0,
        padding: 16,
        minHeight: 320,
        maxWidth: '100%',
        boxSizing: 'border-box',
        overflow: 'auto',
        background: '#0a0c0f',
        color: '#d8dde3',
        border: `1px solid ${wf.darkLine}`,
        borderRadius: 8,
        fontFamily: wf.mono,
        fontSize: 12,
        lineHeight: 1.6,
      }}>{jsonText}</pre>
    </div>
  );
};

const FindMomentsDemo = () => {
  const { form, setField, setMediaUrl, useDemo, uploadMediaFile, requestFindMoments, state, renderMoment, usingDemoMedia, advanced, setAdvancedField, toggleAdvancedEndpoint } = useFindMoments();
  const [selectedMomentIndex, setSelectedMomentIndex] = React.useState(null);
  const moments = state.result && Array.isArray(state.result.moments) ? state.result.moments : [];
  const nearMisses = state.result && Array.isArray(state.result.near_misses) ? state.result.near_misses : [];
  const previewMoments = moments.length ? moments : nearMisses;
  const previewMoment = (moment, index) => {
    setSelectedMomentIndex(index);
    const player = document.getElementById('miq-source-player');
    const start = Number(moment && moment.start);
    if (!player || !Number.isFinite(start)) return;
    try {
      player.currentTime = Math.max(0, start);
      if (typeof player.play === 'function') {
        const playResult = player.play();
        if (playResult && typeof playResult.catch === 'function') playResult.catch(function() {});
      }
    } catch (err) {}
  };
  const loading = state.status === 'loading';
  const uploadActive = state.upload.status === 'presigning' || state.upload.status === 'uploading';
  const promptValue = form.intent === 'custom' ? form.custom_prompt : PROMPT_BY_INTENT[form.intent];
  return (
    <Page current="Find Moments">
      <PageHero
        kicker="Find Moments"
        title="Find moments in long media."
        sub="Choose an editing intent, run the workflow, and inspect timestamped edit decisions with reasons, signal evidence, JSON, and render actions."
        right={<div style={{ border: `1px solid ${wf.darkLine}`, borderRadius: 8, background: '#0f1216', padding: 16 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 12 }}><Method kind="POST" /><Endpoint dark>/v1/moments/find</Endpoint></div>
          <div style={{ fontFamily: wf.mono, fontSize: 12, lineHeight: 1.65, color: wf.darkInk2 }}>
            intent_router<br />signal_plan<br />range_generation<br />moment_scoring
          </div>
        </div>}
        accentBg
      />
      <main style={{ maxWidth: 1280, margin: '0 auto', padding: '28px 28px 64px' }}>
        <div className="miq-find-grid" style={{ display: 'grid', gridTemplateColumns: 'minmax(320px, 430px) minmax(0, 1fr)', gap: 22, alignItems: 'start', minWidth: 0 }}>
          <Panel>
            <div style={{ display: 'grid', gap: 16 }}>
              <div>
                <FieldLabel>Moment type</FieldLabel>
                <IntentSelector value={form.intent} onChange={value => setField('intent', value)} />
              </div>
              <div>
                <FieldLabel>{form.intent === 'custom' ? 'Custom prompt' : 'Preset prompt'}</FieldLabel>
                <PromptInput value={promptValue || ''} readOnly={form.intent !== 'custom'} onChange={value => setField('custom_prompt', value)} />
              </div>
              <div>
                <FieldLabel>Media URL or choose file</FieldLabel>
                <TextInput value={form.media_url} onChange={setMediaUrl} placeholder="https://.../source.mp4" />
              </div>
              <div>
                <UploadBox upload={state.upload} onUpload={uploadMediaFile} onUseDemo={useDemo} showDemoButton={!usingDemoMedia} />
              </div>
              <div className="miq-number-grid" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
                <div>
                  <FieldLabel>Target duration</FieldLabel>
                  <TextInput type="number" min="15" max="120" value={form.target_duration} onChange={value => setField('target_duration', value)} />
                </div>
                <div>
                  <FieldLabel>Max moments</FieldLabel>
                  <TextInput type="number" min="1" max="10" value={form.max_moments} onChange={value => setField('max_moments', value)} />
                </div>
              </div>
              <div>
                <FieldLabel>Advanced testing</FieldLabel>
                <AdvancedSettings advanced={advanced} onField={setAdvancedField} onToggleEndpoint={toggleAdvancedEndpoint} />
              </div>
              <button type="button" disabled={loading || uploadActive} onClick={requestFindMoments} style={{
                minHeight: 44,
                border: '1px solid var(--accent)',
                background: (loading || uploadActive) ? 'var(--accent-soft)' : 'var(--accent)',
                color: (loading || uploadActive) ? 'var(--accent)' : '#fff',
                borderRadius: 8,
                fontFamily: wf.sans,
                fontSize: 14,
                fontWeight: 800,
                cursor: (loading || uploadActive) ? 'wait' : 'pointer',
              }}>{loading ? 'Finding moments...' : uploadActive ? 'Uploading media...' : 'Find Moments'}</button>
              <CostStrip result={state.result} loading={loading} />
              <ErrorBox error={state.error} requestId={state.requestId} />
            </div>
          </Panel>

          <div style={{ display: 'grid', gap: 18, minWidth: 0, maxWidth: '100%', overflow: 'hidden' }}>
            <SourcePreview mediaUrl={form.media_url} moments={previewMoments} mediaSeconds={state.result?.media_seconds} selectedIndex={selectedMomentIndex} onPreview={previewMoment} />
            <Panel>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, marginBottom: 12 }}>
                <div>
                  <div style={{ fontFamily: wf.mono, fontSize: 11, textTransform: 'uppercase', letterSpacing: 1, color: 'var(--accent)' }}>Timestamped edit decisions</div>
                  <h2 style={{ fontFamily: wf.sans, fontSize: 22, margin: '5px 0 0', color: wf.ink }}>Results</h2>
                </div>
                {state.result?.debug?.routed_intent && <Endpoint>{state.result.debug.routed_intent}</Endpoint>}
              </div>
              <MomentTable result={state.result} rendering={state.rendering} onRender={renderMoment} onPreview={previewMoment} selectedIndex={selectedMomentIndex} />
            </Panel>
            <Panel>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, marginBottom: 12 }}>
                <div>
                  <div style={{ fontFamily: wf.mono, fontSize: 11, textTransform: 'uppercase', letterSpacing: 1, color: 'var(--accent)' }}>Raw response</div>
                  <h2 style={{ fontFamily: wf.sans, fontSize: 22, margin: '5px 0 0', color: wf.ink }}>JSON</h2>
                </div>
                {state.requestId && <span style={{ fontFamily: wf.mono, fontSize: 11.5, color: wf.ink3 }}>request_id: {state.requestId}</span>}
              </div>
              <JsonViewer result={state.result} />
            </Panel>
          </div>
        </div>
      </main>
    </Page>
  );
};
