const { useState, useEffect, useRef } = React;

/* ════════════════════════════════════════════════════════════
   STATE 2 — PROGRESS
   ════════════════════════════════════════════════════════════ */
const STAGES = [
  'Создаём Паспорт жизни...',
  'Анализируем данные...',
  'Формируем персональный профиль...',
  'Выполняем расчёты...',
  'Формируем результат...',
  'Генерируем PDF-документ...',
  'Подготавливаем файл к скачиванию...',
  'Готово.',
];

function Progress({ name, orderId, initError, onDone, onError }) {
  const [pct, setPct] = useState(0);
  const [serverStatus, setServerStatus] = useState('processing');
  const [errorMessage, setErrorMessage] = useState('');
  const [userName, setUserName] = useState(name || '');
  const pctRef = useRef(0);
  const statusRef = useRef('processing');
  const orderDataRef = useRef(null);

  useEffect(() => {
    statusRef.current = serverStatus;
  }, [serverStatus]);

  useEffect(() => {
    if (initError) {
      setServerStatus('fail');
      setErrorMessage(initError);
    }
  }, [initError]);

  useEffect(() => {
    if (!orderId || initError) return;

    let timerId;
    const checkStatus = async () => {
      try {
        const res = await fetch(`/api/orders/${orderId}`);
        if (!res.ok) throw new Error('Не удалось получить статус заказа');
        const data = await res.json();

        if (data.name) {
          setUserName(data.name);
        }

        if (data.status === 'success') {
          setServerStatus('success');
          orderDataRef.current = data;
          if (timerId) clearInterval(timerId);
        } else if (data.status === 'fail') {
          setServerStatus('fail');
          setErrorMessage(data.error || 'Произошла ошибка при генерации документа.');
          if (timerId) clearInterval(timerId);
        } else if (data.status === 'pending_payment') {
          setServerStatus('pending_payment');
        } else if (data.status === 'processing') {
          setServerStatus('processing');
        }
      } catch (err) {
        console.error('Ошибка опроса статуса:', err);
      }
    };

    timerId = setInterval(checkStatus, 2000);
    checkStatus();

    return () => {
      if (timerId) clearInterval(timerId);
    };
  }, [orderId, initError]);

  useEffect(() => {
    const iv = setInterval(() => {
      let p = pctRef.current;
      const currentStatus = statusRef.current;

      if (currentStatus === 'fail' || currentStatus === 'pending_payment') {
        return;
      }

      if (p < 100) {
        // Готов на сервере → быстро добиваем до 100. Иначе:
        // быстрый старт → замедление → очень медленное «ползание» во время долгой ИИ-генерации,
        // чтобы прогресс не упирался в 99% и не выглядел зависшим.
        const maxPct = currentStatus === 'success' ? 100 : 92;
        let step;
        if (currentStatus === 'success')      step = 2 + Math.random() * 2;
        else if (p < 50)                      step = 1.2 + Math.random() * 1.5;
        else if (p < 70)                      step = 0.4 + Math.random() * 0.5;
        else                                  step = 0.004 + Math.random() * 0.012;
        if (p < maxPct) {
          p = Math.min(maxPct, p + step);
          pctRef.current = p;
          setPct(p);
        }
      } else {
        clearInterval(iv);
        setTimeout(() => onDone(orderDataRef.current), 900);
      }
    }, 45);
    return () => clearInterval(iv);
  }, [onDone]);

  const stageIdx = Math.min(STAGES.length - 1, Math.floor((pct / 100) * (STAGES.length - 1) + 0.0001));
  const ring = 2 * Math.PI * 86;

  let displayStage;
  if (serverStatus === 'pending_payment') {
    displayStage = 'Ожидаем подтверждения оплаты...';
  } else if (serverStatus === 'success' && pct >= 99.5) {
    displayStage = 'Готово.';
  } else if (pct >= 70) {
    // Долгая стадия: ИИ пишет интерпретацию, затем рендер PDF (до 1–2 минут)
    displayStage = 'Интерпретация карты и создание PDF — это может занять 1–2 минуты...';
  } else {
    displayStage = STAGES[stageIdx];
  }

  if (serverStatus === 'fail') {
    return (
      <div className="cosmic-bg relative min-h-screen overflow-hidden flex items-center justify-center px-6">
        <StarField count={110} />
        <div className="pointer-events-none absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 h-[640px] w-[640px] rounded-full bg-[radial-gradient(circle,rgba(220,38,38,.12),transparent_62%)]"></div>

        <div className="relative flex flex-col items-center text-center fade-up max-w-md">
          <div className="mx-auto mb-6 flex h-16 w-16 items-center justify-center rounded-full border border-red-500/40 bg-red-500/[.08] text-red-400 text-[30px] shadow-[0_0_40px_-8px_rgba(239,68,68,.6)]">
            <Icon name="alert-triangle" />
          </div>
          <h2 className="font-serif text-[clamp(1.8rem,4vw,2.6rem)] text-lav">Произошла ошибка</h2>
          <p className="mt-4 font-sans text-[15px] text-lavmut leading-relaxed">
            {errorMessage || 'Не удалось сгенерировать Паспорт жизни. Пожалуйста, попробуйте снова.'}
          </p>
          <button onClick={onError} className="mt-8 gold-btn rounded-full px-8 py-3.5 font-sans font-semibold text-[#2A1C05]">
            Вернуться назад
          </button>
        </div>
      </div>
    );
  }

  return (
    <div className="cosmic-bg relative min-h-screen overflow-hidden flex items-center justify-center px-6">
      <StarField count={110} />
      <div className="pointer-events-none absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 h-[640px] w-[640px] rounded-full bg-[radial-gradient(circle,rgba(124,82,200,.30),transparent_62%)]"></div>

      <div className="relative flex flex-col items-center text-center fade-up">
        {/* circular gauge */}
        <div className="relative h-[220px] w-[220px]">
          {/* pulsing halo */}
          <div className="absolute inset-0 rounded-full bg-[radial-gradient(circle,rgba(196,149,106,.28),transparent_60%)]"
            style={{ animation: 'pulseGlow 2.4s ease-in-out infinite' }}></div>
          {/* rotating dashed ring */}
          <svg className="absolute inset-0" viewBox="0 0 220 220" style={{ animation: 'spin 14s linear infinite', transformOrigin: 'center' }}>
            <circle cx="110" cy="110" r="102" fill="none" stroke="rgba(196,149,106,.22)" strokeWidth="1" strokeDasharray="2 10" />
          </svg>
          {/* progress ring */}
          <svg className="absolute inset-0 -rotate-90" viewBox="0 0 220 220">
            <circle cx="110" cy="110" r="86" fill="none" stroke="rgba(168,159,196,.16)" strokeWidth="6" />
            <circle cx="110" cy="110" r="86" fill="none" stroke="url(#gg)" strokeWidth="6" strokeLinecap="round"
              strokeDasharray={ring} strokeDashoffset={ring * (1 - pct / 100)}
              style={{ transition: 'stroke-dashoffset .12s linear' }} />
            <defs>
              <linearGradient id="gg" x1="0" y1="0" x2="1" y2="1">
                <stop offset="0%" stopColor="#d4b896" />
                <stop offset="100%" stopColor="#8b5e3c" />
              </linearGradient>
            </defs>
          </svg>
          {/* center — процент строго по центру кружка */}
          <div className="absolute inset-0 flex items-center justify-center">
            <div className="font-serif text-[52px] leading-none gold-text">{Math.round(pct)}<span className="text-[26px]">%</span></div>
          </div>
        </div>

        <h2 className="mt-12 font-serif font-normal text-[clamp(1.6rem,3.5vw,2.4rem)] text-goldlt">
          Создаём Паспорт{userName ? <>, {userName}</> : ''}
        </h2>

        {/* linear bar */}
        <div className="mt-7 h-1.5 w-[min(440px,80vw)] overflow-hidden rounded-full bg-white/[.08]">
          <div className="h-full rounded-full bg-gradient-to-r from-goldlt via-gold to-golddk transition-[width] duration-150 shadow-[0_0_16px_rgba(196,149,106,.6)]"
            style={{ width: pct + '%' }}></div>
        </div>

        <div className="mt-6 h-6 font-sans text-[15px] tracking-wide text-lavmut">
          <span key={displayStage} className="fade-up inline-block">{displayStage}</span>
        </div>
      </div>
    </div>
  );
}

/* ════════════════════════════════════════════════════════════
   STATE 3 — RESULT
   ════════════════════════════════════════════════════════════ */
function getZodiacSign(dateStr) {
  if (!dateStr) return { name: 'Космос', symbol: '✨' };
  const date = new Date(dateStr);
  const m = date.getMonth() + 1;
  const d = date.getDate();
  if ((m === 3 && d >= 21) || (m === 4 && d <= 19)) return { name: 'Овен', symbol: '♈' };
  if ((m === 4 && d >= 20) || (m === 5 && d <= 20)) return { name: 'Телец', symbol: '♉' };
  if ((m === 5 && d >= 21) || (m === 6 && d <= 20)) return { name: 'Близнецы', symbol: '♊' };
  if ((m === 6 && d >= 21) || (m === 7 && d <= 22)) return { name: 'Рак', symbol: '♋' };
  if ((m === 7 && d >= 23) || (m === 8 && d <= 22)) return { name: 'Лев', symbol: '♌' };
  if ((m === 8 && d >= 23) || (m === 9 && d <= 22)) return { name: 'Дева', symbol: '♍' };
  if ((m === 9 && d >= 23) || (m === 10 && d <= 22)) return { name: 'Весы', symbol: '♎' };
  if ((m === 10 && d >= 23) || (m === 11 && d <= 21)) return { name: 'Скорпион', symbol: '♏' };
  if ((m === 11 && d >= 22) || (m === 12 && d <= 21)) return { name: 'Стрелец', symbol: '♐' };
  if ((m === 12 && d >= 22) || (m === 1 && d <= 19)) return { name: 'Козерог', symbol: '♑' };
  if ((m === 1 && d >= 20) || (m === 2 && d <= 18)) return { name: 'Водолей', symbol: '♒' };
  return { name: 'Рыбы', symbol: '♓' };
}

const SPHERE_META = {
  love:     { emoji: '❤️',  label: 'Любовь и отношения' },
  money:    { emoji: '💰',  label: 'Деньги и финансы' },
  career:   { emoji: '💼',  label: 'Карьера и призвание' },
  family:   { emoji: '🏠',  label: 'Семья и близкие' },
  health:   { emoji: '🌿',  label: 'Здоровье и тело' },
  growth:   { emoji: '🌱',  label: 'Развитие и духовность' },
  creative: { emoji: '✨',  label: 'Творчество и самовыражение' },
};

function SectionDivider({ title }) {
  return (
    <div className="my-10 flex items-center gap-4">
      <div className="h-px flex-1 bg-gradient-to-r from-transparent to-gold/18"></div>
      <span className="font-serif text-[18px] font-normal text-goldlt/85 tracking-wide">{title}</span>
      <div className="h-px flex-1 bg-gradient-to-l from-transparent to-gold/18"></div>
    </div>
  );
}

function PassportCard({ children, className = '' }) {
  return (
    <div className={`rounded-[22px] p-6 sm:p-7 ${className}`}
      style={{ background: 'rgba(255,255,255,.025)', border: '1px solid rgba(255,255,255,.065)' }}>
      {children}
    </div>
  );
}

function Result({ data, orderId, onBack }) {
  const [name, setName] = React.useState(data?.name || '');
  const frameRef = React.useRef(null);

  React.useEffect(() => {
    if (name || !orderId) return;
    fetch(`/api/orders/${orderId}`).then(r => r.json())
      .then(d => { if (d.name) setName(d.name); }).catch(() => {});
  }, [orderId]);

  const handleDownload = () => {
    if (!orderId) return;
    const link = document.createElement('a');
    link.href = `/api/orders/${orderId}/pdf`;
    link.download = `Passport_${name || 'Life'}.pdf`;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  };

  // Авто-подгон высоты iframe под контент (same-origin → доступен)
  const fitFrame = () => {
    const f = frameRef.current;
    if (!f) return;
    try {
      const doc = f.contentWindow.document;
      const h = Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight);
      if (h > 120) f.style.height = h + 'px';
    } catch (e) { /* not ready */ }
  };
  const onFrameLoad = () => { fitFrame(); [300, 800, 1600, 3000].forEach(t => setTimeout(fitFrame, t)); };

  return (
    <div className="cosmic-bg relative min-h-screen">
      {/* Sticky header */}
      <div className="sticky top-0 z-30 border-b border-white/[.05] bg-[#0C0820]/85 backdrop-blur-lg">
        <div className="mx-auto max-w-4xl px-5 py-3.5 flex items-center justify-between">
          <button onClick={onBack}
            className="flex items-center gap-1.5 font-sans text-[12.5px] text-lavmut hover:text-gold transition-colors">
            <Icon name="arrow-left" className="text-[14px]" /> Назад
          </button>
          <span className="font-serif text-[15px] gold-text tracking-wide">Паспорт жизни{name ? ` — ${name}` : ''}</span>
          <button onClick={handleDownload}
            className="gold-btn rounded-full px-4 py-1.5 font-sans text-[12px] font-semibold text-[#2A1C05] flex items-center gap-1.5">
            <Icon name="download" className="text-[13px]" /> PDF
          </button>
        </div>
      </div>

      {/* Полный паспорт — тот же рендер, что и в PDF (через /preview) */}
      <iframe ref={frameRef} src={`/api/orders/${orderId}/preview`} title="Паспорт жизни"
        onLoad={onFrameLoad} scrolling="no"
        style={{ width: '100%', border: 'none', display: 'block', minHeight: '80vh', overflow: 'hidden', background: '#0d0d1a' }} />

      {/* Скачать PDF */}
      <div className="relative z-10 mx-auto max-w-3xl px-5 pb-20 pt-8 text-center">
        <button onClick={handleDownload}
          className="gold-btn rounded-full px-10 py-4 font-sans font-semibold text-[#2A1C05] text-[15px] inline-flex items-center gap-2.5">
          <Icon name="download" /> Скачать полный Паспорт (PDF)
        </button>
        <div className="mt-6">
          <button onClick={onBack}
            className="inline-flex items-center gap-2 font-sans text-[13px] text-lavdim hover:text-lavmut transition-colors">
            <Icon name="arrow-left" className="text-[14px]" /> На главную
          </button>
        </div>
      </div>
    </div>
  );
}

/* ════════════════════════════════════════════════════════════
   APP — state machine
   ════════════════════════════════════════════════════════════ */
function App() {
  const [screen, setScreen] = useState('landing'); // landing | progress | result
  const [data, setData] = useState(null);
  const [orderId, setOrderId] = useState(null);
  const [error, setError] = useState(null);
  const [isRedirecting, setIsRedirecting] = useState(false);

  // refresh lucide icons after every render
  useEffect(() => {
    if (window.lucide) window.lucide.createIcons();
  });

  // scroll to top on screen change
  useEffect(() => { window.scrollTo(0, 0); }, [screen]);

  // Handle URL payment status params on mount
  useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    const paymentStatus = params.get('payment_status');
    const orderIdParam = params.get('order_id');

    if (orderIdParam) {
      if (paymentStatus === 'success') {
        setOrderId(orderIdParam);
        setScreen('progress');
      } else if (paymentStatus === 'decline' || paymentStatus === 'fail') {
        setError('Платеж был отклонен или произошла ошибка при оплате. Пожалуйста, попробуйте снова.');
      }
      
      // Clean query parameters from URL without reloading page
      const cleanUrl = window.location.pathname;
      window.history.replaceState({}, document.title, cleanUrl);
    }
  }, []);

  const start = async (formData) => {
    setData(formData);
    setError(null);
    setIsRedirecting(true);

    try {
      const res = await fetch('/api/orders', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(formData),
      });

      if (!res.ok) {
        throw new Error('Не удалось отправить форму на сервер. Пожалуйста, попробуйте ещё раз.');
      }

      const result = await res.json();
      if (!result.orderId || !result.paymentUrl) {
        throw new Error('Неверный ответ сервера (отсутствует ID заказа или ссылка на оплату).');
      }

      // Redirect user to the payment link
      window.location.href = result.paymentUrl;
    } catch (err) {
      console.error(err);
      setError(err.message || 'Ошибка сети при обращении к серверу.');
      setIsRedirecting(false);
    }
  };

  const finish = (orderData) => {
    if (orderData && orderData.name) {
      setData({ name: orderData.name });
    }
    setScreen('result');
  };

  const reset = () => {
    setScreen('landing');
    setData(null);
    setOrderId(null);
    setError(null);
    setIsRedirecting(false);
  };

  return (
    <div key={screen}>
      {isRedirecting && (
        <div className="cosmic-bg fixed inset-0 z-50 overflow-hidden flex items-center justify-center px-6">
          <StarField count={110} />
          <div className="pointer-events-none absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 h-[640px] w-[640px] rounded-full bg-[radial-gradient(circle,rgba(124,82,200,.25),transparent_62%)]"></div>
          <div className="relative flex flex-col items-center text-center fade-up">
            <div className="relative h-16 w-16 mb-8">
              <div className="absolute inset-0 rounded-full border-2 border-gold/20"></div>
              <div className="absolute inset-0 rounded-full border-2 border-gold border-t-transparent animate-spin"></div>
            </div>
            <h2 className="font-serif text-[24px] text-lav">Подготовка к оплате...</h2>
            <p className="mt-3 font-sans text-[14px] text-lavmut">Перенаправляем на защищенный платежный шлюз BePaid</p>
          </div>
        </div>
      )}
      {screen === 'landing' && <Landing onStart={start} error={error} />}
      {screen === 'progress' && (
        <Progress
          name={data?.name}
          orderId={orderId}
          initError={error}
          onDone={finish}
          onError={reset}
        />
      )}
      {screen === 'result' && <Result data={data} orderId={orderId} onBack={reset} />}
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
