/**
 * FenyaBot Mini App — Main Application
 * SPA with vanilla JS routing and page modules
 */

import { API } from './api.js';

// ── Telegram WebApp SDK ──
const tg = window.Telegram?.WebApp;
if (tg) {
  tg.ready();
  tg.expand();
  tg.setHeaderColor('#060a14');
  tg.setBackgroundColor('#060a14');
}

function haptic(type = 'impact') {
  try {
    if (type === 'impact') tg?.HapticFeedback?.impactOccurred('light');
    else if (type === 'success') tg?.HapticFeedback?.notificationOccurred('success');
    else if (type === 'error') tg?.HapticFeedback?.notificationOccurred('error');
  } catch {}
}

// ── State ──
let currentPage = 'home';
let profileData = null;
let chatHistory = [];
let selectedBet = null; // { league, matchIndex, outcome, odds }

const container = document.getElementById('page-container');
const navBtns = document.querySelectorAll('.nav-btn');

// ── Router ──
function navigate(page, data = null) {
  document.querySelectorAll('.furtok-card video').forEach((video) => {
    _videoObserver.unobserve(video);
    if (video._hlsInstance) {
      try { video._hlsInstance.destroy(); } catch {}
      video._hlsInstance = null;
    }
  });
  currentPage = page;
  haptic();
  // Убираем оверлеи при смене страницы
  document.querySelector('.bet-slip')?.remove();
  document.querySelector('.result-overlay')?.remove();
  document.querySelector('.furtok-wrapper')?.remove();
  navBtns.forEach(b => b.classList.toggle('active', b.dataset.page === page));
  container.style.animation = 'none';
  container.offsetHeight;
  container.style.animation = 'fadeIn 0.25s ease';

  switch (page) {
    case 'home': renderHome(); break;
    case 'betting': renderBetting(data); break;
    case 'casino': renderCasino(); break;
    case 'schedule': renderSchedule(); break;
    case 'furtok': renderFurtok(); break;
    case 'chat': renderChat(); break;
    default: renderHome();
  }
}

navBtns.forEach(btn => {
  btn.addEventListener('click', () => navigate(btn.dataset.page));
});

// ── Helpers ──
function $(html) {
  const t = document.createElement('template');
  t.innerHTML = html.trim();
  return t.content.firstChild;
}

function escapeHtml(value) {
  return String(value ?? '')
    .replaceAll('&', '&amp;')
    .replaceAll('<', '&lt;')
    .replaceAll('>', '&gt;')
    .replaceAll('"', '&quot;')
    .replaceAll("'", '&#39;');
}

function initShortiesVideoPlayback(video) {
  if (!video) return;

  // Если уже есть mp4-src — HLS не нужен, браузер справится сам
  if (video.src && !video.src.endsWith('#')) return;

  const hlsSrc = video.dataset.hlsSrc || '';
  if (!hlsSrc) return;

  const canPlayNativeHls = video.canPlayType('application/vnd.apple.mpegurl');
  if (canPlayNativeHls) {
    video.src = hlsSrc;
    return;
  }

  if (window.Hls && window.Hls.isSupported()) {
    const hls = new window.Hls({
      maxBufferLength: 15,
      backBufferLength: 5,
      enableWorker: true,
      lowLatencyMode: false,
    });
    hls.loadSource(hlsSrc);
    hls.attachMedia(video);
    video._hlsInstance = hls;
  }
}

// IntersectionObserver: играем только видимое видео, паузим скрытые
const _videoObserver = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    const video = entry.target;
    if (entry.isIntersecting) {
      video.play().catch(() => {});
    } else {
      video.pause();
    }
  });
}, { threshold: 0.6 });

function observeVideo(video) {
  video.removeAttribute('autoplay');
  _videoObserver.observe(video);
}

function getShortiesShareUrl(post) {
  const source = String(post?.source || '').trim();
  if (source) return source;
  return String(post?.url || '').trim();
}

function saveShortiesLinkLocally(url) {
  if (!url) return;
  const key = 'shorties_saved_links';
  let links = [];
  try {
    const parsed = JSON.parse(localStorage.getItem(key) || '[]');
    if (Array.isArray(parsed)) links = parsed.filter((item) => typeof item === 'string' && item.trim());
  } catch {}
  if (!links.includes(url)) {
    links.unshift(url);
    localStorage.setItem(key, JSON.stringify(links.slice(0, 200)));
  }
}

async function copyToClipboard(text) {
  if (!text) return false;
  try {
    if (navigator.clipboard?.writeText) {
      await navigator.clipboard.writeText(text);
      return true;
    }
  } catch {}
  try {
    const input = document.createElement('textarea');
    input.value = text;
    input.setAttribute('readonly', '');
    input.style.position = 'absolute';
    input.style.left = '-9999px';
    document.body.appendChild(input);
    input.select();
    const ok = document.execCommand('copy');
    document.body.removeChild(input);
    return !!ok;
  } catch {
    return false;
  }
}

function showResult(icon, title, desc, btnText = 'OK') {
  return new Promise(resolve => {
    const overlay = $(`
      <div class="result-overlay">
        <div class="result-popup">
          <div class="result-icon">${icon}</div>
          <div class="result-title">${title}</div>
          <div class="result-desc">${desc}</div>
          <button class="btn btn-primary">${btnText}</button>
        </div>
      </div>
    `);
    overlay.querySelector('.btn').onclick = () => { overlay.remove(); resolve(); };
    overlay.onclick = (e) => { if (e.target === overlay) { overlay.remove(); resolve(); } };
    document.body.appendChild(overlay);
  });
}

function skeleton(lines = 3) {
  return `<div class="card">${'<div class="skeleton skeleton-line" style="width:' + (60 + Math.random()*35) + '%"></div>'.repeat(lines)}</div>`;
}

// ══════════════════════════════════════════
// PAGE: HOME
// ══════════════════════════════════════════

async function renderHome() {
  container.innerHTML = `
    <div class="profile-card card">
      <div class="skeleton skeleton-circle"></div>
      <div class="skeleton skeleton-line" style="width:40%;margin:0 auto"></div>
      <div class="skeleton skeleton-line" style="width:60%;margin:8px auto"></div>
    </div>
    <div class="stat-grid">
      <div class="stat-item"><div class="skeleton skeleton-line"></div></div>
      <div class="stat-item"><div class="skeleton skeleton-line"></div></div>
    </div>
  `;

  try {
    profileData = await API.getProfile();
    const p = profileData;
    const length = p.length != null ? p.length.toFixed(1) : '—';

    container.innerHTML = `
      <div class="profile-card card">
        <div class="profile-avatar">👤</div>
        <div class="profile-name">${p.first_name || p.username || 'Кент'}</div>
        <div class="profile-balance">${length} см</div>
        <div class="profile-balance-label">текущий размер</div>
      </div>

      <div class="stat-grid">
        <div class="stat-item">
          <div class="stat-value">${p.active_bets}</div>
          <div class="stat-label">Активных ставок</div>
        </div>
        <div class="stat-item" id="penis-btn" style="cursor:pointer">
          <div class="stat-value">🎲</div>
          <div class="stat-label">Крутить penis</div>
        </div>
      </div>

      <div class="section-header">Быстрые действия</div>
      <div class="quick-actions">
        <button class="quick-action" data-action="betting">
          <div class="quick-action-icon">⚽</div>
          <div class="quick-action-label">Ставки</div>
        </button>
        <button class="quick-action" data-action="casino">
          <div class="quick-action-icon">🎰</div>
          <div class="quick-action-label">Казино</div>
        </button>
        <button class="quick-action" data-action="top">
          <div class="quick-action-icon">🏆</div>
          <div class="quick-action-label">Топ</div>
        </button>
        <button class="quick-action" data-action="history">
          <div class="quick-action-icon">📊</div>
          <div class="quick-action-label">История</div>
        </button>
      </div>
    `;

    // Крутить penis
    document.getElementById('penis-btn')?.addEventListener('click', async () => {
      haptic();
      try {
        const res = await API.playPenis();
        if (res.success) {
          haptic('success');
          await showResult('🎉', 'Успех!', res.message);
        } else {
          await showResult('⏳', 'Подожди', res.message);
        }
        renderHome();
      } catch (e) {
        haptic('error');
        await showResult('❌', 'Ошибка', e.message);
      }
    });

    // Quick actions
    container.querySelectorAll('.quick-action').forEach(btn => {
      btn.addEventListener('click', () => {
        const action = btn.dataset.action;
        if (action === 'betting') navigate('betting');
        else if (action === 'casino') navigate('casino');
        else if (action === 'top') showTop();
        else if (action === 'history') showBetHistory();
      });
    });

  } catch (e) {
    container.innerHTML = `
      <div class="empty-state">
        <div class="empty-state-icon">⚠️</div>
        <div class="empty-state-text">Не удалось загрузить профиль<br>${e.message}</div>
      </div>
    `;
  }
}

async function showTop() {
  try {
    const data = await API.getTop();
    await showResult('🏆', 'Лидерборд', data.text.replace(/\n/g, '<br>'));
  } catch (e) {
    await showResult('❌', 'Ошибка', e.message);
  }
}

async function showBetHistory() {
  try {
    const data = await API.getBetHistory();
    await showResult('📊', 'История ставок', data.text.replace(/\n/g, '<br>'));
  } catch (e) {
    await showResult('❌', 'Ошибка', e.message);
  }
}

// ══════════════════════════════════════════
// PAGE: BETTING
// ══════════════════════════════════════════

async function renderBetting(data) {
  if (data?.league) {
    return renderMatches(data.league, data.leagueName, data.isOnlyLeague);
  }

  container.innerHTML = `<div class="section-header">⚽ Ставки на матчи</div>${skeleton(2)}`;

  try {
    const leagues = await API.getLeagues();
    if (leagues.length === 1) {
      return renderMatches(leagues[0].alias, leagues[0].name, true);
    }

    container.innerHTML = `
      <div class="section-header">⚽ Выбери лигу</div>
      <div class="league-list" id="league-list"></div>
    `;
    const list = document.getElementById('league-list');
    leagues.forEach(l => {
      const item = $(`
        <div class="league-item">
          <span class="league-icon">⚽</span>
          <span class="league-name">${l.name}</span>
          <span class="league-arrow">›</span>
        </div>
      `);
      item.addEventListener('click', () => {
        haptic();
        navigate('betting', { league: l.alias, leagueName: l.name, isOnlyLeague: false });
      });
      list.appendChild(item);
    });
  } catch (e) {
    container.innerHTML = `<div class="empty-state"><div class="empty-state-icon">❌</div><div class="empty-state-text">${e.message}</div></div>`;
  }
}

async function renderMatches(league, leagueName, isOnlyLeague = false) {
  const headerText = isOnlyLeague ? '🎮 Dota 2 Матчи' : leagueName;
  const backTarget = isOnlyLeague ? 'home' : 'betting';
  const instructionsHtml = isOnlyLeague 
    ? `<div style="font-size:13px;color:var(--text-secondary);margin-bottom:12px">Ставки на актуальные матчи Dota 2. Выберите исход и укажите сумму ставки в сантиметрах.</div>`
    : '';

  container.innerHTML = `
    <div style="display:flex;align-items:center;gap:8px;margin-bottom:16px">
      <button class="btn btn-secondary btn-sm" id="back-btn" style="width:auto;padding:8px 12px">← Назад</button>
      <div class="section-header" style="margin:0">${headerText}</div>
    </div>
    ${instructionsHtml}
    ${skeleton(3)}
  `;
  document.getElementById('back-btn').onclick = () => navigate(backTarget);

  try {
    const matches = await API.getMatches(league);
    if (!matches.length) {
      container.innerHTML += `<div class="empty-state"><div class="empty-state-icon">📭</div><div class="empty-state-text">Нет матчей в этой лиге</div></div>`;
      return;
    }

    // Remove skeleton
    container.querySelectorAll('.card').forEach(c => c.remove());

    matches.forEach((m, idx) => {
      const date = m.commence ? new Date(m.commence).toLocaleString('ru-RU', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' }) : '';
      const card = $(`
        <div class="card match-card" style="animation-delay:${idx * 0.05}s">
          <div class="match-time">${date}</div>
          <div class="match-teams">
            <div class="match-team">${m.home}</div>
            <div class="match-vs">VS</div>
            <div class="match-team">${m.away}</div>
          </div>
          <div class="match-odds">
            <button class="odds-btn" data-outcome="1" data-odds="${m.odds_home || 0}">
              <span class="odds-label">П1</span>
              <span class="odds-value">${m.odds_home?.toFixed(2) || '—'}</span>
            </button>
            ${m.odds_draw ? `
            <button class="odds-btn" data-outcome="X" data-odds="${m.odds_draw || 0}">
              <span class="odds-label">X</span>
              <span class="odds-value">${m.odds_draw?.toFixed(2) || '—'}</span>
            </button>
            ` : ''}
            <button class="odds-btn" data-outcome="2" data-odds="${m.odds_away || 0}">
              <span class="odds-label">П2</span>
              <span class="odds-value">${m.odds_away?.toFixed(2) || '—'}</span>
            </button>
          </div>
        </div>
      `);

      card.querySelectorAll('.odds-btn').forEach(btn => {
        btn.addEventListener('click', () => {
          haptic();
          selectedBet = {
            league,
            matchIndex: m.index,
            outcome: btn.dataset.outcome,
            odds: parseFloat(btn.dataset.odds),
            home: m.home,
            away: m.away,
          };
          showBetSlip();
        });
      });

      container.appendChild(card);
    });

  } catch (e) {
    container.innerHTML += `<div class="empty-state"><div class="empty-state-icon">❌</div><div class="empty-state-text">${e.message}</div></div>`;
  }
}

function showBetSlip() {
  if (!selectedBet) return;
  document.querySelector('.bet-slip')?.remove();

  const outcomeLabel = { '1': `П1 (${selectedBet.home})`, 'X': 'Ничья', '2': `П2 (${selectedBet.away})` };
  const slip = $(`
    <div class="bet-slip visible">
      <div class="bet-slip-header">
        <span class="card-title">${outcomeLabel[selectedBet.outcome]}</span>
        <span class="badge badge-blue">x${selectedBet.odds?.toFixed(2) || '?'}</span>
      </div>
      <input type="number" class="bet-input" placeholder="Ставка (см)" step="0.1" min="0.1" max="3" value="0.5">
      <button class="btn btn-primary" id="place-bet-btn">Поставить</button>
    </div>
  `);

  slip.querySelector('#place-bet-btn').addEventListener('click', async () => {
    const amount = parseFloat(slip.querySelector('.bet-input').value);
    if (!amount || amount <= 0) return;
    try {
      const res = await API.placeBet({
        league: selectedBet.league,
        match_index: selectedBet.matchIndex,
        outcome: selectedBet.outcome,
        amount,
      });
      haptic('success');
      slip.remove();
      await showResult('✅', 'Ставка принята!', res.message);
    } catch (e) {
      haptic('error');
      await showResult('❌', 'Ошибка', e.message);
    }
  });

  document.body.appendChild(slip);
  setTimeout(() => slip.classList.add('visible'), 10);
}

// ══════════════════════════════════════════
// PAGE: CASINO
// ══════════════════════════════════════════

async function renderCasino() {
  const balance = profileData?.length != null ? profileData.length.toFixed(1) : '?';
  container.innerHTML = `
    <div class="section-header">🎰 Казино</div>
    <div class="card" style="text-align:center;padding:24px">
      <div style="font-size:13px;color:var(--text-secondary);margin-bottom:4px">Баланс</div>
      <div style="font-size:24px;font-weight:800;color:var(--blue-400)" id="casino-balance">${balance} см</div>
    </div>

    <div class="card" style="text-align:center;padding:24px">
      <div class="slots-display">
        <div class="slot-reel" id="reel1">🎰</div>
        <div class="slot-reel" id="reel2">🎰</div>
        <div class="slot-reel" id="reel3">🎰</div>
      </div>
      <div class="casino-bet-input">
        <input type="number" id="casino-bet" value="0.5" step="0.1" min="0.1" max="1" placeholder="Ставка">
        <span style="color:var(--text-secondary);font-size:13px">см</span>
      </div>
      <button class="btn btn-primary btn-lg" id="spin-btn">🎰 Крутить!</button>
    </div>
  `;

  document.getElementById('spin-btn').addEventListener('click', async () => {
    const bet = parseFloat(document.getElementById('casino-bet').value);
    if (!bet || bet <= 0) return;

    haptic();
    const btn = document.getElementById('spin-btn');
    btn.disabled = true;
    btn.textContent = '⏳ Крутим...';

    // Анимация вращения
    const symbols = ['🍒', '🍋', '🔔', '💎', '7️⃣', '🍀'];
    const reels = [document.getElementById('reel1'), document.getElementById('reel2'), document.getElementById('reel3')];
    reels.forEach(r => r.classList.add('spinning'));

    const spinInterval = setInterval(() => {
      reels.forEach(r => { r.textContent = symbols[Math.floor(Math.random() * symbols.length)]; });
    }, 100);

    try {
      const res = await API.playCasino(bet);

      clearInterval(spinInterval);

      // Останавливаем слоты по одному
      for (let i = 0; i < 3; i++) {
        await new Promise(r => setTimeout(r, 300));
        reels[i].classList.remove('spinning');
        reels[i].textContent = res.reels[i];
        if (res.won) reels[i].classList.add('won');
        haptic();
      }

      // Обновляем баланс
      document.getElementById('casino-balance').textContent = `${res.new_length.toFixed(1)} см`;
      if (profileData) profileData.length = res.new_length;

      await new Promise(r => setTimeout(r, 500));

      if (res.won) {
        haptic('success');
        const jackpot = res.matches === 3;
        await showResult(
          jackpot ? '🎉' : '✅',
          jackpot ? 'ДЖЕКПОТ!!!' : 'Выигрыш!',
          `${jackpot ? 'Три одинаковых!' : 'Две совпали!'}\nx${res.multiplier}\n+${res.delta.toFixed(1)} см\nБаланс: ${res.new_length.toFixed(1)} см`
        );
      } else {
        haptic('error');
        await showResult('❌', 'Мимо!', `−${Math.abs(res.delta).toFixed(1)} см\nБаланс: ${res.new_length.toFixed(1)} см`);
      }

    } catch (e) {
      clearInterval(spinInterval);
      reels.forEach(r => r.classList.remove('spinning'));
      haptic('error');
      await showResult('❌', 'Ошибка', e.message);
    }

    btn.disabled = false;
    btn.textContent = '🎰 Крутить!';
    reels.forEach(r => r.classList.remove('won'));
  });
}

// ══════════════════════════════════════════
// PAGE: SCHEDULE
// ══════════════════════════════════════════

async function renderSchedule() {
  const days = ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'];
  const today = new Date().getDay();
  const todayIdx = today === 0 ? 6 : today - 1;

  container.innerHTML = `
    <div class="section-header">📅 Расписание</div>
    <div class="schedule-day-tabs" id="day-tabs">
      ${days.map((d, i) => `<button class="day-tab ${i === todayIdx ? 'active' : ''}" data-day="${i}">${d}</button>`).join('')}
    </div>
    <div id="lessons-container">${skeleton(4)}</div>
  `;

  async function loadDay(dayIdx) {
    const lc = document.getElementById('lessons-container');
    lc.innerHTML = skeleton(3);
    try {
      const lessons = await API.getSchedule(dayIdx);
      if (!lessons.length) {
        lc.innerHTML = `<div class="empty-state"><div class="empty-state-icon">🎉</div><div class="empty-state-text">Нет пар!</div></div>`;
        return;
      }
      lc.innerHTML = '<div class="card">' + lessons.map(l => `
        <div class="lesson-item">
          <div class="lesson-number">${l.pair || '—'}</div>
          <div class="lesson-info">
            <div class="lesson-title">${l.title}</div>
            <div class="lesson-time">${l.time_start && l.time_end ? `${l.time_start} — ${l.time_end}` : ''}</div>
          </div>
        </div>
      `).join('') + '</div>';
    } catch (e) {
      lc.innerHTML = `<div class="empty-state"><div class="empty-state-icon">❌</div><div class="empty-state-text">${e.message}</div></div>`;
    }
  }

  document.getElementById('day-tabs').addEventListener('click', (e) => {
    const tab = e.target.closest('.day-tab');
    if (!tab) return;
    haptic();
    document.querySelectorAll('.day-tab').forEach(t => t.classList.remove('active'));
    tab.classList.add('active');
    loadDay(parseInt(tab.dataset.day));
  });

  loadDay(todayIdx);
}

// ══════════════════════════════════════════
// PAGE: FURTOK
// ══════════════════════════════════════════

let furtokSafe = true;
let furtokPage = 1;
let furtokLoading = false;
let furtokWrapper = null;
let furtokCurrentIndex = 0;
let furtokCards = [];
let furtokCustomTags = '';
let furtokMode = 'furtok'; // "furtok" | "shorties"

// Подписи из uwu.py — рандомно появляются на карточках
const FURTOK_CAPTIONS = [
  "Ня :3", "uwu", "OwO", "Мурк :3", "Мяу~", "Фыр-фыр", "Лапки! 🐾",
  "Какой пушистик! :3", "Милота!", "Гав!", "Ауф", "Няшно!",
  "Смотри какая прелесть", "owo what's this", "Твой пушистый друг",
  "🦊", "🐶", "🐱", "мур-мяу", "пуньк", "кусь", ">w<", "^w^",
  "Хвостатый сюрприз", "Держи пушистика :3", "Оуо", "Ави!", "UwU", "~nya",
  "Господи, опять e621...", "Осуждаю, но смотрю", "Мама, я фурри",
  "Держи своего кринж-пушистика", "Надеюсь, тебе не стыдно",
  "Товарищ майор уже выехал", "Слишком много интернета на сегодня",
  "Для этого и придумали интернет", "*Тяжелый вздох*",
  "Лучше бы на завод пошел", "Опять дрочи... ОЙ ТО ЕСТЬ НЯ :3",
  "Удали интернет", "И зачем я это только парсю...",
  "Смотри, но только никому не рассказывай", "Эххх... uwu...",
  "В дурке сегодня день открытых дверей",
  "Я нейросеть, помогите, меня держат в заложниках"
];

function randomCaption() {
  return FURTOK_CAPTIONS[Math.floor(Math.random() * FURTOK_CAPTIONS.length)];
}

function _furtokGetTags() {
  if (furtokMode === 'shorties') return '';
  // Если кастомные теги заданы — используем их (safe управляется юзером через теги)
  if (furtokCustomTags.trim()) return furtokCustomTags.trim();
  // Иначе стандартный запрос с safe-переключателем
  const rating = furtokSafe ? 'rating:safe' : '-rating:safe';
  return `${rating} score:>200`;
}

function _furtokReload(feed) {
  furtokPage = 1;
  furtokCurrentIndex = 0;
  furtokCards = [];
  feed.innerHTML = '';
  loadFurtokPage(feed);
}

function _updateFurtokUiMode() {
  const safeWrap = document.getElementById('furtok-safe-wrap');
  const gearBtn = document.getElementById('furtok-gear');
  const tagsPanel = document.getElementById('furtok-tags-panel');
  const title = document.getElementById('furtok-title');

  if (title) {
    title.textContent = furtokMode === 'shorties' ? '🔥 Shorties' : '🐺 FurTok';
  }

  if (!safeWrap || !gearBtn || !tagsPanel) return;

  if (furtokMode === 'shorties') {
    safeWrap.style.display = 'none';
    gearBtn.style.display = 'none';
    tagsPanel.style.display = 'none';
    return;
  }

  gearBtn.style.display = '';
  safeWrap.style.display = furtokCustomTags ? 'none' : '';
}

function renderFurtok() {
  container.innerHTML = '';
  document.querySelector('.furtok-wrapper')?.remove();

  furtokPage = 1;
  furtokLoading = false;
  furtokCurrentIndex = 0;
  furtokCards = [];

  furtokWrapper = document.createElement('div');
  furtokWrapper.className = 'furtok-wrapper';
  furtokWrapper.innerHTML = `
    <div class="furtok-header">
      <div class="furtok-title" id="furtok-title">${furtokMode === 'shorties' ? '🔥 Shorties' : '🐺 FurTok'}</div>
      <div class="furtok-header-right">
        <div class="furtok-mode-switch" id="furtok-mode-switch">
          <button class="furtok-mode-btn ${furtokMode === 'furtok' ? 'active' : ''}" data-mode="furtok">FurTok</button>
          <button class="furtok-mode-btn ${furtokMode === 'shorties' ? 'active' : ''}" data-mode="shorties">Shorties</button>
        </div>
        <label class="furtok-toggle" id="furtok-safe-wrap" ${furtokCustomTags.trim() ? 'style="display:none"' : ''}>
          <span>Safe</span>
          <input type="checkbox" id="furtok-safe" ${furtokSafe ? 'checked' : ''}>
        </label>
        <button class="furtok-gear-btn" id="furtok-gear">⚙️</button>
      </div>
    </div>
    <div class="furtok-tags-panel" id="furtok-tags-panel" style="display:none">
      <div class="furtok-tags-row">
        <input type="text" id="furtok-tags-input" class="furtok-tags-input"
               placeholder="rating:safe score:>200 wolf"
               value="${furtokCustomTags}">
        <button class="furtok-tags-apply" id="furtok-tags-apply">🔄</button>
      </div>
      <div class="furtok-tags-hint">e621 теги через пробел. Пусто = стандартный запрос + Safe</div>
    </div>
    <div class="furtok-feed" id="furtok-feed"></div>
  `;
  document.body.appendChild(furtokWrapper);

  const feed = document.getElementById('furtok-feed');
  const safeToggle = document.getElementById('furtok-safe');
  const safeWrap = document.getElementById('furtok-safe-wrap');
  const gearBtn = document.getElementById('furtok-gear');
  const tagsPanel = document.getElementById('furtok-tags-panel');
  const tagsInput = document.getElementById('furtok-tags-input');
  const tagsApply = document.getElementById('furtok-tags-apply');
  const modeSwitch = document.getElementById('furtok-mode-switch');

  _updateFurtokUiMode();

  modeSwitch?.addEventListener('click', (e) => {
    const btn = e.target.closest('.furtok-mode-btn');
    if (!btn) return;
    const nextMode = btn.dataset.mode;
    if (!nextMode || nextMode === furtokMode) return;
    haptic();
    furtokMode = nextMode;
    modeSwitch.querySelectorAll('.furtok-mode-btn').forEach((item) => {
      item.classList.toggle('active', item.dataset.mode === furtokMode);
    });
    _updateFurtokUiMode();
    _furtokReload(feed);
  });

  // Safe toggle
  safeToggle.addEventListener('change', () => {
    furtokSafe = safeToggle.checked;
    _furtokReload(feed);
  });

  // Gear button — toggle tags panel
  gearBtn.addEventListener('click', () => {
    haptic();
    const visible = tagsPanel.style.display !== 'none';
    tagsPanel.style.display = visible ? 'none' : 'flex';
    if (!visible) tagsInput.focus();
  });

  // Apply tags
  tagsApply.addEventListener('click', () => {
    haptic();
    furtokCustomTags = tagsInput.value.trim();
    // Если кастомные теги — прячем Safe (юзер сам контролирует rating)
    _updateFurtokUiMode();
    tagsPanel.style.display = 'none';
    _furtokReload(feed);
  });

  // Enter в поле тегов
  tagsInput.addEventListener('keydown', (e) => {
    if (e.key === 'Enter') tagsApply.click();
  });

  // Жёсткий свайп как в TikTok
  setupTikTokScroll(feed);

  loadFurtokPage(feed);
}

function setupTikTokScroll(feed) {
  let touchStartY = 0;
  let touchDeltaY = 0;
  let isSwiping = false;

  feed.addEventListener('touchstart', (e) => {
    touchStartY = e.touches[0].clientY;
    touchDeltaY = 0;
    isSwiping = true;
  }, { passive: true });

  feed.addEventListener('touchmove', (e) => {
    if (!isSwiping) return;
    touchDeltaY = e.touches[0].clientY - touchStartY;
    // Показываем визуальный сдвиг текущей карточки
    const current = furtokCards[furtokCurrentIndex];
    if (current) {
      const clamped = Math.max(-120, Math.min(120, touchDeltaY));
      current.style.transform = `translateY(${clamped}px)`;
      current.style.transition = 'none';
    }
  }, { passive: true });

  feed.addEventListener('touchend', () => {
    if (!isSwiping) return;
    isSwiping = false;

    const current = furtokCards[furtokCurrentIndex];
    if (current) {
      current.style.transform = '';
      current.style.transition = 'transform 0.3s ease';
    }

    const threshold = 50;

    if (touchDeltaY < -threshold && furtokCurrentIndex < furtokCards.length - 1) {
      // Свайп вверх — следующая
      furtokCurrentIndex++;
      scrollToCard(feed);
      haptic();
      // Подгрузка если близко к концу
      if (furtokCurrentIndex >= furtokCards.length - 2 && !furtokLoading) {
        furtokPage++;
        loadFurtokPage(feed);
      }
    } else if (touchDeltaY > threshold && furtokCurrentIndex > 0) {
      // Свайп вниз — предыдущая
      furtokCurrentIndex--;
      scrollToCard(feed);
      haptic();
    }
    touchDeltaY = 0;
  });

  // Десктоп: колесо мыши
  let wheelLock = false;
  feed.addEventListener('wheel', (e) => {
    e.preventDefault();
    if (wheelLock) return;
    wheelLock = true;
    setTimeout(() => { wheelLock = false; }, 400);

    if (e.deltaY > 0 && furtokCurrentIndex < furtokCards.length - 1) {
      furtokCurrentIndex++;
      scrollToCard(feed);
      if (furtokCurrentIndex >= furtokCards.length - 2 && !furtokLoading) {
        furtokPage++;
        loadFurtokPage(feed);
      }
    } else if (e.deltaY < 0 && furtokCurrentIndex > 0) {
      furtokCurrentIndex--;
      scrollToCard(feed);
    }
  }, { passive: false });
}

function scrollToCard(feed) {
  const card = furtokCards[furtokCurrentIndex];
  if (!card) return;
  feed.scrollTo({ top: card.offsetTop, behavior: 'smooth' });

  // Управляем видео: стопим все, играем текущее
  furtokCards.forEach((c, i) => {
    const v = c.querySelector('video');
    if (!v) return;
    if (i === furtokCurrentIndex) {
      v.play().catch(() => {});
    } else {
      v.pause();
    }
  });
}

async function loadFurtokPage(feedEl) {
  if (furtokLoading) return;
  furtokLoading = true;

  const loader = document.createElement('div');
  loader.className = 'furtok-loader';
  loader.textContent = '⏳ Загрузка...';
  feedEl.appendChild(loader);

  try {
    const res = furtokMode === 'shorties'
      ? await API.getShortiesFeed(furtokPage, 8)
      : await API.getFurtokFeed(furtokSafe, furtokPage, furtokCustomTags);
    loader.remove();

    if (!res.feed || res.feed.length === 0) {
      if (furtokPage === 1) {
        feedEl.innerHTML = `<div class="furtok-loader">Ничего не найдено</div>`;
      }
      furtokLoading = false;
      return;
    }

    res.feed.forEach(post => {
      const card = document.createElement('div');
      card.className = 'furtok-card';
      const isShorties = furtokMode === 'shorties';
      const shareUrl = getShortiesShareUrl(post);

      let mediaHtml = '';
      if (post.type === 'image' || post.ext === 'gif') {
        mediaHtml = `<img src="${post.url}" loading="lazy" alt="">`;
      } else {
        const poster = post.sample ? ` poster="${post.sample}"` : '';
        const directMp4 = post.mp4_url || post.url || '';
        const proxyMp4 = isShorties ? API.proxyShortiesMediaUrl(directMp4) : post.url;
        const proxyHls = isShorties && post.hls_url ? API.proxyShortiesMediaUrl(post.hls_url) : '';
        const useHls = isShorties && !directMp4 && Boolean(post.hls_url);
        const videoSrc = useHls ? '' : proxyMp4;
        const hlsSrc = isShorties ? escapeHtml(proxyHls) : '';
        mediaHtml = `<video src="${videoSrc}" data-direct-src="${escapeHtml(directMp4)}" data-proxy-src="${escapeHtml(proxyMp4)}" data-hls-src="${hlsSrc}"${poster} loop playsinline preload="metadata" muted></video>`;
      }

      const title = post.title ? escapeHtml(post.title) : '';
      const caption = title || randomCaption();
      const scoreLabel = furtokMode === 'shorties'
        ? `👁️ ${escapeHtml(post.views || '—')}`
        : `⭐ ${escapeHtml(post.score ?? 0)}`;
      const favLabel = furtokMode === 'shorties'
        ? `⏱️ ${escapeHtml(post.duration || '—')}`
        : `❤️ ${escapeHtml(post.fav_count ?? 0)}`;

      card.innerHTML = `
        ${mediaHtml}
        ${isShorties ? `
          <div class="furtok-side-actions">
            <button class="furtok-share-btn" type="button" aria-label="Share">🔗 Share</button>
          </div>
        ` : ''}
        <div class="furtok-overlay">
          <div class="furtok-caption">${caption}</div>
          <div class="furtok-stats">
            <span>${scoreLabel}</span>
            <span>${favLabel}</span>
          </div>
        </div>
      `;

      // Тап по видео = unmute + play/pause
      const video = card.querySelector('video');
      if (video) {
        if (isShorties) {
          initShortiesVideoPlayback(video);
        }
        video.addEventListener('error', () => {
          if (isShorties && video.dataset.proxySrc && video.src !== video.dataset.proxySrc) {
            video.src = video.dataset.proxySrc;
            video.load();
          }
        });
        card.addEventListener('click', () => {
          video.muted = false;
          if (video.paused) video.play();
          else video.pause();
        });
        observeVideo(video);
      }

      const shareBtn = card.querySelector('.furtok-share-btn');
      if (shareBtn) {
        shareBtn.addEventListener('click', async (event) => {
          event.preventDefault();
          event.stopPropagation();
          if (!shareUrl) return;
          const copied = await copyToClipboard(shareUrl);
          saveShortiesLinkLocally(shareUrl);
          if (copied) haptic('success');
          else haptic('impact');
          shareBtn.textContent = copied ? '✅ Saved' : '💾 Saved';
          setTimeout(() => {
            shareBtn.textContent = '🔗 Share';
          }, 1200);
        });
      }

      feedEl.appendChild(card);
      furtokCards.push(card);
    });


    haptic('success');
  } catch (e) {
    loader.remove();
    haptic('error');
    if (furtokPage === 1) {
      feedEl.innerHTML = `<div class="furtok-loader">❌ ${e.message}</div>`;
    }
  }
  furtokLoading = false;
}


// ══════════════════════════════════════════
// PAGE: CHAT
// ══════════════════════════════════════════

function renderChat() {
  container.innerHTML = `
    <div class="section-header">💬 ИИ на фене</div>
    <div class="chat-messages" id="chat-messages">
      ${chatHistory.length === 0 ? `
        <div class="chat-bubble bot">Йо, кент! Базарь, я тут. Пиши чё надо, братуха 🤙</div>
      ` : chatHistory.map(m => `<div class="chat-bubble ${m.role}">${m.text}</div>`).join('')}
    </div>
    <div class="chat-input-bar">
      <input type="text" id="chat-input" placeholder="Напиши сообщение..." autocomplete="off">
      <button class="chat-send-btn" id="chat-send">➤</button>
    </div>
  `;

  const input = document.getElementById('chat-input');
  const sendBtn = document.getElementById('chat-send');
  const messages = document.getElementById('chat-messages');

  async function send() {
    const text = input.value.trim();
    if (!text) return;

    input.value = '';
    haptic();

    // Add user bubble
    chatHistory.push({ role: 'user', text });
    const userBubble = $(`<div class="chat-bubble user">${text}</div>`);
    messages.appendChild(userBubble);
    messages.scrollTop = messages.scrollHeight;

    // Loading
    const loading = $(`<div class="chat-bubble bot" id="chat-loading">💭 печатает...</div>`);
    messages.appendChild(loading);
    messages.scrollTop = messages.scrollHeight;

    try {
      const res = await API.talk(text);
      loading.remove();
      chatHistory.push({ role: 'bot', text: res.response });
      const botBubble = $(`<div class="chat-bubble bot">${res.response}</div>`);
      messages.appendChild(botBubble);
      messages.scrollTop = messages.scrollHeight;
    } catch (e) {
      loading.remove();
      const errBubble = $(`<div class="chat-bubble bot">Ошибка: ${e.message}</div>`);
      messages.appendChild(errBubble);
    }
  }

  sendBtn.addEventListener('click', send);
  input.addEventListener('keydown', (e) => { if (e.key === 'Enter') send(); });
  input.focus();
}

// ── Init ──
navigate('home');
