import './index.css';
import { MOVIES_DATA, NEWS_DATA, TEAM_MEMBERS, HISTORY_EVENTS, CORPORATE_CULTURE } from './data';
import { Movie, TeamMember, HistoryEvent } from './types';

// ==================== STATE MANAGEMENT ====================
let currentTab: string = 'home';
let searchQuery: string = '';
let filterType: string = '全部';
let filterRegion: string = '全部';
let filterYear: string = '全部';
let filterRating: string = '全部';
let filterSort: string = '最热点击';
let currentPage: number = 1;
const ITEMS_PER_PAGE: number = 6;

// Timeline active index
let selectedTimelineIndex: number = HISTORY_EVENTS.length - 1;

// Interactive Vector Map States
let mapZoom: number = 1.0;
let mapOffsetX: number = 0;
let mapOffsetY: number = 0;
let isDraggingMap: boolean = false;
let startDragX: number = 0;
let startDragY: number = 0;
let selectedPoiIndex: number = 0;

// Player Simulation State inside modal
let isPlayerPlaying: boolean = true;
let playerProgress: number = 22; // initial progress %
let playerVolume: number = 85;
let selectedPlaybackLine: string = '朝阳 BGP 极速 4K 加速专线';
let playerTimerInterval: any = null;

// ==================== DOM ELEMENTS CACHE ====================
const elements = {
  // Navigation elements
  headerLogoBtn: document.getElementById('header-logo-btn'),
  searchShortcutBtn: document.getElementById('search-quick-shortcut'),
  headerCollaborationBtn: document.getElementById('header-collaboration-btn'),
  mobileMenuHamburger: document.getElementById('mobile-menu-hamburger'),
  mobileDrawer: document.getElementById('mobile-drawer'),
  mobileSearchTrigger: document.getElementById('mobile-search-trigger'),
  mobileContactTrigger: document.getElementById('mobile-contact-trigger'),
  footerLogoBtn: document.getElementById('footer-logo-btn'),
  
  // Tab container views
  tabHome: document.getElementById('tab-content-home'),
  tabProducts: document.getElementById('tab-content-products'),
  tabAbout: document.getElementById('tab-content-about'),
  tabContact: document.getElementById('tab-content-contact'),
  
  // Home Grids & Banners
  homePopularMovies: document.getElementById('home-popular-movies'),
  homeLatestMovies: document.getElementById('home-latest-movies'),
  homeNewsGrid: document.getElementById('home-news-grid'),
  viewMorePopularBtn: document.getElementById('view-more-popular-btn'),
  heroPlayTrigger: document.getElementById('hero-play-trigger'),
  heroCatalogTrigger: document.getElementById('hero-catalog-trigger'),
  commitmentContactBtn: document.getElementById('commitment-contact-btn'),
  
  // Products/Catalog Tab
  catalogSearchInput: document.getElementById('catalog-search-input') as HTMLInputElement,
  catalogSearchClear: document.getElementById('catalog-search-clear'),
  catalogMoviesGrid: document.getElementById('catalog-movies-grid'),
  catalogEmptyView: document.getElementById('catalog-empty-view'),
  catalogEmptyReset: document.getElementById('catalog-empty-reset'),
  catalogCountDisplay: document.getElementById('catalog-count-display'),
  catalogSortSelect: document.getElementById('catalog-sort-select') as HTMLSelectElement,
  activeTagsContainer: document.getElementById('active-tags-container'),
  btnPagePrev: document.getElementById('btn-page-prev') as HTMLButtonElement,
  btnPageNext: document.getElementById('btn-page-next') as HTMLButtonElement,
  pageNumbersContainer: document.getElementById('page-numbers-container'),
  catalogPagination: document.getElementById('catalog-pagination'),
  
  // About Tab
  aboutTeamGrid: document.getElementById('about-team-grid'),
  cultureMissionText: document.getElementById('culture-mission-text'),
  cultureVisionText: document.getElementById('culture-vision-text'),
  cultureValuesList: document.getElementById('culture-values-list'),
  timelineYearsPanel: document.getElementById('timeline-years-panel'),
  timelineYearBig: document.getElementById('timeline-year-big'),
  timelineTitleDisplay: document.getElementById('timeline-title-display'),
  timelineDescDisplay: document.getElementById('timeline-desc-display'),
  
  // Contact View Form
  contactForm: document.getElementById('contact-form') as HTMLFormElement,
  formSubmitBtn: document.getElementById('form-submit-btn') as HTMLButtonElement,
  formSubmitText: document.getElementById('form-submit-text'),
  formSubmitSpinner: document.getElementById('form-submit-spinner'),
  triggerOnlineChat: document.getElementById('trigger-online-chat'),
  
  // Interactive Canvas Map
  mapCanvas: document.getElementById('interactive-sandmap-canvas') as HTMLCanvasElement,
  mapCtrlZoomIn: document.getElementById('map-ctrl-zoom-in'),
  mapCtrlZoomOut: document.getElementById('map-ctrl-zoom-out'),
  mapCtrlReset: document.getElementById('map-ctrl-reset'),
  poiMetaDist: document.getElementById('poi-meta-dist'),
  poiMetaTitle: document.getElementById('poi-meta-title'),
  poiMetaDesc: document.getElementById('poi-meta-desc'),
  poiRowsSelector: document.getElementById('poi-rows-selector'),
  
  // Dialog modal player
  videoStreamDialog: document.getElementById('video-stream-dialog'),
  modalCloseTrigger: document.getElementById('modal-close-trigger'),
  modalDynamicContent: document.getElementById('modal-dynamic-content'),
  
  // Online AI Chat Simulator
  floatingChatTrigger: document.getElementById('floating-chat-trigger'),
  onlineChatWindow: document.getElementById('online-chat-window'),
  chatWindowClose: document.getElementById('chat-window-close'),
  chatMessagesBox: document.getElementById('chat-messages-box'),
  chatUserInput: document.getElementById('chat-user-input') as HTMLInputElement,
  chatSubmitForm: document.getElementById('chat-submit-form') as HTMLFormElement,
  chatSuggestionBox: document.getElementById('chat-suggestion-box'),
  
  // Success Toast Notification
  globalSuccessToast: document.getElementById('global-success-toast'),
  toastTitle: document.getElementById('toast-title'),
  toastDesc: document.getElementById('toast-desc'),
  toastCloseBtn: document.getElementById('toast-close-btn')
};

// ==================== MAP POIS DATA ====================
interface MapPoi {
  title: string;
  desc: string;
  x: number; // coordinate x inside virtual 800x500 box
  y: number; // coordinate y
  distance: string;
}

const MAP_POIS: MapPoi[] = [
  {
    title: "闪闪科技研发总部大楼",
    desc: "北京市朝阳区中关村互联网大厦C座。北京闪闪数字流媒体科技有限公司的技术孵化及运营核心枢纽。部署了 Shanshan-AI 超分辨率画面智能重制系统与高并行转码服务器集群，提供极致的国产高清视频展示服务。",
    x: 400,
    y: 250,
    distance: "0米"
  },
  {
    title: "闪闪多线 BGP 高速云机房",
    desc: "北京朝阳区骨干接入汇聚云节点，直连中国电信、中国联通、中国移动、广电等顶级光纤通道。承载全站最新手机在线电影与高评分电视剧全集的秒速并发解析分发。",
    x: 550,
    y: 160,
    distance: "320米"
  },
  {
    title: "朝阳公园地铁站 B出口",
    desc: "北京地铁14号线重要换乘枢纽，步行仅需150米即可直连中关村互联网大厦C座闪闪总部，是商务接洽会面及站长互联的重要交通坐标。",
    x: 325,
    y: 350,
    distance: "145米"
  }
];

// ==================== RENDERING UTILITIES ====================

// Switch Navigation Tabs
function switchTab(tabName: string) {
  currentTab = tabName;
  
  // Hide all tab views
  const tabViews = document.querySelectorAll('.tab-view');
  tabViews.forEach(view => {
    view.classList.add('hidden');
    view.classList.remove('block');
  });

  // Show active tab view
  const targetView = document.getElementById(`tab-content-${tabName}`);
  if (targetView) {
    targetView.classList.remove('hidden');
    targetView.classList.add('block');
  }

  // Update navigation desktop active state
  const navTabs = document.querySelectorAll('.nav-tab');
  navTabs.forEach(tab => {
    const btnTab = tab.getAttribute('data-tab');
    if (btnTab === tabName) {
      tab.className = "nav-tab px-5 py-2 rounded-lg text-xs font-bold transition duration-200 cursor-pointer text-black bg-amber-500 border border-amber-400/20 shadow";
    } else {
      tab.className = "nav-tab px-5 py-2 rounded-lg text-xs font-bold transition duration-200 cursor-pointer text-slate-400 hover:text-white hover:bg-slate-900/60";
    }
  });

  // Update mobile drawer active state
  const mobileTabBtns = document.querySelectorAll('.mobile-tab-btn');
  mobileTabBtns.forEach(btn => {
    const btnTab = btn.getAttribute('data-tab');
    if (btnTab === tabName) {
      btn.className = "mobile-tab-btn text-left px-4 py-3 rounded-xl text-sm font-bold text-white bg-amber-500/10 border border-amber-500/20";
    } else {
      btn.className = "mobile-tab-btn text-left px-4 py-3 rounded-xl text-sm font-bold text-slate-400 hover:text-white";
    }
  });

  // Close mobile drawer
  if (elements.mobileDrawer) {
    elements.mobileDrawer.classList.add('hidden');
  }

  // Scroll to top
  window.scrollTo({ top: 0, behavior: 'smooth' });

  // Special triggers: if moving to contact, draw the map canvas
  if (tabName === 'contact') {
    setTimeout(() => {
      initMapCanvas();
    }, 100);
  }
}

// Generate Rating Stars HTML
function getRatingStars(rating: number): string {
  const fullStars = Math.floor(rating / 2);
  const halfStar = rating % 2 >= 1 ? 1 : 0;
  let starsHtml = '';
  for (let i = 0; i < 5; i++) {
    if (i < fullStars) {
      starsHtml += '<span class="text-amber-400 text-xs sm:text-sm">★</span>';
    } else if (i === fullStars && halfStar === 1) {
      starsHtml += '<span class="text-amber-400/80 text-xs sm:text-sm">★</span>';
    } else {
      starsHtml += '<span class="text-slate-700 text-xs sm:text-sm">★</span>';
    }
  }
  return starsHtml;
}

// Create Card HTML for Movie
function createMovieCardHTML(movie: Movie): string {
  const imgUrl = `https://tse-mm.bing.com/th?q=${encodeURIComponent(movie.title + ' 电影海报')}`;
  return `
    <div class="movie-card relative bg-[#090d16]/70 border border-slate-900 hover:border-amber-500/30 rounded-2xl overflow-hidden shadow cursor-pointer group flex flex-col justify-between transition-all duration-300 transform hover:-translate-y-1.5" data-movie-id="${movie.id}">
      
      <!-- Poster image container with search redirect wrapper -->
      <div class="relative aspect-[3/4] w-full overflow-hidden bg-slate-950">
        <a href="https://tse-mm.bing.com/th?q=${encodeURIComponent(movie.title)}" target="_blank" class="block w-full h-full relative" onclick="event.stopPropagation();">
          <img 
            src="${imgUrl}" 
            alt="${movie.title} - 闪闪电影院免费在线观看" 
            class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-105"
            referrerPolicy="no-referrer"
            loading="lazy"
          />
          <div class="absolute inset-0 bg-gradient-to-t from-[#05070f] via-transparent to-transparent"></div>
        </a>
        
        <!-- Badge Type -->
        <div class="absolute top-2.5 left-2.5 flex flex-col gap-1 z-10 font-mono pointer-events-none text-[9px]">
          <span class="bg-black/60 backdrop-blur text-amber-400 border border-amber-500/15 px-2 py-0.5 rounded shadow">
            ${movie.type}
          </span>
          ${movie.isFeatured ? '<span class="bg-amber-500 text-[8px] font-black text-black px-1.5 py-0.5 rounded shadow tracking-wider uppercase">主推</span>' : ''}
        </div>

        <!-- Rating overlay -->
        <div class="absolute top-2.5 right-2.5 bg-black/60 backdrop-blur px-1.5 py-0.5 rounded border border-slate-900 shadow flex items-center gap-0.5 text-[9px] font-mono text-amber-400 font-bold pointer-events-none">
          <span>★</span>
          <span>${movie.rating.toFixed(1)}</span>
        </div>

        <!-- Update Status -->
        <div class="absolute bottom-2.5 left-2.5 bg-slate-950/80 backdrop-blur px-2 py-0.5 rounded border border-slate-900 text-[9px] text-slate-400 font-mono pointer-events-none">
          ${movie.updateStatus}
        </div>

        <!-- Play Icon Hover Ring -->
        <div class="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition duration-300 bg-black/40 pointer-events-none">
          <div class="w-11 h-11 rounded-full bg-amber-500 flex items-center justify-center text-black shadow-lg shadow-amber-500/20 transform scale-90 group-hover:scale-100 transition duration-300">
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
          </div>
        </div>

      </div>

      <!-- Specs Footer -->
      <div class="p-3.5 space-y-1 bg-[#090d16]/80 text-left">
        <h4 class="text-white text-xs sm:text-sm font-black tracking-tight leading-tight truncate group-hover:text-amber-400 transition duration-150">
          ${movie.title}
        </h4>
        <div class="flex items-center justify-between text-[10px] text-slate-500 font-mono">
          <span>${movie.region} · ${movie.year}</span>
          <span>${movie.playCount}次播放</span>
        </div>
      </div>
    </div>
  `;
}

// Render Home Grid elements
function renderHomeMovies() {
  if (!elements.homePopularMovies || !elements.homeLatestMovies) return;

  const popular = MOVIES_DATA.filter(m => m.isPopular).slice(0, 6);
  const latest = MOVIES_DATA.filter(m => m.isLatest).slice(0, 6);

  elements.homePopularMovies.innerHTML = popular.map(movie => createMovieCardHTML(movie)).join('');
  elements.homeLatestMovies.innerHTML = latest.map(movie => createMovieCardHTML(movie)).join('');

  // Re-bind click event to open details player modal
  bindMovieCardClicks();
}

// Render SEO-friendly Tech News/Blogs inside Home View
function renderHomeNews() {
  if (!elements.homeNewsGrid) return;

  elements.homeNewsGrid.innerHTML = NEWS_DATA.map(item => {
    const detailUrl = `https://tse-mm.bing.com/th?q=${encodeURIComponent(item.category + ' technology standard')}`;
    return `
      <div class="bg-[#090d16] border border-slate-900 rounded-2xl overflow-hidden shadow-lg hover:border-amber-500/10 transition duration-300 flex flex-col justify-between text-left">
        <div class="p-6 space-y-3">
          <div class="flex items-center justify-between text-[10px] font-mono font-bold">
            <span class="bg-amber-500/10 text-amber-400 border border-amber-500/15 px-2.5 py-0.5 rounded-full">${item.category}</span>
            <span class="text-slate-500">${item.date}</span>
          </div>
          <h4 class="text-white font-extrabold text-sm leading-snug hover:text-amber-400 cursor-pointer transition">
            <a href="${detailUrl}" target="_blank" class="block">${item.title}</a>
          </h4>
          <p class="text-[11px] text-slate-500 leading-relaxed font-sans line-clamp-4">
            ${item.content}
          </p>
        </div>
        
        <div class="px-6 py-4.5 bg-[#05070f] border-t border-slate-900/60 flex items-center justify-between">
          <span class="text-[9px] text-slate-600 font-mono tracking-wider truncate max-w-[200px]">
            SEO标签: ${item.seoKeywords}
          </span>
          <a href="https://tse-mm.bing.com/th?q=${encodeURIComponent(item.title)}" target="_blank" class="text-amber-400 hover:text-amber-300 text-[10px] font-bold font-mono transition inline-flex items-center gap-1 shrink-0">
            <span>浏览详情</span>
            <span>&rarr;</span>
          </a>
        </div>
      </div>
    `;
  }).join('');
}

// Render Catalog/Products Movies List with dynamic filters
function renderCatalogGrid() {
  if (!elements.catalogMoviesGrid) return;

  // Filter movies
  let filtered = MOVIES_DATA.filter(movie => {
    // Search query matching (Title, actors, director, genre)
    const matchSearch = searchQuery.trim() === '' || 
      movie.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
      movie.actors.toLowerCase().includes(searchQuery.toLowerCase()) ||
      movie.director.toLowerCase().includes(searchQuery.toLowerCase()) ||
      movie.genre.toLowerCase().includes(searchQuery.toLowerCase());

    // Type filter
    const matchType = filterType === '全部' || movie.type === filterType;

    // Region filter
    let matchRegion = true;
    if (filterRegion !== '全部') {
      if (filterRegion === '其他') {
        matchRegion = movie.region !== '大陆' && movie.region !== '港台';
      } else {
        matchRegion = movie.region === filterRegion;
      }
    }

    // Year filter
    const matchYear = filterYear === '全部' || movie.year === filterYear;

    // Rating filter
    let matchRating = true;
    if (filterRating !== '全部') {
      const minVal = parseFloat(filterRating);
      matchRating = movie.rating >= minVal;
    }

    return matchSearch && matchType && matchRegion && matchYear && matchRating;
  });

  // Sort movies
  if (filterSort === '最新上线') {
    filtered.sort((a, b) => b.year.localeCompare(a.year));
  } else if (filterSort === '评分最高') {
    filtered.sort((a, b) => b.rating - a.rating);
  } else {
    // 最热点击 - sort by length of playCount string (or simple parse)
    filtered.sort((a, b) => {
      const countA = parseInt(a.playCount.replace(/,/g, ''), 10);
      const countB = parseInt(b.playCount.replace(/,/g, ''), 10);
      return countB - countA;
    });
  }

  // Update count indicator
  if (elements.catalogCountDisplay) {
    elements.catalogCountDisplay.innerText = filtered.length.toString();
  }

  // Pagination bounds
  const totalItems = filtered.length;
  const maxPage = Math.max(1, Math.ceil(totalItems / ITEMS_PER_PAGE));
  if (currentPage > maxPage) currentPage = maxPage;

  const startIndex = (currentPage - 1) * ITEMS_PER_PAGE;
  const pageItems = filtered.slice(startIndex, startIndex + ITEMS_PER_PAGE);

  // Render list or empty
  if (totalItems === 0) {
    elements.catalogMoviesGrid.classList.add('hidden');
    if (elements.catalogEmptyView) elements.catalogEmptyView.classList.remove('hidden');
    if (elements.catalogPagination) elements.catalogPagination.classList.add('hidden');
  } else {
    elements.catalogMoviesGrid.classList.remove('hidden');
    if (elements.catalogEmptyView) elements.catalogEmptyView.classList.add('hidden');
    if (elements.catalogPagination) elements.catalogPagination.classList.remove('hidden');

    elements.catalogMoviesGrid.innerHTML = pageItems.map(movie => createMovieCardHTML(movie)).join('');
    bindMovieCardClicks();
    renderPageNumbers(maxPage);
  }

  // Disable / enable page buttons
  if (elements.btnPagePrev) elements.btnPagePrev.disabled = currentPage === 1;
  if (elements.btnPageNext) elements.btnPageNext.disabled = currentPage === maxPage;
}

// Generate pagination numbers
function renderPageNumbers(maxPage: number) {
  if (!elements.pageNumbersContainer) return;

  let numbersHtml = '';
  for (let i = 1; i <= maxPage; i++) {
    const isActive = i === currentPage;
    numbersHtml += `
      <button class="page-num-btn w-8 h-8 rounded-lg font-mono text-xs font-bold transition cursor-pointer ${isActive ? 'bg-amber-500 text-black border border-amber-400/20 shadow' : 'bg-[#090d16] hover:bg-slate-900 text-slate-400 hover:text-white border border-slate-900'}" data-page="${i}">
        ${i}
      </button>
    `;
  }
  elements.pageNumbersContainer.innerHTML = numbersHtml;

  // Bind click
  const buttons = document.querySelectorAll('.page-num-btn');
  buttons.forEach(btn => {
    btn.addEventListener('click', (e) => {
      const target = e.currentTarget as HTMLElement;
      currentPage = parseInt(target.getAttribute('data-page') || '1', 10);
      renderCatalogGrid();
      window.scrollTo({ top: elements.tabProducts ? elements.tabProducts.offsetTop - 50 : 0, behavior: 'smooth' });
    });
  });
}

// Bind click listeners to dynamically created movie cards
function bindMovieCardClicks() {
  const cards = document.querySelectorAll('.movie-card');
  cards.forEach(card => {
    card.addEventListener('click', () => {
      const movieId = card.getAttribute('data-movie-id');
      if (movieId) {
        openStreamingModal(movieId);
      }
    });
  });
}

// Render About Tab elements (Team + Cultures)
function renderAboutTab() {
  if (elements.aboutTeamGrid) {
    elements.aboutTeamGrid.innerHTML = TEAM_MEMBERS.map(member => {
      const portraitUrl = `https://tse-mm.bing.com/th?q=${encodeURIComponent(member.name + ' executive portrait portrait')}`;
      return `
        <div class="bg-[#090d16] border border-slate-900 p-6 sm:p-8 rounded-3xl space-y-5 text-left group hover:border-amber-500/10 transition duration-300 shadow">
          
          <div class="relative w-16 h-16 sm:w-20 sm:h-20 rounded-2xl overflow-hidden border border-slate-800 bg-[#05070f] shrink-0">
            <a href="${portraitUrl}" target="_blank" class="block w-full h-full relative">
              <img 
                src="${portraitUrl}" 
                alt="${member.name} - 闪闪影视科技高管肖像" 
                class="w-full h-full object-cover transition-transform duration-300 group-hover:scale-105"
                referrerPolicy="no-referrer"
              />
            </a>
          </div>

          <div class="space-y-1">
            <h4 class="text-white font-black text-base">${member.name}</h4>
            <span class="text-[10px] text-amber-400 font-mono font-bold uppercase tracking-wider block">${member.role}</span>
          </div>

          <p class="text-xs text-slate-400 leading-relaxed font-sans">
            ${member.bio}
          </p>
        </div>
      `;
    }).join('');
  }

  // Cultures Mission & Vision
  if (elements.cultureMissionText) elements.cultureMissionText.innerText = CORPORATE_CULTURE.mission;
  if (elements.cultureVisionText) elements.cultureVisionText.innerText = CORPORATE_CULTURE.vision;

  if (elements.cultureValuesList) {
    elements.cultureValuesList.innerHTML = CORPORATE_CULTURE.values.map(val => {
      return `
        <li class="flex items-center gap-2 bg-slate-950 border border-slate-900 px-3 py-2 rounded-xl text-xs">
          <span class="text-amber-400 font-bold">✓</span>
          <span>${val}</span>
        </li>
      `;
    }).join('');
  }
}

// Render Timeline Milestones
function renderTimelinePanel() {
  if (!elements.timelineYearsPanel) return;

  elements.timelineYearsPanel.innerHTML = HISTORY_EVENTS.map((evt, idx) => {
    const isSelected = selectedTimelineIndex === idx;
    return `
      <button class="timeline-year-btn w-full text-left p-4.5 rounded-2xl transition duration-150 flex items-center justify-between border cursor-pointer ${isSelected ? 'bg-amber-500 border-amber-400 text-black shadow-lg font-black' : 'bg-[#090d16] border-slate-900 text-slate-400 hover:text-white hover:border-slate-800'}" data-idx="${idx}">
        <span class="text-sm font-black font-mono">${evt.year} 年</span>
        <span class="text-[10px] truncate max-w-[180px]">${evt.title}</span>
      </button>
    `;
  }).join('');

  // Update display panel
  const activeEvt = HISTORY_EVENTS[selectedTimelineIndex];
  if (activeEvt) {
    if (elements.timelineYearBig) elements.timelineYearBig.innerText = activeEvt.year;
    if (elements.timelineTitleDisplay) elements.timelineTitleDisplay.innerText = activeEvt.title;
    if (elements.timelineDescDisplay) elements.timelineDescDisplay.innerText = activeEvt.description;
  }

  // Bind click
  const buttons = document.querySelectorAll('.timeline-year-btn');
  buttons.forEach(btn => {
    btn.addEventListener('click', (e) => {
      const target = e.currentTarget as HTMLElement;
      const idx = parseInt(target.getAttribute('data-idx') || '0', 10);
      selectedTimelineIndex = idx;
      renderTimelinePanel();
    });
  });
}

// Update Active Filter Pills State & Tag indicators
function updateFilterActivePills() {
  // Type pills
  const typePills = document.querySelectorAll('#pill-row-type button');
  typePills.forEach(pill => {
    const val = pill.getAttribute('data-value');
    if (val === filterType) {
      pill.className = "filter-pill px-3.5 py-1.5 rounded-lg font-bold border transition cursor-pointer bg-amber-500 border-amber-400 text-black shadow";
    } else {
      pill.className = "filter-pill px-3.5 py-1.5 rounded-lg font-bold border transition cursor-pointer bg-[#05070f] border-slate-900 text-slate-400 hover:text-white hover:border-slate-800";
    }
  });

  // Region pills
  const regionPills = document.querySelectorAll('#pill-row-region button');
  regionPills.forEach(pill => {
    const val = pill.getAttribute('data-value');
    if (val === filterRegion) {
      pill.className = "filter-pill px-3.5 py-1.5 rounded-lg font-bold border transition cursor-pointer bg-amber-500 border-amber-400 text-black shadow";
    } else {
      pill.className = "filter-pill px-3.5 py-1.5 rounded-lg font-bold border transition cursor-pointer bg-[#05070f] border-slate-900 text-slate-400 hover:text-white hover:border-slate-800";
    }
  });

  // Year pills
  const yearPills = document.querySelectorAll('#pill-row-year button');
  yearPills.forEach(pill => {
    const val = pill.getAttribute('data-value');
    if (val === filterYear) {
      pill.className = "filter-pill px-3.5 py-1.5 rounded-lg font-bold border transition cursor-pointer bg-amber-500 border-amber-400 text-black shadow";
    } else {
      pill.className = "filter-pill px-3.5 py-1.5 rounded-lg font-bold border transition cursor-pointer bg-[#05070f] border-slate-900 text-slate-400 hover:text-white hover:border-slate-800";
    }
  });

  // Rating pills
  const ratingPills = document.querySelectorAll('#pill-row-rating button');
  ratingPills.forEach(pill => {
    const val = pill.getAttribute('data-value');
    if (val === filterRating) {
      pill.className = "filter-pill px-3.5 py-1.5 rounded-lg font-bold border transition cursor-pointer bg-amber-500 border-amber-400 text-black shadow";
    } else {
      pill.className = "filter-pill px-3.5 py-1.5 rounded-lg font-bold border transition cursor-pointer bg-[#05070f] border-slate-900 text-slate-400 hover:text-white hover:border-slate-800";
    }
  });

  // Render tag indicators breadcrumbs
  if (elements.activeTagsContainer) {
    let tagsHtml = `<span class="text-[10px] text-slate-500 font-mono">交叉条件:</span>`;
    let count = 0;

    if (filterType !== '全部') {
      tagsHtml += `
        <span class="bg-amber-500/10 border border-amber-500/20 text-amber-400 font-bold px-2.5 py-1 rounded-lg flex items-center gap-1">
          <span>类型: ${filterType}</span>
          <button id="clear-tag-type" class="hover:text-white font-mono leading-none cursor-pointer">✕</button>
        </span>
      `;
      count++;
    }
    if (filterRegion !== '全部') {
      tagsHtml += `
        <span class="bg-amber-500/10 border border-amber-500/20 text-amber-400 font-bold px-2.5 py-1 rounded-lg flex items-center gap-1">
          <span>地区: ${filterRegion}</span>
          <button id="clear-tag-region" class="hover:text-white font-mono leading-none cursor-pointer">✕</button>
        </span>
      `;
      count++;
    }
    if (filterYear !== '全部') {
      tagsHtml += `
        <span class="bg-amber-500/10 border border-amber-500/20 text-amber-400 font-bold px-2.5 py-1 rounded-lg flex items-center gap-1">
          <span>年份: ${filterYear}</span>
          <button id="clear-tag-year" class="hover:text-white font-mono leading-none cursor-pointer">✕</button>
        </span>
      `;
      count++;
    }
    if (filterRating !== '全部') {
      tagsHtml += `
        <span class="bg-amber-500/10 border border-amber-500/20 text-amber-400 font-bold px-2.5 py-1 rounded-lg flex items-center gap-1">
          <span>评分: ${filterRating === '9' ? '9分+' : filterRating === '8.5' ? '8.5分+' : '8分+'}</span>
          <button id="clear-tag-rating" class="hover:text-white font-mono leading-none cursor-pointer">✕</button>
        </span>
      `;
      count++;
    }
    if (searchQuery.trim() !== '') {
      tagsHtml += `
        <span class="bg-amber-500/10 border border-amber-500/20 text-amber-400 font-bold px-2.5 py-1 rounded-lg flex items-center gap-1">
          <span class="truncate max-w-[100px]">搜索: ${searchQuery}</span>
          <button id="clear-tag-search" class="hover:text-white font-mono leading-none cursor-pointer">✕</button>
        </span>
      `;
      count++;
    }

    if (count === 0) {
      tagsHtml += `<span class="bg-slate-900 border border-slate-950 text-slate-500 px-2 py-0.5 rounded font-mono text-[10px]">无</span>`;
    } else {
      tagsHtml += `
        <button id="clear-tag-all" class="text-[10px] text-red-400 hover:text-red-300 font-black font-mono transition ml-2 cursor-pointer hover:underline">
          重置重构条件
        </button>
      `;
    }

    elements.activeTagsContainer.innerHTML = tagsHtml;

    // Bind remove button clicks
    const btnType = document.getElementById('clear-tag-type');
    if (btnType) btnType.addEventListener('click', () => { filterType = '全部'; onFiltersChanged(); });

    const btnRegion = document.getElementById('clear-tag-region');
    if (btnRegion) btnRegion.addEventListener('click', () => { filterRegion = '全部'; onFiltersChanged(); });

    const btnYear = document.getElementById('clear-tag-year');
    if (btnYear) btnYear.addEventListener('click', () => { filterYear = '全部'; onFiltersChanged(); });

    const btnRating = document.getElementById('clear-tag-rating');
    if (btnRating) btnRating.addEventListener('click', () => { filterRating = '全部'; onFiltersChanged(); });

    const btnSearch = document.getElementById('clear-tag-search');
    if (btnSearch) btnSearch.addEventListener('click', () => { 
      searchQuery = ''; 
      if (elements.catalogSearchInput) elements.catalogSearchInput.value = '';
      if (elements.catalogSearchClear) elements.catalogSearchClear.classList.add('hidden');
      onFiltersChanged(); 
    });

    const btnAll = document.getElementById('clear-tag-all');
    if (btnAll) btnAll.addEventListener('click', () => { resetAllFilters(); });
  }
}

// Reset all filters
function resetAllFilters() {
  filterType = '全部';
  filterRegion = '全部';
  filterYear = '全部';
  filterRating = '全部';
  searchQuery = '';
  currentPage = 1;
  if (elements.catalogSearchInput) elements.catalogSearchInput.value = '';
  if (elements.catalogSearchClear) elements.catalogSearchClear.classList.add('hidden');
  onFiltersChanged();
}

// Hook called when filter params shift
function onFiltersChanged() {
  currentPage = 1;
  updateFilterActivePills();
  renderCatalogGrid();
}

// ==================== TOAST & TICKET SYSTEM ====================
function triggerSuccessToast(title: string, desc: string) {
  if (!elements.globalSuccessToast || !elements.toastTitle || !elements.toastDesc) return;

  elements.toastTitle.innerText = title;
  elements.toastDesc.innerText = desc;
  
  elements.globalSuccessToast.classList.remove('hidden');
  elements.globalSuccessToast.classList.add('flex');

  // Trigger sound effect or blink
  setTimeout(() => {
    elements.globalSuccessToast?.classList.add('hidden');
    elements.globalSuccessToast?.classList.remove('flex');
  }, 5000);
}

// Close toast
if (elements.toastCloseBtn) {
  elements.toastCloseBtn.addEventListener('click', () => {
    elements.globalSuccessToast?.classList.add('hidden');
  });
}

// Contact form Submission Handler
if (elements.contactForm) {
  elements.contactForm.addEventListener('submit', (e) => {
    e.preventDefault();

    const nameVal = (document.getElementById('form-name') as HTMLInputElement)?.value;
    const phoneVal = (document.getElementById('form-phone') as HTMLInputElement)?.value;
    const typeVal = (document.getElementById('form-message-type') as HTMLSelectElement)?.value;
    const captchaVal = (document.getElementById('form-captcha') as HTMLInputElement)?.value.trim().toUpperCase();

    if (captchaVal !== 'SS') {
      alert('防刷机器验证错误，请输入 闪闪 的大写拼音缩写: SS');
      return;
    }

    // Toggle submit button loader
    if (elements.formSubmitBtn) elements.formSubmitBtn.disabled = true;
    if (elements.formSubmitText) elements.formSubmitText.innerText = '正在进行全传输安全协议校验...';
    if (elements.formSubmitSpinner) elements.formSubmitSpinner.classList.remove('hidden');

    setTimeout(() => {
      // Revert loading
      if (elements.formSubmitBtn) elements.formSubmitBtn.disabled = false;
      if (elements.formSubmitText) elements.formSubmitText.innerText = '安全提交闪闪工单';
      if (elements.formSubmitSpinner) elements.formSubmitSpinner.classList.add('hidden');

      // Random Ticket Id
      const randTicketId = "SS-2026-" + Math.floor(1000 + Math.random() * 9000);
      
      triggerSuccessToast(
        "工单安全提报成功！",
        `尊敬的 ${nameVal}，您提报的【${typeVal}】已入库。派发编号: ${randTicketId}。请妥善保存，客服微信将在1小时内与您对接！`
      );

      // Reset Form
      elements.contactForm.reset();
    }, 1500);

  });
}

// ==================== STREAMING DETAILS PLAY DIALOG (MODAL) ====================

// Simulate video progress playback loop
function startSimulatedVideoTimer() {
  stopSimulatedVideoTimer();
  
  const progressBar = document.getElementById('player-progress-bar') as HTMLInputElement;
  const timerText = document.getElementById('player-timer-text');
  if (!progressBar) return;

  playerTimerInterval = setInterval(() => {
    if (isPlayerPlaying) {
      playerProgress += 0.2;
      if (playerProgress >= 100) {
        playerProgress = 0;
      }
      progressBar.value = playerProgress.toString();
      
      // Calculate min & seconds
      const totalSeconds = Math.round(150 * 60); // 150 min
      const elapsedSeconds = Math.round((playerProgress / 100) * totalSeconds);
      
      const elapsedMin = Math.floor(elapsedSeconds / 60);
      const elapsedSec = elapsedSeconds % 60;
      
      const elStr = `${elapsedMin.toString().padStart(2, '0')}:${elapsedSec.toString().padStart(2, '0')}`;
      timerText!.innerText = `${elStr} / 02:30:00`;

      // Update amber visual bar
      progressBar.style.background = `linear-gradient(to right, #f59e0b 0%, #f59e0b ${playerProgress}%, #374151 ${playerProgress}%, #374151 100%)`;
    }
  }, 200);
}

function stopSimulatedVideoTimer() {
  if (playerTimerInterval) {
    clearInterval(playerTimerInterval);
    playerTimerInterval = null;
  }
}

// Open Streaming dialog
function openStreamingModal(movieId: string) {
  const movie = MOVIES_DATA.find(m => m.id === movieId);
  if (!movie || !elements.videoStreamDialog || !elements.modalDynamicContent) return;

  elements.videoStreamDialog.classList.remove('hidden');
  elements.videoStreamDialog.classList.add('flex');
  document.body.style.overflow = 'hidden'; // lock scroll

  isPlayerPlaying = true;
  playerProgress = Math.floor(5 + Math.random() * 40); // random start

  const posterUrl = `https://tse-mm.bing.com/th?q=${encodeURIComponent(movie.title + ' movie wallpaper landscape')}`;

  // Build the rich dynamic HTML for streaming experience
  elements.modalDynamicContent.innerHTML = `
    <!-- Top Showcase banner with blurred cover -->
    <div class="relative w-full aspect-video md:aspect-[21/9] bg-black overflow-hidden flex items-center justify-center">
      
      <a href="https://tse-mm.bing.com/th?q=${encodeURIComponent(movie.title)}" target="_blank" class="absolute inset-0 block w-full h-full z-0">
        <img 
          src="${posterUrl}" 
          alt="${movie.title} - 高清在线背景" 
          id="player-virtual-canvas-bg"
          class="w-full h-full object-cover transition duration-300 filter ${isPlayerPlaying ? 'brightness-[0.45] saturate-100' : 'blur-xs brightness-[0.25]'}"
          referrerPolicy="no-referrer"
        />
      </a>
      
      <!-- Video control core view overlay -->
      <div class="absolute inset-0 flex flex-col justify-between p-4 sm:p-6 z-10 font-mono">
        
        <!-- Header status -->
        <div class="flex items-center justify-between text-[10px] text-white/90 bg-black/40 backdrop-blur px-3 py-1.5 rounded-xl border border-white/10">
          <div class="flex items-center gap-2">
            <span class="w-2 h-2 rounded-full bg-amber-400 animate-ping"></span>
            <span class="font-bold font-sans">正在极速解码: ${movie.title} (${movie.year})</span>
          </div>
          <div class="flex items-center gap-3">
            <span class="text-amber-400">4K UHD HDR 原画</span>
            <span id="player-status-line" class="text-slate-300 font-bold">接入节点: ${selectedPlaybackLine}</span>
          </div>
        </div>

        <!-- Center big pause button indicator -->
        <button id="player-center-toggle-btn" class="self-center w-14 h-14 sm:w-16 sm:h-16 rounded-full bg-amber-500 hover:bg-amber-400 text-black flex items-center justify-center shadow-2xl transition duration-200 transform active:scale-95 cursor-pointer">
          <span id="player-center-icon-symbol" class="text-lg font-bold">${isPlayerPlaying ? '⏸️' : '▶️'}</span>
        </button>

        <!-- Player controls dashboard bar -->
        <div class="space-y-3 bg-black/65 backdrop-blur-md p-3.5 sm:p-5 rounded-2xl border border-white/5 text-white">
          
          <!-- Slider Track -->
          <div class="flex items-center gap-3">
            <span class="text-[10px] text-slate-400 font-mono shrink-0" id="player-timer-text">00:00:00 / 02:30:00</span>
            <input 
              type="range" 
              id="player-progress-bar" 
              min="0" 
              max="100" 
              value="${playerProgress}"
              class="flex-grow h-1.5 rounded-lg appearance-none cursor-pointer bg-slate-700 outline-none transition"
              style="background: linear-gradient(to right, #f59e0b 0%, #f59e0b ${playerProgress}%, #374151 ${playerProgress}%, #374151 100%)"
            />
          </div>

          <!-- Interaction controllers -->
          <div class="flex flex-wrap items-center justify-between gap-4 text-xs font-bold pt-1">
            <div class="flex items-center gap-4">
              <button id="player-toggle-btn" class="hover:text-amber-400 cursor-pointer text-sm" title="播放/暂停">${isPlayerPlaying ? '⏸️ 暂停' : '▶️ 播放'}</button>
              
              <!-- Volume slider -->
              <div class="flex items-center gap-2">
                <span class="text-slate-400 text-xs select-none">🔊</span>
                <input 
                  type="range" 
                  id="player-volume-bar" 
                  min="0" 
                  max="100" 
                  value="${playerVolume}"
                  class="w-16 sm:w-20 h-1 rounded-lg appearance-none bg-slate-700 focus:outline-none cursor-pointer"
                  style="background: linear-gradient(to right, #ffffff 0%, #ffffff ${playerVolume}%, #374151 ${playerVolume}%, #374151 100%)"
                />
              </div>
            </div>

            <!-- Streaming Lines and Projection -->
            <div class="flex items-center gap-3">
              <!-- Playback speed -->
              <select id="player-speed-select" class="bg-[#05070f] border border-slate-800 text-slate-300 font-bold rounded-lg px-2 py-1 text-[10px] cursor-pointer focus:outline-none">
                <option value="1.0">1.0X 倍速</option>
                <option value="1.25">1.25X</option>
                <option value="1.5" selected>1.5X 极速</option>
                <option value="2.0">2.0X</option>
              </select>

              <!-- Lines selection -->
              <select id="player-line-select" class="bg-[#05070f] border border-slate-800 text-amber-400 font-bold rounded-lg px-2 py-1 text-[10px] cursor-pointer focus:outline-none">
                <option value="朝阳 BGP 极速 4K 加速专线">朝阳 BGP 极速 4K专线</option>
                <option value="北京电信 100G 骨干直连">北京电信 100G直连</option>
                <option value="北京联通 AI 智能中继">北京联通 AI中继</option>
                <option value="海外多端异构 CDN 线路">海外异构 P2P分发</option>
              </select>

              <button id="player-aircast-btn" class="bg-amber-500/10 hover:bg-amber-500/20 text-amber-400 border border-amber-500/10 px-3 py-1 rounded-lg text-[10px] cursor-pointer transition flex items-center gap-1">
                <span>📲 AirCast 智能投屏</span>
              </button>
            </div>
          </div>

        </div>

      </div>

    </div>

    <!-- Bottom Content: Metadata info split -->
    <div class="p-6 sm:p-10 grid grid-cols-1 lg:grid-cols-12 gap-8 text-left bg-[#05070f]">
      
      <!-- Left side: Core Movie facts -->
      <div class="lg:col-span-8 space-y-6">
        
        <div class="space-y-2">
          <div class="flex flex-wrap items-center gap-2">
            <span class="bg-amber-500/10 text-amber-400 border border-amber-500/20 px-2.5 py-0.5 rounded-lg text-[10px] font-mono font-bold">${movie.type}</span>
            <span class="text-slate-400 text-xs font-mono">${movie.genre}</span>
          </div>
          <h2 class="text-2xl sm:text-4xl font-black text-white leading-tight">${movie.title}</h2>
          <div class="flex items-center gap-4 text-xs font-mono text-slate-500">
            <span>出产地: ${movie.region}</span>
            <span>上映年: ${movie.year}</span>
            <span>时长/规格: ${movie.durationOrEpisodes}</span>
            <span class="text-amber-400 font-bold">★ ${movie.rating.toFixed(1)}分</span>
          </div>
        </div>

        <div class="p-5 bg-[#090d16] border border-slate-900 rounded-2xl space-y-3">
          <h4 class="text-white font-extrabold text-sm">影片独家艺术价值简介</h4>
          <p class="text-xs sm:text-sm text-slate-400 leading-relaxed font-sans font-medium">
            ${movie.description}
          </p>
        </div>

        <!-- Cast -->
        <div class="grid grid-cols-1 sm:grid-cols-2 gap-4 text-xs font-mono leading-relaxed bg-[#090d16]/30 p-5 rounded-2xl border border-slate-900">
          <div>
            <strong class="text-slate-500 block mb-0.5">主创导演:</strong>
            <span class="text-white font-sans">${movie.director}</span>
          </div>
          <div>
            <strong class="text-slate-500 block mb-0.5">主要领衔主演:</strong>
            <span class="text-white font-sans">${movie.actors}</span>
          </div>
        </div>

      </div>

      <!-- Right side: Similar recommendations list -->
      <div class="lg:col-span-4 space-y-5">
        <h4 class="text-white font-black text-sm uppercase tracking-wider border-b border-slate-900 pb-2">精品相似国产推荐</h4>
        
        <div class="space-y-4" id="modal-recommendations-box">
          <!-- Populated dynamically below -->
        </div>
      </div>

    </div>
  `;

  // Populate Recommendations Box
  const recsBox = document.getElementById('modal-recommendations-box');
  if (recsBox) {
    const similar = MOVIES_DATA.filter(m => m.id !== movie.id && m.type === movie.type).slice(0, 3);
    recsBox.innerHTML = similar.map(m => {
      const recImg = `https://tse-mm.bing.com/th?q=${encodeURIComponent(m.title + ' movie banner')}`;
      return `
        <div class="modal-rec-row flex items-center gap-3.5 bg-[#090d16] border border-slate-900/80 p-2.5 rounded-xl cursor-pointer hover:border-amber-500/20 transition group" data-movie-id="${m.id}">
          <div class="w-12 aspect-[3/4] rounded-lg overflow-hidden shrink-0 bg-slate-950">
            <img src="${recImg}" alt="${m.title}" class="w-full h-full object-cover group-hover:scale-105 transition" referrerPolicy="no-referrer">
          </div>
          <div class="min-w-0 flex-grow text-left space-y-1">
            <h5 class="text-white text-xs font-bold truncate group-hover:text-amber-400 transition">${m.title}</h5>
            <p class="text-[10px] text-slate-500 font-mono">${m.region} · ${m.year} · ★ ${m.rating.toFixed(1)}</p>
          </div>
        </div>
      `;
    }).join('');

    // Bind click for similar movie cards inside modal
    const recRows = document.querySelectorAll('.modal-rec-row');
    recRows.forEach(row => {
      row.addEventListener('click', () => {
        const targetId = row.getAttribute('data-movie-id');
        if (targetId) {
          openStreamingModal(targetId);
        }
      });
    });
  }

  // Active timers
  startSimulatedVideoTimer();

  // BIND PLAYER INTERACTIVE ACTIONS
  const centerBtn = document.getElementById('player-center-toggle-btn');
  const bottomToggle = document.getElementById('player-toggle-btn');
  const centerIcon = document.getElementById('player-center-icon-symbol');
  const mainImg = document.getElementById('player-virtual-canvas-bg');
  
  const togglePlayState = () => {
    isPlayerPlaying = !isPlayerPlaying;
    
    if (isPlayerPlaying) {
      if (centerIcon) centerIcon.innerText = '⏸️';
      if (bottomToggle) bottomToggle.innerText = '⏸️ 暂停';
      if (mainImg) {
        mainImg.classList.remove('blur-xs', 'brightness-[0.25]');
        mainImg.classList.add('brightness-[0.45]');
      }
      startSimulatedVideoTimer();
    } else {
      if (centerIcon) centerIcon.innerText = '▶️';
      if (bottomToggle) bottomToggle.innerText = '▶️ 播放';
      if (mainImg) {
        mainImg.classList.remove('brightness-[0.45]');
        mainImg.classList.add('blur-xs', 'brightness-[0.25]');
      }
      stopSimulatedVideoTimer();
    }
  };

  if (centerBtn) centerBtn.addEventListener('click', togglePlayState);
  if (bottomToggle) bottomToggle.addEventListener('click', togglePlayState);

  // Volume slider control
  const volumeSlider = document.getElementById('player-volume-bar') as HTMLInputElement;
  if (volumeSlider) {
    volumeSlider.addEventListener('input', () => {
      playerVolume = parseInt(volumeSlider.value, 10);
      volumeSlider.style.background = `linear-gradient(to right, #ffffff 0%, #ffffff ${playerVolume}%, #374151 ${playerVolume}%, #374151 100%)`;
    });
  }

  // Progress manual change
  const progressSlider = document.getElementById('player-progress-bar') as HTMLInputElement;
  if (progressSlider) {
    progressSlider.addEventListener('input', () => {
      playerProgress = parseFloat(progressSlider.value);
      progressSlider.style.background = `linear-gradient(to right, #f59e0b 0%, #f59e0b ${playerProgress}%, #374151 ${playerProgress}%, #374151 100%)`;
    });
  }

  // Line routing switcher
  const lineSelect = document.getElementById('player-line-select') as HTMLSelectElement;
  const statusLineText = document.getElementById('player-status-line');
  if (lineSelect) {
    lineSelect.addEventListener('change', () => {
      selectedPlaybackLine = lineSelect.value;
      if (statusLineText) statusLineText.innerText = `接入节点: ${selectedPlaybackLine}`;
      
      // Simulate quick line reconnection buffer delay
      isPlayerPlaying = false;
      if (centerIcon) centerIcon.innerText = '⏳';
      if (mainImg) mainImg.classList.add('blur-xs');
      stopSimulatedVideoTimer();

      setTimeout(() => {
        isPlayerPlaying = true;
        if (centerIcon) centerIcon.innerText = '⏸️';
        if (mainImg) mainImg.classList.remove('blur-xs');
        startSimulatedVideoTimer();
      }, 800);
    });
  }

  // AirCast projection simulation
  const aircastBtn = document.getElementById('player-aircast-btn');
  if (aircastBtn) {
    aircastBtn.addEventListener('click', () => {
      alert(`【闪闪智能投屏系统提示】\n已成功探测并握手您客厅的电视设备（DLNA协议）。智能转码流已安全分发至家庭投屏网。现在尽情享受您的 4K 大屏视听吧！`);
    });
  }
}

// Close dialog
function closeStreamingModal() {
  if (elements.videoStreamDialog) {
    elements.videoStreamDialog.classList.add('hidden');
    elements.videoStreamDialog.classList.remove('flex');
    document.body.style.overflow = ''; // release scroll
    stopSimulatedVideoTimer();
  }
}

if (elements.modalCloseTrigger) {
  elements.modalCloseTrigger.addEventListener('click', closeStreamingModal);
}

// Close modal when clicking dark backdrop
if (elements.videoStreamDialog) {
  elements.videoStreamDialog.addEventListener('click', (e) => {
    if (e.target === elements.videoStreamDialog) {
      closeStreamingModal();
    }
  });
}

// ==================== INTERACTIVE VECTOR GRAPHICS CANVAS SANDBOX MAP ====================
function initMapCanvas() {
  const canvas = elements.mapCanvas;
  if (!canvas) return;

  const ctx = canvas.getContext('2d');
  if (!ctx) return;

  // Set explicit canvas dimensions bound to container
  const container = document.getElementById('map-stage-container');
  if (container) {
    canvas.width = container.clientWidth;
    canvas.height = container.clientHeight;
  } else {
    canvas.width = 800;
    canvas.height = 450;
  }

  // Initial offsets to center HQ POI (400, 250)
  mapOffsetX = canvas.width / 2 - MAP_POIS[0].x * mapZoom;
  mapOffsetY = canvas.height / 2 - MAP_POIS[0].y * mapZoom;

  let animationFrameId: number;

  function drawMap() {
    if (!ctx) return;
    
    // Clear
    ctx.fillStyle = '#030408';
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    ctx.save();
    // Apply pan and zoom transforms
    ctx.translate(mapOffsetX, mapOffsetY);
    ctx.scale(mapZoom, mapZoom);

    // 1. Draw coordinate grid lines (Cyber topology theme)
    ctx.strokeStyle = 'rgba(245, 158, 11, 0.03)';
    ctx.lineWidth = 1;
    const gridSize = 40;
    for (let x = -1000; x < 2000; x += gridSize) {
      ctx.beginPath();
      ctx.moveTo(x, -1000);
      ctx.lineTo(x, 2000);
      ctx.stroke();
    }
    for (let y = -1000; y < 2000; y += gridSize) {
      ctx.beginPath();
      ctx.moveTo(-1000, y);
      ctx.lineTo(2000, y);
      ctx.stroke();
    }

    // 2. Draw Vector Streets / Streets mesh
    ctx.strokeStyle = '#111827';
    ctx.lineWidth = 30;
    ctx.lineCap = 'round';
    ctx.lineJoin = 'round';

    // Main Avenue
    ctx.beginPath();
    ctx.moveTo(-200, 250);
    ctx.lineTo(1000, 250);
    ctx.stroke();

    // Secondary vertical street
    ctx.beginPath();
    ctx.moveTo(350, -200);
    ctx.lineTo(350, 800);
    ctx.stroke();

    // High speed Ring road
    ctx.beginPath();
    ctx.moveTo(500, -200);
    ctx.lineTo(500, 800);
    ctx.stroke();

    // Overlay golden street borders for high-fidelity vector feeling
    ctx.strokeStyle = 'rgba(245, 158, 11, 0.15)';
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.moveTo(-200, 235);
    ctx.lineTo(1000, 235);
    ctx.moveTo(-200, 265);
    ctx.lineTo(1000, 265);
    ctx.moveTo(335, -200);
    ctx.lineTo(335, 800);
    ctx.moveTo(365, -200);
    ctx.lineTo(365, 800);
    ctx.stroke();

    // 3. Draw adjacent greenery / park
    ctx.fillStyle = 'rgba(16, 185, 129, 0.04)';
    ctx.beginPath();
    ctx.arc(200, 380, 120, 0, Math.PI * 2);
    ctx.fill();

    // 4. Draw rivers / channels
    ctx.strokeStyle = 'rgba(59, 130, 246, 0.07)';
    ctx.lineWidth = 15;
    ctx.beginPath();
    ctx.moveTo(-200, 50);
    ctx.bezierCurveTo(200, -50, 400, 150, 1000, 50);
    ctx.stroke();

    // 5. Draw simple ambient vector building shapes
    ctx.fillStyle = '#090d16';
    ctx.strokeStyle = 'rgba(255,255,255,0.03)';
    ctx.lineWidth = 1;
    // surrounding houses
    ctx.fillRect(150, 120, 60, 50); ctx.strokeRect(150, 120, 60, 50);
    ctx.fillRect(240, 120, 50, 50); ctx.strokeRect(240, 120, 50, 50);
    ctx.fillRect(680, 210, 70, 80); ctx.strokeRect(680, 210, 70, 80);

    // 6. Draw POIs
    MAP_POIS.forEach((poi, idx) => {
      const isSelected = selectedPoiIndex === idx;

      // Draw pulsing ring around selected
      if (isSelected) {
        const pulse = (Date.now() % 1500) / 1500;
        ctx.strokeStyle = 'rgba(245, 158, 11, ' + (1.0 - pulse) + ')';
        ctx.lineWidth = 1.5;
        ctx.beginPath();
        ctx.arc(poi.x, poi.y, 10 + pulse * 28, 0, Math.PI * 2);
        ctx.stroke();
      }

      // Draw building/node frame
      ctx.fillStyle = isSelected ? '#f59e0b' : '#0f172a';
      ctx.strokeStyle = isSelected ? '#ffffff' : 'rgba(245, 158, 11, 0.4)';
      ctx.lineWidth = 2;

      ctx.beginPath();
      ctx.arc(poi.x, poi.y, 9, 0, Math.PI * 2);
      ctx.fill();
      ctx.stroke();

      // Small inner core
      ctx.fillStyle = isSelected ? '#000000' : '#f59e0b';
      ctx.beginPath();
      ctx.arc(poi.x, poi.y, 3, 0, Math.PI * 2);
      ctx.fill();

      // Text labels on map
      ctx.fillStyle = isSelected ? '#ffffff' : '#94a3b8';
      ctx.font = 'bold 10px font-sans';
      ctx.textAlign = 'center';
      ctx.fillText(poi.title.slice(0, 6), poi.x, poi.y - 15);
    });

    ctx.restore();

    animationFrameId = requestAnimationFrame(drawMap);
  }

  // Run draw loop
  drawMap();

  // Mouse / Touch event handling for dragging
  const handleMouseDown = (e: MouseEvent) => {
    isDraggingMap = true;
    startDragX = e.clientX - mapOffsetX;
    startDragY = e.clientY - mapOffsetY;
    canvas.style.cursor = 'grabbing';
  };

  const handleMouseMove = (e: MouseEvent) => {
    if (!isDraggingMap) return;
    mapOffsetX = e.clientX - startDragX;
    mapOffsetY = e.clientY - startDragY;
  };

  const handleMouseUp = () => {
    isDraggingMap = false;
    canvas.style.cursor = 'grab';
  };

  // Click handler to select POI
  const handleCanvasClick = (e: MouseEvent) => {
    // Determine canvas absolute click
    const rect = canvas.getBoundingClientRect();
    const clickX = e.clientX - rect.left;
    const clickY = e.clientY - rect.top;

    // Convert screen coordinates back into map virtual coordinates
    const mapClickX = (clickX - mapOffsetX) / mapZoom;
    const mapClickY = (clickY - mapOffsetY) / mapZoom;

    // Find closest POI in 20px threshold
    let clickedIdx = -1;
    let minDist = 25;

    MAP_POIS.forEach((poi, idx) => {
      const dist = Math.sqrt(Math.pow(poi.x - mapClickX, 2) + Math.pow(poi.y - mapClickY, 2));
      if (dist < minDist) {
        minDist = dist;
        clickedIdx = idx;
      }
    });

    if (clickedIdx !== -1) {
      focusPoiIndex(clickedIdx);
    }
  };

  // Attach canvas listeners
  canvas.addEventListener('mousedown', handleMouseDown);
  canvas.addEventListener('mousemove', handleMouseMove);
  canvas.addEventListener('mouseup', handleMouseUp);
  canvas.addEventListener('mouseleave', handleMouseUp);
  canvas.addEventListener('click', handleCanvasClick);

  // Zoom buttons
  elements.mapCtrlZoomIn?.addEventListener('click', () => {
    mapZoom = Math.min(2.5, mapZoom + 0.15);
  });
  elements.mapCtrlZoomOut?.addEventListener('click', () => {
    mapZoom = Math.max(0.6, mapZoom - 0.15);
  });
  elements.mapCtrlReset?.addEventListener('click', () => {
    mapZoom = 1.0;
    mapOffsetX = canvas.width / 2 - MAP_POIS[0].x * mapZoom;
    mapOffsetY = canvas.height / 2 - MAP_POIS[0].y * mapZoom;
    focusPoiIndex(0);
  });

  // Handle responsive canvas resize on frame resizing
  const resizeObserver = new ResizeObserver(entries => {
    for (let entry of entries) {
      canvas.width = entry.contentRect.width;
      canvas.height = entry.contentRect.height;
      // center active
      mapOffsetX = canvas.width / 2 - MAP_POIS[selectedPoiIndex].x * mapZoom;
      mapOffsetY = canvas.height / 2 - MAP_POIS[selectedPoiIndex].y * mapZoom;
    }
  });
  resizeObserver.observe(container!);
}

// Centering and details hydration on POI change
function focusPoiIndex(idx: number) {
  selectedPoiIndex = idx;
  const poi = MAP_POIS[idx];
  
  if (!poi) return;

  // Soft slide camera center physics
  const canvas = elements.mapCanvas;
  if (canvas) {
    mapOffsetX = canvas.width / 2 - poi.x * mapZoom;
    mapOffsetY = canvas.height / 2 - poi.y * mapZoom;
  }

  // Update Information DOM elements
  if (elements.poiMetaDist) elements.poiMetaDist.innerText = `距离: ${poi.distance}`;
  if (elements.poiMetaTitle) elements.poiMetaTitle.innerText = poi.title;
  if (elements.poiMetaDesc) elements.poiMetaDesc.innerText = poi.desc;

  // Update right-side rows styles
  const rows = document.querySelectorAll('#poi-rows-selector button');
  rows.forEach((row, rIdx) => {
    if (rIdx === idx) {
      row.className = "map-poi-row-btn w-full text-left p-3 rounded-xl bg-amber-500/10 border border-amber-500/30 transition flex items-center justify-between text-xs cursor-pointer shadow";
      row.querySelector('.text-slate-400')?.classList.replace('text-slate-400', 'text-white');
    } else {
      row.className = "map-poi-row-btn w-full text-left p-3 rounded-xl bg-[#05070f] border border-slate-900 hover:border-slate-800 transition flex items-center justify-between text-xs cursor-pointer";
    }
  });
}

// Bind clicks on right side POI items
if (elements.poiRowsSelector) {
  const rows = elements.poiRowsSelector.querySelectorAll('.map-poi-row-btn');
  rows.forEach(row => {
    row.addEventListener('click', (e) => {
      const target = e.currentTarget as HTMLElement;
      const idx = parseInt(target.getAttribute('data-idx') || '0', 10);
      focusPoiIndex(idx);
    });
  });
}

// ==================== FLOATING ONLINE CHAT SIMULATOR (小美) ====================

// Append bubble
function appendChatBubble(sender: 'user' | 'bot', text: string) {
  if (!elements.chatMessagesBox) return;

  const bubble = document.createElement('div');
  const isBot = sender === 'bot';
  
  bubble.className = `flex items-start gap-2.5 max-w-[85%] ${isBot ? 'self-start' : 'self-end flex-row-reverse'}`;
  
  const formattedText = text.replace(/\n/g, '<br/>');

  bubble.innerHTML = `
    <div class="w-7 h-7 rounded-full flex items-center justify-center text-xs shrink-0 select-none ${isBot ? 'bg-amber-500 text-black' : 'bg-slate-800 text-white'}">
      <span>${isBot ? '🤖' : '👤'}</span>
    </div>
    <div class="p-3 rounded-2xl text-[11px] leading-relaxed shadow-md ${isBot ? 'bg-slate-900 text-slate-300 rounded-tl-none border border-slate-900' : 'bg-amber-500 text-black rounded-tr-none'}">
      <p class="font-sans">${formattedText}</p>
    </div>
  `;

  elements.chatMessagesBox.appendChild(bubble);
  
  // scroll to bottom
  setTimeout(() => {
    if (elements.chatMessagesBox) {
      elements.chatMessagesBox.scrollTop = elements.chatMessagesBox.scrollHeight;
    }
  }, 50);
}

// Standard Bot Bot Replies
function triggerSmartReply(userMsg: string) {
  let reply = '';
  const msg = userMsg.trim().toLowerCase();

  if (msg.includes('求片') || msg.includes('想看') || msg.includes('怎么填') || msg.includes('工单')) {
    reply = `您好！在我们的【联系我们】页面中，特别设立了【提报需求工单】系统。\n您只需填写姓名和微信，并在详情里备注想要看的国产电影或电视剧名字、主演和年代，最后输入人类验证码‘SS’并发送，我们的24小时流媒体合规雷达系统和后台技术运维将在24小时内为您抓取上架！`;
  } else if (msg.includes('卡顿') || msg.includes('慢') || msg.includes('缓冲') || msg.includes('播放')) {
    reply = `您好！闪闪电影院采用自研的Shining-P2P异构分发算法，能够自动利用网民闲置的上行带宽进行流媒体极速分发。\n如果您遇到了缓冲缓慢或播放卡顿：\n1. 建议点击视频播放弹窗中的‘中继线路切换’，换用‘朝阳 BGP 极速 4K 加速专线’或‘北京电信骨干直连’；\n2. 检查您的设备（手机/电脑）是否开启了全局代理或VPN，关闭后可大幅提高流媒体下载速度；\n3. 如果依然卡顿，建议刷新页面或直接投射电视体验！`;
  } else if (msg.includes('免费') || msg.includes('会员') || msg.includes('注册') || msg.includes('收费')) {
    reply = `您好！闪闪影院在此做出终身承诺：【全场影视，终身免VIP卡、免注册登录、没有任何隐藏充值付费】！\n我们的视频采用P2P多端聚能算法分发，这极大缩减了传统的服务器流量带宽。日常运营和版权展示完全由北京闪闪数字流媒体科技有限公司提供公益资金扶植，请您绝对放心看片！`;
  } else if (msg.includes('广告') || msg.includes('合作') || msg.includes('邮箱') || msg.includes('联系')) {
    reply = `您好！我们热忱欢迎正规独立的影视版权方、华语制片厂或者高权重正规站长与我们开展展示合作或友链接洽。\n您可以直接发送详情至我们的核心邮箱：contact@shanshan-cinema.com，或添加官方微信客服：ShanshanCinema_2026。\n【安全合规提示】：我们坚决不接受任何涉及赌博、色情、网贷、虚假理财等违法暗色调商业广告，一经发现我们将直接拉黑退信。`;
  } else {
    reply = `您好！我是闪闪影院24小时全时在线AI智脑小美，已收到您的消息：【${userMsg}】。\n为了更好更迅速地帮助您：\n1. 需要找片？可在极速筛选大库中模糊检索，或者直接在‘联系我们’提交工单；\n2. 合作对接？可查阅我们的联系邮箱与微信号。\n闪闪电影院，让您快乐追剧！`;
  }

  // Simulate thinking bubble delay
  setTimeout(() => {
    appendChatBubble('bot', reply);
  }, 600);
}

// Chat Window triggers
if (elements.floatingChatTrigger) {
  elements.floatingChatTrigger.addEventListener('click', () => {
    elements.onlineChatWindow?.classList.remove('hidden');
    // Say initial welcome if empty
    if (elements.chatMessagesBox?.children.length === 0) {
      appendChatBubble('bot', '您好！我是闪闪电影院24h在线AI助手【小美】✨。我能为您解决大屏电视投屏故障排查、卡顿加速路由建议、求片工单自动受理或商务发布合作报价事宜。请问有什么我能帮您的？');
    }
  });
}

if (elements.chatWindowClose) {
  elements.chatWindowClose.addEventListener('click', () => {
    elements.onlineChatWindow?.classList.add('hidden');
  });
}

if (elements.chatSubmitForm) {
  elements.chatSubmitForm.addEventListener('submit', (e) => {
    e.preventDefault();
    const val = elements.chatUserInput.value;
    if (!val.trim()) return;

    appendChatBubble('user', val);
    elements.chatUserInput.value = '';
    
    triggerSmartReply(val);
  });
}

// Bind suggestions chips
if (elements.chatSuggestionBox) {
  const chips = elements.chatSuggestionBox.querySelectorAll('.chat-sugg-pill');
  chips.forEach(chip => {
    chip.addEventListener('click', () => {
      const text = (chip as HTMLElement).innerText;
      appendChatBubble('user', text);
      triggerSmartReply(text);
    });
  });
}

// Trigger chat from "联系我们" page button
if (elements.triggerOnlineChat) {
  elements.triggerOnlineChat.addEventListener('click', () => {
    elements.onlineChatWindow?.classList.remove('remove');
    elements.onlineChatWindow?.classList.remove('hidden');
    if (elements.chatMessagesBox?.children.length === 0) {
      appendChatBubble('bot', '您好！我是闪闪电影院24h在线AI助手【小美】✨。我能为您解决大屏电视投屏故障排查、卡顿加速路由建议、求片工单自动受理或商务发布合作报价事宜。请问有什么我能帮您的？');
    }
    elements.onlineChatWindow?.scrollIntoView({ behavior: 'smooth' });
  });
}

// ==================== KEY BINDINGS & QUICK SEARCH SHORTCUT ====================

// Bind quick Ctrl+F search keyboard focus
window.addEventListener('keydown', (e) => {
  if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'f') {
    e.preventDefault();
    switchTab('products');
    setTimeout(() => {
      elements.catalogSearchInput?.focus();
    }, 150);
  }
});

if (elements.searchShortcutBtn) {
  elements.searchShortcutBtn.addEventListener('click', () => {
    switchTab('products');
    setTimeout(() => {
      elements.catalogSearchInput?.focus();
    }, 150);
  });
}

if (elements.mobileSearchTrigger) {
  elements.mobileSearchTrigger.addEventListener('click', () => {
    switchTab('products');
    setTimeout(() => {
      elements.catalogSearchInput?.focus();
    }, 150);
  });
}

// ==================== OTHER STATIC BINDINGS ====================

// Logo button click back to home
if (elements.headerLogoBtn) elements.headerLogoBtn.addEventListener('click', () => switchTab('home'));
if (elements.footerLogoBtn) elements.footerLogoBtn.addEventListener('click', () => switchTab('home'));

// Mobile hamburger toggle
if (elements.mobileMenuHamburger && elements.mobileDrawer) {
  elements.mobileMenuHamburger.addEventListener('click', () => {
    elements.mobileDrawer?.classList.toggle('hidden');
  });
}

// Hero banner triggers
if (elements.heroPlayTrigger) {
  elements.heroPlayTrigger.addEventListener('click', () => {
    openStreamingModal('m2'); // Stream "流浪地球2：太空电梯" (id: m2)
  });
}

if (elements.heroCatalogTrigger) {
  elements.heroCatalogTrigger.addEventListener('click', () => {
    switchTab('products');
  });
}

if (elements.commitmentContactBtn) {
  elements.commitmentContactBtn.addEventListener('click', () => {
    switchTab('contact');
  });
}

if (elements.mobileContactTrigger) {
  elements.mobileContactTrigger.addEventListener('click', () => {
    switchTab('contact');
  });
}

if (elements.viewMorePopularBtn) {
  elements.viewMorePopularBtn.addEventListener('click', () => {
    filterType = '电视剧';
    switchTab('products');
    onFiltersChanged();
  });
}

// Catalog Search dynamic filter binds
if (elements.catalogSearchInput) {
  elements.catalogSearchInput.addEventListener('input', () => {
    searchQuery = elements.catalogSearchInput.value;
    
    if (searchQuery.trim() !== '') {
      elements.catalogSearchClear?.classList.remove('hidden');
    } else {
      elements.catalogSearchClear?.classList.add('hidden');
    }

    onFiltersChanged();
  });
}

if (elements.catalogSearchClear) {
  elements.catalogSearchClear.addEventListener('click', () => {
    searchQuery = '';
    elements.catalogSearchInput.value = '';
    elements.catalogSearchClear?.classList.add('hidden');
    onFiltersChanged();
  });
}

// Catalog filters pills bindings
const filterRows = ['pill-row-type', 'pill-row-region', 'pill-row-year', 'pill-row-rating'];
filterRows.forEach(rowId => {
  const rowEl = document.getElementById(rowId);
  if (rowEl) {
    const pills = rowEl.querySelectorAll('button');
    pills.forEach(pill => {
      pill.addEventListener('click', () => {
        const filterName = pill.getAttribute('data-filter');
        const filterVal = pill.getAttribute('data-value') || '全部';

        if (filterName === 'type') filterType = filterVal;
        if (filterName === 'region') filterRegion = filterVal;
        if (filterName === 'year') filterYear = filterVal;
        if (filterName === 'rating') filterRating = filterVal;

        onFiltersChanged();
      });
    });
  }
});

// Sort select change
if (elements.catalogSortSelect) {
  elements.catalogSortSelect.addEventListener('change', () => {
    filterSort = elements.catalogSortSelect.value;
    renderCatalogGrid();
  });
}

// Prev/Next page Binds
if (elements.btnPagePrev) {
  elements.btnPagePrev.addEventListener('click', () => {
    if (currentPage > 1) {
      currentPage--;
      renderCatalogGrid();
      window.scrollTo({ top: elements.tabProducts ? elements.tabProducts.offsetTop - 50 : 0, behavior: 'smooth' });
    }
  });
}

if (elements.btnPageNext) {
  elements.btnPageNext.addEventListener('click', () => {
    currentPage++;
    renderCatalogGrid();
    window.scrollTo({ top: elements.tabProducts ? elements.tabProducts.offsetTop - 50 : 0, behavior: 'smooth' });
  });
}

// Empty state reset button
if (elements.catalogEmptyReset) {
  elements.catalogEmptyReset.addEventListener('click', () => {
    resetAllFilters();
  });
}

// Footer site map tab link binders
const footerTabLinks = document.querySelectorAll('.footer-tab-link');
footerTabLinks.forEach(link => {
  link.addEventListener('click', (e) => {
    const tabName = (e.currentTarget as HTMLElement).getAttribute('data-tab') || 'home';
    switchTab(tabName);
  });
});

// Bind general nav tab links
const navTabs = document.querySelectorAll('.nav-tab, .mobile-tab-btn');
navTabs.forEach(tab => {
  tab.addEventListener('click', (e) => {
    const tabName = (e.currentTarget as HTMLElement).getAttribute('data-tab') || 'home';
    switchTab(tabName);
  });
});

// ==================== APP INITIALIZATION ====================
function initApplet() {
  // 1. Render all lists
  renderHomeMovies();
  renderHomeNews();
  renderCatalogGrid();
  renderAboutTab();
  renderTimelinePanel();

  // 2. Setup Filters Pills styling
  updateFilterActivePills();

  // 3. Focus first POI on Map
  setTimeout(() => {
    focusPoiIndex(0);
  }, 200);

  console.log("Shanshan Cinema Static App compiled and mounted successfully.");
}

// Start applet
initApplet();
