/* ============================================================
   studio-video.jsx — Генерация видео (8 моделей, 3 шага)
   ============================================================ */

const { useState, useEffect, useRef } = React;

/* Базовые цены по модели/длительности/аудио — fallback если API недоступен.
   Совпадает с VIDEO_MODELS в app/tg/create/page.tsx. */
const VIDEO_BASE = {
  veo:           { dur: { 8: 199, 15: 349, 30: 599 }, audio: {} },
  kling:         { dur: { 5: 149, 10: 249, 15: 349 }, audio: { 5: 199, 10: 329, 15: 449 } },
  'kling-26':    { dur: { 5: 99, 10: 119 },           audio: { 5: 99, 10: 189 } },
  'kling-turbo': { dur: { 5: 99, 10: 119 },           audio: {} },
  grok:          { dur: { 6: 149 },                   audio: {} },
  hailuo:        { dur: { 6: 129, 10: 229 },          audio: {} },
  seedance:      { dur: { 4: 79, 8: 149, 12: 219 },   audio: { 4: 109, 8: 199, 12: 289 } },
  pika:          { dur: { 5: 89, 10: 169 },           audio: {} },
};

function videoBaseFallback(modelId, duration, audio) {
  const m = VIDEO_BASE[modelId];
  if (!m) return 88;
  if (audio && m.audio[duration] != null) return m.audio[duration];
  return m.dur[duration] ?? 88;
}

/* Точная копия getStaticResPrice из app/tg/create/page.tsx */
function getStaticResPrice(modelId, resolution, duration, audio, base) {
  if (modelId === 'veo' && resolution === '1080p') return 299;
  if (modelId === 'grok' && resolution === '480p') return 119;
  if (modelId === 'hailuo' && resolution === '1080p') return duration === 10 ? 329 : 229;
  if (modelId === 'pika' && resolution === '1080p') return duration === 10 ? 219 : 119;
  if (modelId === 'seedance') {
    const r = resolution === '480p' ? '_480' : resolution === '1080p' ? '_1080' : '';
    const a = audio ? '_audio' : '';
    const d = {
      '':           { 4: 79, 8: 149, 12: 219 }, '_audio':      { 4: 109, 8: 199, 12: 289 },
      '_480':       { 4: 69, 8: 119, 12: 179 }, '_480_audio':  { 4: 89, 8: 159, 12: 229 },
      '_1080':      { 4: 99, 8: 199, 12: 289 }, '_1080_audio': { 4: 149, 8: 259, 12: 379 },
    };
    return d[`${r}${a}`]?.[duration] ?? base;
  }
  if (modelId === 'kling-26') { if (audio) return duration >= 10 ? 189 : 99; return duration >= 10 ? 119 : 99; }
  if (modelId === 'kling-turbo') return duration >= 10 ? 119 : 99;
  return base;
}

/* Точная копия getVideoPriceFromData из app/tg/create/page.tsx */
function getVideoPriceFromData(data, modelId, resolution, duration, audio, fallback) {
  if (!data) return getStaticResPrice(modelId, resolution, duration, audio, fallback);
  const m = data[modelId];
  if (!m) return getStaticResPrice(modelId, resolution, duration, audio, fallback);
  let key;
  if (modelId === 'seedance') key = audio ? `${resolution}_audio` : resolution;
  else if (modelId === 'kling' || modelId === 'kling-26') key = audio ? 'audio' : 'default';
  else if (modelId === 'kling-turbo') key = 'default';
  else key = resolution;
  return (m[key]?.[duration]) ?? getStaticResPrice(modelId, resolution, duration, audio, fallback);
}

function VideoPage() {
  const { API_BASE, user } = useAuth();
  const toast = useToast();

  const [step, setStep] = useState(1); // 1=выбор модели, 2=параметры, 3=ожидание
  const [selectedModel, setSelectedModel] = useState(null);
  const [duration, setDuration] = useState(null);
  const [aspectRatio, setAspectRatio] = useState('16:9');
  const [resolution, setResolution] = useState('720p');
  const [audioEnabled, setAudioEnabled] = useState(false);
  const [fixedCamera, setFixedCamera] = useState(false);
  const [prompt, setPrompt] = useState('');
  const [sourceFile, setSourceFile] = useState(null);
  const [enhancing, setEnhancing] = useState(false);
  const [videoId, setVideoId] = useState(null);
  const [pollStatus, setPollStatus] = useState(null); // pending|processing|done|failed
  const [videoUrl, setVideoUrl] = useState(null);
  const [pollPct, setPollPct] = useState(0);
  const [videoPricesData, setVideoPricesData] = useState(null);
  const pollRef = useRef(null);

  /* Динамические цены видео из API (как в Mini App) */
  useEffect(() => {
    fetch(`${API_BASE}/api/tg/video-prices`)
      .then(r => r.ok ? r.json() : null)
      .then(d => { if (d) setVideoPricesData(d); })
      .catch(() => {});
  }, []);

  /* Veo 1080p доступен только при 16:9 + 8с */
  const veoRes1080Locked = (r) => selectedModel?.id === 'veo' && r === '1080p' && (aspectRatio !== '16:9' || duration !== 8);
  useEffect(() => {
    if (veoRes1080Locked(resolution)) setResolution('720p');
  }, [selectedModel, aspectRatio, duration, resolution]);

  function pickModel(m) {
    setSelectedModel(m);
    setDuration(m.durations[0]);
    setAspectRatio(m.aspectRatios[0] || '16:9');
    setResolution(m.resolutions[0] || '720p');
    setAudioEnabled(false);
    setFixedCamera(false);
    setStep(2);
  }

  function getPrice() {
    if (!selectedModel) return 0;
    const fallback = videoBaseFallback(selectedModel.id, duration, audioEnabled);
    return getVideoPriceFromData(videoPricesData, selectedModel.id, resolution, duration, audioEnabled, fallback);
  }

  async function enhance() {
    if (!prompt.trim()) return;
    setEnhancing(true);
    try {
      const r = await fetch(`${API_BASE}/api/tg/enhance-prompt`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ prompt, type: 'video' }),
        credentials: 'include',
      });
      const data = await r.json();
      if (data.enhanced) { setPrompt(data.enhanced); toast('Промпт улучшен ✨', 'ok'); }
    } catch { toast('Ошибка', 'warn'); }
    finally { setEnhancing(false); }
  }

  async function pay() {
    if (!prompt.trim()) { toast('Введи промпт', 'warn'); return; }
    try {
      const body = {
        model: selectedModel.id,
        duration,
        aspectRatio,
        resolution,
        audioEnabled,
        fixedCamera,
        prompt,
      };
      if (sourceFile) {
        // Сначала загружаем файл
        const form = new FormData();
        form.append('file', sourceFile);
        const up = await fetch(`${API_BASE}/api/tg/admin/upload`, { method: 'POST', body: form, credentials: 'include' });
        const upData = await up.json();
        if (upData.url) body.sourceImageUrl = upData.url;
      }

      const r = await fetch(`${API_BASE}/api/payment/video-invoice-link`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body),
        credentials: 'include',
      });
      const data = await r.json();
      if (!r.ok) { toast(data.error || 'Ошибка оплаты', 'warn'); return; }

      if (data.videoId) setVideoId(data.videoId);

      if (data.confirmationUrl) {
        window.open(data.confirmationUrl, '_blank');
        toast('Откройте ссылку для оплаты', 'pay');
        setStep(3);
        setPollStatus('pending');
      } else if (data.videoId) {
        /* admin bypass — уже оплачено */
        setStep(3);
        startPolling(data.videoId);
      }
    } catch { toast('Ошибка сети', 'warn'); }
  }

  function startPolling(id) {
    const vid = id || videoId;
    if (!vid) return;
    setPollStatus('processing');
    let pct = 5;
    pollRef.current = setInterval(async () => {
      try {
        const r = await fetch(`${API_BASE}/api/video-status/${vid}`, { credentials: 'include' });
        const data = await r.json();
        pct = Math.min(92, pct + 4);
        setPollPct(pct);
        if (data.status === 'done' && data.videoUrl) {
          clearInterval(pollRef.current);
          setVideoUrl(data.videoUrl);
          setPollStatus('done');
          setPollPct(100);
          toast('Видео готово! 🎬', 'ok');
        } else if (data.status === 'failed') {
          clearInterval(pollRef.current);
          setPollStatus('failed');
          toast('Генерация не удалась', 'warn');
        }
      } catch {}
    }, 3500);
  }

  useEffect(() => () => clearInterval(pollRef.current), []);

  function reset() {
    clearInterval(pollRef.current);
    setStep(1);
    setSelectedModel(null);
    setPrompt('');
    setVideoId(null);
    setVideoUrl(null);
    setPollStatus(null);
    setPollPct(0);
    setSourceFile(null);
  }

  /* ─── Step 1: выбор модели ─── */
  if (step === 1) return (
    <div>
      <div className="page-head">
        <div className="page-head-text">
          <h1 className="page-title h-display">🎬 Видео</h1>
          <p className="page-sub muted">Выбери AI-модель для генерации</p>
        </div>
      </div>
      <div className="vid-models">
        {VIDEO_MODELS.map(m => (
          <button key={m.id} className="glass hov-lift vid-model" onClick={() => pickModel(m)}>
            <div style={{ flex: 1 }}>
              <div className="vm-head">
                <span style={{ fontSize: 22 }}>{m.emoji}</span>
                <span className="vm-name">{m.name}</span>
                <span className="tag">{m.provider}</span>
              </div>
              <p className="vm-note muted">{m.note}</p>
              <div className="vm-specs">
                <span>⏱ {m.durationLabel}</span>
                {m.resolutions.length > 0 && <span>📐 {m.resolutions.join('/')}</span>}
                {m.hasAudio && <span>🔊 Аудио</span>}
                {m.hasCamera && <span>📷 Фикс. камера</span>}
              </div>
            </div>
            <div className="vm-right">
              <span className="vm-price">от {m.priceFrom}₽</span>
              <span className="btn btn-ghost btn-sm">Выбрать →</span>
            </div>
          </button>
        ))}
      </div>
    </div>
  );

  /* ─── Step 2: параметры ─── */
  if (step === 2) return (
    <div>
      <div className="page-head">
        <div className="page-head-text">
          <h1 className="page-title h-display">🎬 Параметры видео</h1>
        </div>
        <button className="btn btn-ghost back-btn" onClick={() => setStep(1)}>← Назад</button>
      </div>

      {/* Выбранная модель */}
      <div className="glass selected-model" style={{ marginBottom: 20 }}>
        <span style={{ fontSize: 24 }}>{selectedModel.emoji}</span>
        <div>
          <div style={{ fontWeight: 700 }}>{selectedModel.name}</div>
          <div className="muted" style={{ fontSize: 13 }}>{selectedModel.provider} · от {selectedModel.priceFrom}₽</div>
        </div>
      </div>

      <div className="gen-layout">
        <div className="gen-settings">

          {/* Длительность */}
          <div className="field-block">
            <div className="block-label">Длительность</div>
            <Seg
              items={selectedModel.durations.map(d => ({ value: d, label: `${d}с` }))}
              value={duration}
              onChange={setDuration}
            />
          </div>

          {/* Соотношение сторон */}
          {selectedModel.aspectRatios.length > 0 && (
            <div className="field-block">
              <div className="block-label">Соотношение сторон</div>
              <div className="seg" style={{ flexWrap: 'wrap' }}>
                {selectedModel.aspectRatios.map(ar => (
                  <button
                    key={ar}
                    className={`seg-btn${aspectRatio === ar ? ' on' : ''}`}
                    onClick={() => setAspectRatio(ar)}
                  >
                    {ar === 'auto' ? 'Авто' : ar}
                  </button>
                ))}
              </div>
            </div>
          )}

          {/* Разрешение */}
          {selectedModel.resolutions.length > 0 && (
            <div className="field-block">
              <div className="block-label">Разрешение</div>
              <Seg
                items={selectedModel.resolutions
                  .filter(r => !veoRes1080Locked(r))
                  .map(r => ({ value: r, label: r }))}
                value={resolution}
                onChange={setResolution}
              />
            </div>
          )}

          {/* Аудио / Фикс. камера */}
          {(selectedModel.hasAudio || selectedModel.hasCamera) && (
            <div className="field-block">
              <div className="block-label">Дополнительно</div>
              <div className="toggle-row">
                {selectedModel.hasAudio && (
                  <Toggle label="🔊 Аудио-дорожка" value={audioEnabled} onChange={setAudioEnabled} />
                )}
                {selectedModel.hasCamera && (
                  <Toggle label="📷 Фикс. камера" value={fixedCamera} onChange={setFixedCamera} />
                )}
              </div>
            </div>
          )}

          {/* Исходное фото (image-to-video) */}
          <div className="field-block">
            <div className="block-label">Исходное фото <span className="muted" style={{ fontWeight: 400 }}>(необязательно)</span></div>
            <UploadZone
              label="Загрузи фото для image-to-video"
              accept="image/jpeg,image/png,image/webp"
              file={sourceFile}
              onFile={setSourceFile}
              onClear={() => setSourceFile(null)}
            />
          </div>

          {/* Промпт */}
          <div className="field-block">
            <div className="block-label-row">
              <div className="block-label">Промпт</div>
              <button
                className="btn btn-ghost enhance-btn"
                onClick={enhance}
                disabled={enhancing || !prompt.trim()}
              >
                {enhancing ? <Spinner sm /> : '✨ Улучшить'}
              </button>
            </div>
            <textarea
              className="prompt-area"
              rows={4}
              placeholder="Опиши сцену для видео..."
              value={prompt}
              onChange={e => setPrompt(e.target.value)}
            />
            <PromptIdeas ideas={VIDEO_PROMPT_IDEAS} onPick={setPrompt} />
          </div>

          <button
            className="btn btn-accent btn-block btn-lg"
            onClick={pay}
            disabled={!prompt.trim()}
          >
            💳 Оплатить {getPrice()}₽
          </button>
          <p className="muted" style={{ fontSize: 12, textAlign: 'center' }}>Откроется страница оплаты ЮKassa</p>
        </div>

        {/* Итог */}
        <div className="glass gen-result" style={{ alignItems: 'flex-start', padding: 24 }}>
          <div className="block-title" style={{ marginBottom: 16 }}>Итог</div>
          <div className="vsummary">
            <div><span className="muted">Модель</span><span>{selectedModel.name}</span></div>
            <div><span className="muted">Длительность</span><span>{duration}с</span></div>
            {selectedModel.aspectRatios.length > 0 && (
              <div><span className="muted">Формат</span><span>{aspectRatio === 'auto' ? 'Авто' : aspectRatio}</span></div>
            )}
            {selectedModel.resolutions.length > 0 && (
              <div><span className="muted">Разрешение</span><span>{resolution}</span></div>
            )}
            {selectedModel.hasAudio && (
              <div><span className="muted">Аудио</span><span>{audioEnabled ? '✓ Да' : '—'}</span></div>
            )}
            <div>
              <span className="muted">Итого</span>
              <span className="vsummary-price">{getPrice()}₽</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  );

  /* ─── Step 3: ожидание / результат ─── */
  return (
    <div>
      <div className="page-head">
        <div className="page-head-text">
          <h1 className="page-title h-display">🎬 Генерация видео</h1>
        </div>
        <button className="btn btn-ghost" onClick={reset}>← Новое видео</button>
      </div>

      <div className="glass" style={{ maxWidth: 640, padding: 32 }}>
        {pollStatus === 'pending' && (
          <div style={{ textAlign: 'center' }}>
            <div style={{ fontSize: 48, marginBottom: 16 }}>💳</div>
            <div style={{ fontWeight: 700, fontSize: 18, marginBottom: 8 }}>Ожидаем оплату</div>
            <p className="muted" style={{ marginBottom: 24 }}>После оплаты нажми кнопку ниже</p>
            <button
              className="btn btn-accent"
              onClick={() => { if (videoId) startPolling(videoId); else { setPollStatus('processing'); startPolling(); } }}
            >
              ✓ Оплата выполнена — начать генерацию
            </button>
          </div>
        )}

        {pollStatus === 'processing' && (
          <div className="render-box">
            <PlaceholderArt type="vid" style={{ height: 200 }} />
            <div className="render-info">
              <div className="render-model">{selectedModel?.name} · {duration}с</div>
              <div className="render-pct muted">Генерирую видео... {pollPct}%</div>
              <ProgressBar pct={pollPct} />
            </div>
          </div>
        )}

        {pollStatus === 'done' && videoUrl && (
          <div className="render-box">
            <VideoPlayer src={videoUrl} />
            <div className="render-info">
              <div className="render-model">{selectedModel?.name} · {duration}с · {resolution}</div>
              <div style={{ display: 'flex', gap: 10, marginTop: 8 }}>
                <a href={videoUrl} download className="btn btn-accent btn-sm">⬇ Скачать</a>
                <button className="btn btn-ghost btn-sm" onClick={reset}>Новое видео</button>
              </div>
            </div>
          </div>
        )}

        {pollStatus === 'failed' && (
          <div style={{ textAlign: 'center' }}>
            <div style={{ fontSize: 48, marginBottom: 16 }}>❌</div>
            <div style={{ fontWeight: 700, marginBottom: 8 }}>Генерация не удалась</div>
            <button className="btn btn-accent" onClick={reset}>Попробовать снова</button>
          </div>
        )}
      </div>
    </div>
  );
}
