import './index.css';
import { MOVIES_DATA, NEWS_DATA, TEAM_MEMBERS, HISTORY_EVENTS, CORPORATE_CULTURE } from './data';
import { Movie } 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 - 2; // Default to 2025 or any valid event

// 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 = 42; // initial progress %
let playerVolume: number = 85;
let selectedPlaybackLine: string = '金箍棒 BGP 极速 4K 专线';
let playerTimerInterval: any = null;
let visualizerAnimationId: number | null = null;

// ==================== 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: "4399信息大厦B座研发总部",
    desc: "广州市天河区高新技术产业开发区核心。广州4399流媒体数字科技有限公司的智能分发研发总部。部署了天眼智能AI逐帧画质修复算力中心、金箍棒多线骨干极速分发云台，致力于为全网追剧爱好者打造无限制、免VIP的高清绿色播放端。",
    x: 400,
    y: 250,
    distance: "0米"
  },
  {
    title: "金箍棒五线 BGP 千兆骨干直连机房",
    desc: "广州科学城千兆高带宽多线BGP直连骨干机房。直连三大运营商与主流骨干骨架网，能够全天候支撑数千万用户在并发时段极速秒播最新高清免费电影、免费日韩、美剧国产剧等视频，免去缓冲卡顿困扰。",
    x: 580,
    y: 180,
    distance: "280米"
  },
  {
    title: "高新技术地铁站 A口",
    desc: "地铁4号线高新技术产业站核心枢纽。出站后步行约150米即可直达4399信息大厦B座商务大厅，是外部正版版权合作、展示加盟及企业商洽到访的标志坐标。",
    x: 290,
    y: 340,
    distance: "150米"
  }
];

// ==================== ELEMENT REFERENCES ====================
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'),
  footerTriggerChat: document.getElementById('footer-trigger-chat'),
  
  // Tab containers
  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 Tab Dynamic Grids
  homePopularMovies: document.getElementById('home-popular-movies'),
  homeLatestMovies: document.getElementById('home-latest-movies'),
  homeNewsGrid: document.getElementById('home-news-grid'),
  heroPlayTrigger: document.getElementById('hero-play-trigger'),
  heroCatalogTrigger: document.getElementById('hero-catalog-trigger'),
  commitmentContactBtn: document.getElementById('commitment-contact-btn'),
  
  // Products Tab Components
  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 Components
  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 Tab Components
  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'),
  
  // Embedded 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') as HTMLSelectElement,
  
  // Streaming Player Dialog Modal
  videoStreamDialog: document.getElementById('video-stream-dialog'),
  modalCloseTrigger: document.getElementById('modal-close-trigger'),
  modalDynamicContent: document.getElementById('modal-dynamic-content'),
  
  // Floating AI Assistant Components
  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')
};

// ==================== 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-white bg-emerald-600 border border-emerald-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-emerald-500/10 border border-emerald-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 smoothly
  window.scrollTo({ top: 0, behavior: 'smooth' });

  // Draw the map canvas if switched to contact tab
  if (tabName === 'contact') {
    setTimeout(() => {
      initMapCanvas();
    }, 150);
  }
}

// Create Card HTML for Movie (Supports direct image-link redirect + Card modal action)
function createMovieCardHTML(movie: Movie): string {
  const keyword = encodeURIComponent(movie.title + " 电影");
  const fallbackImgUrl = `https://tse-mm.bing.com/th?q=${keyword}`;
  const imgUrl = movie.imageUrl || fallbackImgUrl;
  
  return `
    <div class="movie-card relative bg-[#03120d]/60 border border-emerald-950/40 hover:border-emerald-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 Bing API click redirection 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} - 4399影视免费在线观看" 
            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-[#020906] 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/75 backdrop-blur text-emerald-400 border border-emerald-500/15 px-2 py-0.5 rounded shadow font-bold">
            ${movie.type}
          </span>
          ${movie.isFeatured ? '<span class="bg-gradient-to-r from-emerald-500 to-teal-500 text-[8px] font-black text-white px-1.5 py-0.5 rounded shadow tracking-wider uppercase font-extrabold">主打</span>' : ''}
        </div>

        <!-- Rating overlay -->
        <div class="absolute top-2.5 right-2.5 bg-black/75 backdrop-blur px-1.5 py-0.5 rounded border border-emerald-950/35 shadow flex items-center gap-0.5 text-[9px] font-mono text-emerald-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-[#020906]/85 backdrop-blur px-2 py-0.5 rounded border border-emerald-950/20 text-[9px] text-slate-400 font-mono pointer-events-none">
          ${movie.updateStatus}
        </div>

        <!-- Play Icon Hover Overlay -->
        <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-emerald-500 flex items-center justify-center text-white shadow-lg shadow-emerald-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-[#03120d]/80 text-left">
        <h4 class="text-white text-xs sm:text-sm font-black tracking-tight leading-tight truncate group-hover:text-emerald-400 transition duration-150 font-display">
          ${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('');

  bindMovieCardClicks();
}

// Render SEO News
function renderHomeNews() {
  if (!elements.homeNewsGrid) return;

  elements.homeNewsGrid.innerHTML = NEWS_DATA.map(item => {
    const detailUrl = `https://tse-mm.bing.com/th?q=${encodeURIComponent(item.title)}`;
    return `
      <div class="bg-[#03120d] border border-emerald-950/40 rounded-3xl overflow-hidden shadow hover:border-emerald-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-emerald-500/10 text-emerald-400 border border-emerald-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-emerald-400 transition font-display">
            <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-black/40 border-t border-emerald-950/20 flex items-center justify-between gap-4">
          <span class="text-[9px] text-slate-600 font-mono tracking-wider truncate max-w-[200px]">
            SEO: ${item.seoKeywords}
          </span>
          <a href="${detailUrl}" target="_blank" class="text-emerald-400 hover:text-emerald-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 Grid with complex filtering and paging (6 per page)
function renderCatalogGrid() {
  if (!elements.catalogMoviesGrid) return;

  // Filter list
  const filtered = MOVIES_DATA.filter(movie => {
    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());

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

    let matchRegion = true;
    if (filterRegion !== '全部') {
      if (filterRegion === '其他') {
        matchRegion = movie.region !== '大陆' && movie.region !== '港台' && movie.region !== '欧美' && movie.region !== '日韩';
      } else {
        matchRegion = movie.region === filterRegion;
      }
    }

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

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

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

  // Sort list
  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 playCount parsed to integer
    filtered.sort((a, b) => {
      const countA = parseInt(a.playCount.replace(/,/g, ''), 10);
      const countB = parseInt(b.playCount.replace(/,/g, ''), 10);
      return countB - countA;
    });
  }

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

  // Handle 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);

  // Show lists 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);
  }

  if (elements.btnPagePrev) elements.btnPagePrev.disabled = currentPage === 1;
  if (elements.btnPageNext) elements.btnPageNext.disabled = currentPage === maxPage;

  renderActiveTags();
}

// 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-emerald-600 text-white border border-emerald-400/20 shadow' : 'bg-[#03120d] hover:bg-emerald-950 text-slate-400 hover:text-white border border-emerald-950/40'}" data-page="${i}">
        ${i}
      </button>
    `;
  }
  elements.pageNumbersContainer.innerHTML = numbersHtml;

  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();
      // Scroll to catalog top container
      if (elements.tabProducts) {
        window.scrollTo({ top: elements.tabProducts.offsetTop - 40, behavior: 'smooth' });
      }
    });
  });
}

// Render active filters as breadcrumbs tags
function renderActiveTags() {
  if (!elements.activeTagsContainer) return;

  const tags: { type: string; value: string; label: string }[] = [];
  
  if (filterType !== '全部') tags.push({ type: 'type', value: filterType, label: `类型: ${filterType}` });
  if (filterRegion !== '全部') tags.push({ type: 'region', value: filterRegion, label: `地区: ${filterRegion}` });
  if (filterYear !== '全部') tags.push({ type: 'year', value: filterYear, label: `${filterYear}年` });
  if (filterRating !== '全部') tags.push({ type: 'rating', value: filterRating, label: `评分: ${filterRating}分+` });
  if (searchQuery.trim() !== '') tags.push({ type: 'search', value: searchQuery, label: `检索: "${searchQuery}"` });

  if (tags.length === 0) {
    elements.activeTagsContainer.innerHTML = `
      <span class="text-[10px] text-slate-500 font-mono">交叉规则:</span>
      <span class="text-[10px] text-slate-600 bg-[#03120d] px-2.5 py-1 rounded border border-emerald-950/20 font-mono">不限限流中继</span>
    `;
    return;
  }

  let tagsHtml = `<span class="text-[10px] text-slate-500 font-mono">交叉规则:</span>`;
  tagsHtml += tags.map(tag => `
    <span class="inline-flex items-center gap-1.5 bg-emerald-500/10 border border-emerald-500/20 text-emerald-400 text-[10px] font-bold px-2.5 py-1 rounded-lg font-sans shadow-sm">
      <span>${tag.label}</span>
      <button class="remove-tag-btn text-emerald-400 hover:text-white transition cursor-pointer font-bold text-xs" data-tag-type="${tag.type}">✕</button>
    </span>
  `).join('');

  elements.activeTagsContainer.innerHTML = tagsHtml;

  const rmButtons = document.querySelectorAll('.remove-tag-btn');
  rmButtons.forEach(btn => {
    btn.addEventListener('click', (e) => {
      const type = (e.currentTarget as HTMLElement).getAttribute('data-tag-type');
      if (type === 'type') {
        filterType = '全部';
        updatePillsRowSelection('type', '全部');
      } else if (type === 'region') {
        filterRegion = '全部';
        updatePillsRowSelection('region', '全部');
      } else if (type === 'year') {
        filterYear = '全部';
        updatePillsRowSelection('year', '全部');
      } else if (type === 'rating') {
        filterRating = '全部';
        updatePillsRowSelection('rating', '全部');
      } else if (type === 'search') {
        searchQuery = '';
        if (elements.catalogSearchInput) {
          elements.catalogSearchInput.value = '';
        }
        if (elements.catalogSearchClear) {
          elements.catalogSearchClear.classList.add('hidden');
        }
      }
      currentPage = 1;
      renderCatalogGrid();
    });
  });
}

// Update active states of pills row
function updatePillsRowSelection(filterKey: string, activeValue: string) {
  const pills = document.querySelectorAll(`.filter-pill[data-filter="${filterKey}"]`);
  pills.forEach(pill => {
    const val = pill.getAttribute('data-value');
    if (val === activeValue) {
      pill.className = "filter-pill px-3.5 py-1.5 rounded-lg font-bold border transition cursor-pointer bg-emerald-600 border-emerald-400 text-white shadow";
    } else {
      pill.className = "filter-pill px-3.5 py-1.5 rounded-lg font-bold border transition cursor-pointer bg-[#020906] border-emerald-950/40 text-slate-400 hover:text-white hover:border-emerald-800";
    }
  });
}

// Bind click action on movie cards to launch the modal
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 Us Team list, history timeline & cultures
function renderAboutTab() {
  if (elements.aboutTeamGrid) {
    elements.aboutTeamGrid.innerHTML = TEAM_MEMBERS.map(member => {
      const keyword = encodeURIComponent(member.name);
      const portraitUrl = member.imageUrl || `https://tse-mm.bing.com/th?q=${keyword}`;
      return `
        <div class="bg-[#03120d] border border-emerald-950/40 p-6 sm:p-8 rounded-3xl space-y-5 text-left group hover:border-emerald-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-emerald-900/20 bg-[#020906] shrink-0 shadow-lg">
            <a href="${portraitUrl}" target="_blank" class="block w-full h-full relative" onclick="event.stopPropagation();">
              <img 
                src="${portraitUrl}" 
                alt="${member.name} - 4399流媒体合伙人" 
                class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-105"
                referrerPolicy="no-referrer"
              />
            </a>
          </div>

          <div class="space-y-1">
            <h4 class="text-white font-black text-base font-display">${member.name}</h4>
            <span class="text-[10px] text-emerald-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('');
  }

  // Mission Vision Content
  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 => `
      <li class="flex items-center gap-1.5 text-slate-300">
        <span class="text-emerald-400">✨</span>
        <span>${val}</span>
      </li>
    `).join('');
  }

  renderTimelinePanel();
}

// Clickable milestones rendering
function renderTimelinePanel() {
  if (!elements.timelineYearsPanel) return;

  let timelineHtml = '';
  HISTORY_EVENTS.forEach((ev, idx) => {
    const isSelected = idx === selectedTimelineIndex;
    timelineHtml += `
      <button 
        class="timeline-year-selector w-full text-left px-5 py-4 rounded-2xl border transition duration-200 cursor-pointer flex items-center justify-between group ${isSelected ? 'bg-emerald-500/10 border-emerald-500/30 text-emerald-400 shadow-md' : 'bg-[#03120d] border-emerald-950/20 text-slate-400 hover:text-white hover:border-emerald-800'}"
        data-index="${idx}"
      >
        <span class="font-black text-sm font-mono tracking-wider">${ev.year}年</span>
        <div class="flex items-center gap-2 max-w-[70%]">
          <span class="text-xs font-bold truncate block group-hover:text-white font-display">${ev.title}</span>
          <span class="text-emerald-400 opacity-60 text-xs shrink-0 group-hover:translate-x-1 transition-transform">&rarr;</span>
        </div>
      </button>
    `;
  });

  elements.timelineYearsPanel.innerHTML = timelineHtml;

  const years = document.querySelectorAll('.timeline-year-selector');
  years.forEach(yr => {
    yr.addEventListener('click', (e) => {
      const idx = parseInt((e.currentTarget as HTMLElement).getAttribute('data-index') || '0', 10);
      selectedTimelineIndex = idx;
      
      const event = HISTORY_EVENTS[selectedTimelineIndex];
      if (elements.timelineYearBig) elements.timelineYearBig.innerText = event.year;
      if (elements.timelineTitleDisplay) elements.timelineTitleDisplay.innerText = event.title;
      if (elements.timelineDescDisplay) elements.timelineDescDisplay.innerText = event.description;

      renderTimelinePanel();
    });
  });

  // Init initial details text
  const initialEv = HISTORY_EVENTS[selectedTimelineIndex];
  if (initialEv) {
    if (elements.timelineYearBig) elements.timelineYearBig.innerText = initialEv.year;
    if (elements.timelineTitleDisplay) elements.timelineTitleDisplay.innerText = initialEv.title;
    if (elements.timelineDescDisplay) elements.timelineDescDisplay.innerText = initialEv.description;
  }
}

// ==================== ONLINE CUSTOMER SERVICE HELPER ====================

const CHAT_SUGGESTIONS = [
  "如何用手机免VIP观看最新电影电视剧？",
  "支持哪些魔镜无线电视投屏大屏协议？",
  "播放卡顿如何自主调配金箍棒极速中继？",
  "关于4399影视的数字合规与侵权申诉"
];

const AI_REPLY_SCRIPT: { [key: string]: string } = {
  "如何用手机免VIP观看最新电影电视剧？": 
    "4399影视官方服务承诺：<strong>全平台所有的电影、电视剧、动漫和综艺资源均提供终身免费观看！</strong> 您只需点击任何影片海报，在弹出面板中点击“立即点播”即可秒速开播。系统会自动根据您的网络分流到最通畅的高速节点，绝无高昂收费或VIP限制门槛，享受极致清流体验！",
  "支持哪些魔镜无线电视投屏大屏协议？":
    "4399影视自研的<strong>“大屏魔镜投屏协议”</strong>，在底层完全兼容和支持：<strong>DLNA国际投屏标准</strong>、<strong>苹果 AirPlay 视听镜像通道</strong>、以及<strong>安卓多端无线投屏</strong>。只要您手机和电视投影设备处于同一家庭网，在影片模拟播放器一键‘无线投屏’即可秒速在大屏畅看4K画质！",
  "播放卡顿如何自主调配金箍棒极速中继？":
    "如果在极高并发追剧时段遇到轻微缓存，您可以随时在模拟播放器面板下方的“量子加速选路”选择其他专线节点：\n- 推荐首选：<strong>金箍棒 BGP 极速 4K 专线</strong> (负载低)\n- 备用节点：<strong>华南千兆多路由骨干网</strong>\n- 备用直连：<strong>5G 手机高速免卡加速道</strong>\n换线路后系统会自动优化网络，保证毫秒级秒开秒播！",
  "关于4399影视的数字合规与侵权申诉":
    "4399影视高度尊重且敬畏数字版权。本平台展示的所有最新免费电影和日韩美剧，均通过高信誉AI智能雷达过滤，采集自公开发行源或加盟制作方，不含任何垃圾弹窗广告。若您认为有侵权争议，请随时将版权文件发送至官方邮箱 <strong>complaint@4399tv.com</strong>，我们将在24小时内极速处理核实并安排下架！"
};

function initOnlineChatHelper() {
  if (!elements.chatSuggestionBox || !elements.chatMessagesBox) return;

  elements.chatSuggestionBox.innerHTML = CHAT_SUGGESTIONS.map(s => `
    <button type="button" class="chat-sugg-btn bg-emerald-500/10 border border-emerald-500/20 hover:bg-emerald-500/20 text-emerald-400 px-2.5 py-1 rounded-lg transition text-left cursor-pointer font-sans truncate max-w-full text-[10px]">
      ${s}
    </button>
  `).join('');

  appendChatBubble('bot', `您好！我是4399流媒体的<strong>7x24小时智能AI客服助理</strong>，非常荣幸为您提供技术指导与求片协助！<br/><br/>本平台承诺：<strong>全站最新高清免费电影、日韩大作、美剧国产剧影视大全支持终身免费观看，彻底拒绝套路</strong>。请问有什么可以帮您解答？`);

  const suggBtns = document.querySelectorAll('.chat-sugg-btn');
  suggBtns.forEach(btn => {
    btn.addEventListener('click', (e) => {
      const text = (e.currentTarget as HTMLElement).innerText.trim();
      handleUserChatQuery(text);
    });
  });
}

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

  const bubble = document.createElement('div');
  bubble.className = `flex gap-2.5 max-w-[85%] ${sender === 'user' ? 'self-end ml-auto flex-row-reverse text-right' : 'self-start mr-auto text-left'}`;
  
  const avatar = sender === 'user' ? '🙋' : '🤖';
  const bgClass = sender === 'user' ? 'bg-emerald-600 text-white font-medium shadow-md' : 'bg-[#03120d]/95 text-slate-100 border border-emerald-950/40';

  bubble.innerHTML = `
    <div class="w-7 h-7 rounded-full bg-slate-950 flex items-center justify-center shrink-0 text-xs shadow-md border border-emerald-500/20 select-none">${avatar}</div>
    <div class="${bgClass} px-3.5 py-2.5 rounded-2xl leading-relaxed text-xs font-sans whitespace-pre-line">
      ${text}
    </div>
  `;

  elements.chatMessagesBox.appendChild(bubble);
  elements.chatMessagesBox.scrollTop = elements.chatMessagesBox.scrollHeight;
}

function handleUserChatQuery(text: string) {
  if (text.trim() === '') return;

  appendChatBubble('user', text);

  setTimeout(() => {
    const reply = AI_REPLY_SCRIPT[text];
    if (reply) {
      appendChatBubble('bot', reply);
    } else {
      appendChatBubble('bot', `收到您的反馈！已自动将有关<strong>“${text}”</strong>的信息匹配并汇入4399影视客服调度中心工单中。<br/><br/>平台始终维护追剧爱好者的核心权益，如有漏片或投屏故障，请在‘联系我们’页面登记详细手机号与邮箱，我们的技术小哥将在半小时内核实跟进！`);
    }
  }, 450);
}

// ==================== INTERACTIVE HEADQUARTERS VECTOR MAP ====================

function initMapCanvas() {
  const canvas = elements.mapCanvas;
  if (!canvas) return;

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

  const rect = canvas.getBoundingClientRect();
  canvas.width = rect.width * window.devicePixelRatio;
  canvas.height = rect.height * window.devicePixelRatio;
  ctx.scale(window.devicePixelRatio, window.devicePixelRatio);

  drawMapGrid(ctx, rect.width, rect.height);
}

function drawMapGrid(ctx: CanvasRenderingContext2D, width: number, height: number) {
  ctx.clearRect(0, 0, width, height);

  ctx.save();
  // Apply zooming and panning offsets
  ctx.translate(width / 2 + mapOffsetX, height / 2 + mapOffsetY);
  ctx.scale(mapZoom, mapZoom);
  ctx.translate(-width / 2, -height / 2);

  // 1. Grid Mesh Background
  ctx.strokeStyle = '#051812';
  ctx.lineWidth = 0.5;
  const gridSize = 40;
  for (let x = -gridSize * 10; x < width + gridSize * 10; x += gridSize) {
    ctx.beginPath();
    ctx.moveTo(x, -height * 5);
    ctx.lineTo(x, height * 5);
    ctx.stroke();
  }
  for (let y = -gridSize * 10; y < height + gridSize * 10; y += gridSize) {
    ctx.beginPath();
    ctx.moveTo(-width * 5, y);
    ctx.lineTo(width * 5, y);
    ctx.stroke();
  }

  // 2. Main simulated highway coordinates networks
  ctx.strokeStyle = '#020d09';
  ctx.lineWidth = 24;
  ctx.lineCap = 'round';
  ctx.lineJoin = 'round';

  // Road 1: High Tech ring
  ctx.beginPath();
  ctx.moveTo(-width, 250);
  ctx.lineTo(width * 2, 250);
  ctx.stroke();

  // Road 2: Science ring road
  ctx.beginPath();
  ctx.moveTo(100, -height);
  ctx.lineTo(600, height * 2);
  ctx.stroke();

  // Inner lines
  ctx.strokeStyle = '#041d14';
  ctx.lineWidth = 20;
  ctx.stroke();

  // Dotted separator
  ctx.strokeStyle = '#10b981';
  ctx.lineWidth = 1;
  ctx.setLineDash([8, 8]);
  ctx.beginPath();
  ctx.moveTo(-width, 250);
  ctx.lineTo(width * 2, 250);
  ctx.moveTo(100, -height);
  ctx.lineTo(600, height * 2);
  ctx.stroke();
  ctx.setLineDash([]); // clear dash

  // 3. Simulated Eco-Lake representing 대湾区 (Greater Bay Area landscape)
  ctx.fillStyle = '#031711';
  ctx.beginPath();
  ctx.arc(680, 420, 110, 0, Math.PI * 2);
  ctx.fill();
  ctx.strokeStyle = '#34d399';
  ctx.lineWidth = 0.5;
  ctx.stroke();

  ctx.fillStyle = '#10b981';
  ctx.font = '9px monospace';
  ctx.fillText("大湾区流媒体数字文创湖泊", 610, 410);

  // Labels
  ctx.fillStyle = '#047857';
  ctx.font = '10px monospace';
  ctx.fillText("粤港澳科技创新星光大路", 80, 235);
  ctx.fillText("科学城智造主干道", 480, 490);

  // 4. Landmarks nodes
  MAP_POIS.forEach((poi, idx) => {
    const isSelected = idx === selectedPoiIndex;
    
    // Pulse circle
    if (isSelected) {
      ctx.fillStyle = 'rgba(16, 185, 129, 0.2)';
      ctx.beginPath();
      const pulseSize = 25 + Math.sin(Date.now() / 150) * 4;
      ctx.arc(poi.x, poi.y, pulseSize, 0, Math.PI * 2);
      ctx.fill();
    }

    // Outer node dot
    ctx.fillStyle = isSelected ? '#10b981' : '#042f20';
    ctx.strokeStyle = isSelected ? '#ffffff' : '#059669';
    ctx.lineWidth = isSelected ? 2.5 : 1.5;
    
    ctx.beginPath();
    ctx.arc(poi.x, poi.y, isSelected ? 9 : 6.5, 0, Math.PI * 2);
    ctx.fill();
    ctx.stroke();

    // Text tag
    ctx.fillStyle = isSelected ? '#ffffff' : '#a7f3d0';
    ctx.font = isSelected ? 'bold 11px font-sans' : '10px font-sans';
    const tagPrefix = idx === 0 ? "🏢 " : idx === 1 ? "📡 " : "🚇 ";
    ctx.fillText(tagPrefix + poi.title, poi.x - 70, poi.y - 16);
  });

  ctx.restore();
}

function setupMapControls() {
  const canvas = elements.mapCanvas;
  if (!canvas) return;

  elements.mapCtrlZoomIn?.addEventListener('click', () => {
    mapZoom = Math.min(2.5, mapZoom + 0.15);
    initMapCanvas();
  });

  elements.mapCtrlZoomOut?.addEventListener('click', () => {
    mapZoom = Math.max(0.65, mapZoom - 0.15);
    initMapCanvas();
  });

  elements.mapCtrlReset?.addEventListener('click', () => {
    mapZoom = 1.0;
    mapOffsetX = 0;
    mapOffsetY = 0;
    selectedPoiIndex = 0;
    if (elements.poiRowsSelector) {
      elements.poiRowsSelector.value = "0";
    }
    updatePoiMetaCard(0);
    initMapCanvas();
  });

  // Selector dropdown
  elements.poiRowsSelector?.addEventListener('change', (e) => {
    const idx = parseInt((e.target as HTMLSelectElement).value, 10);
    panToPoi(idx);
  });

  // Mouse Drag Panning
  canvas.addEventListener('mousedown', (e) => {
    isDraggingMap = true;
    startDragX = e.clientX - mapOffsetX;
    startDragY = e.clientY - mapOffsetY;
  });

  window.addEventListener('mousemove', (e) => {
    if (!isDraggingMap) return;
    mapOffsetX = e.clientX - startDragX;
    mapOffsetY = e.clientY - startDragY;
    initMapCanvas();
  });

  window.addEventListener('mouseup', () => {
    isDraggingMap = false;
  });

  // Touch drag for mobile
  canvas.addEventListener('touchstart', (e) => {
    if (e.touches.length === 1) {
      isDraggingMap = true;
      startDragX = e.touches[0].clientX - mapOffsetX;
      startDragY = e.touches[0].clientY - mapOffsetY;
    }
  });

  canvas.addEventListener('touchmove', (e) => {
    if (isDraggingMap && e.touches.length === 1) {
      mapOffsetX = e.touches[0].clientX - startDragX;
      mapOffsetY = e.touches[0].clientY - startDragY;
      initMapCanvas();
    }
  });

  canvas.addEventListener('touchend', () => {
    isDraggingMap = false;
  });

  // Periodic pulse loops
  setInterval(() => {
    if (currentTab === 'contact') {
      initMapCanvas();
    }
  }, 250);
}

function panToPoi(idx: number) {
  selectedPoiIndex = idx;
  const poi = MAP_POIS[idx];

  mapZoom = 1.25;
  mapOffsetX = 0;
  mapOffsetY = 0;
  
  const canvas = elements.mapCanvas;
  if (canvas) {
    const rect = canvas.getBoundingClientRect();
    mapOffsetX = (rect.width / 2) - poi.x;
    mapOffsetY = (rect.height / 2) - poi.y;
  }

  updatePoiMetaCard(idx);
  initMapCanvas();
}

function updatePoiMetaCard(idx: number) {
  const poi = MAP_POIS[idx];
  if (elements.poiMetaDist) elements.poiMetaDist.innerText = poi.distance;
  if (elements.poiMetaTitle) elements.poiMetaTitle.innerText = poi.title;
  if (elements.poiMetaDesc) elements.poiMetaDesc.innerText = poi.desc;
}

// ==================== STREAMING PLAYER DIALOG MODAL ====================

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.classList.add('overflow-hidden');

  isPlayerPlaying = true;
  playerProgress = 15 + Math.floor(Math.random() * 30);
  
  initPlayerTicker(movie);
  renderPlayerInsideModal(movie);
  startVisualizerAnimation();
}

function renderPlayerInsideModal(movie: Movie) {
  if (!elements.modalDynamicContent) return;

  elements.modalDynamicContent.innerHTML = `
    <div class="flex flex-col text-left">
      
      <!-- Video stream visual simulated box with equalizers -->
      <div class="relative aspect-video w-full bg-black flex flex-col items-center justify-center border-b border-emerald-950/20 group overflow-hidden">
        
        <!-- Rotating Loading halo -->
        <div id="video-canvas-halo" class="absolute inset-0 flex flex-col items-center justify-center bg-[#020906] pointer-events-none select-none z-10 transition-opacity duration-500">
          <div class="w-16 h-16 rounded-full border-4 border-emerald-500/25 border-t-emerald-400 animate-spin flex items-center justify-center">
            <span class="text-xs text-emerald-400 font-black font-mono">4399</span>
          </div>
          <p id="player-buffering-msg" class="text-[10px] text-emerald-400 font-mono tracking-widest uppercase mt-4">金箍棒5G专线硬解码极速缓冲中...</p>
        </div>

        <!-- Video stream graphics Canvas -->
        <canvas id="movie-stream-canvas" class="w-full h-full block absolute inset-0 z-10"></canvas>

        <!-- Big Play/Pause Toggle Hover overlay -->
        <div class="absolute inset-0 z-20 flex items-center justify-center bg-black/45 opacity-0 group-hover:opacity-100 transition duration-200">
          <button id="player-mid-toggle" class="w-14 h-14 rounded-full bg-emerald-500 hover:bg-emerald-400 text-white flex items-center justify-center shadow-lg shadow-emerald-500/20 transform scale-90 group-hover:scale-100 transition duration-200 cursor-pointer">
            <span class="text-xl" id="mid-toggle-icon">${isPlayerPlaying ? '⏸' : '▶️'}</span>
          </button>
        </div>

        <!-- Bottom Controller overlay -->
        <div class="absolute bottom-0 left-0 right-0 z-30 bg-gradient-to-t from-black/95 via-black/80 to-transparent p-4 pt-10 flex flex-col gap-3 font-mono">
          
          <!-- Seeker slider range -->
          <div class="flex items-center gap-3">
            <span id="player-time-curr" class="text-[10px] text-slate-400">00:23:45</span>
            <input 
              type="range" 
              id="player-progress-range" 
              min="0" 
              max="100" 
              value="${playerProgress}" 
              class="flex-grow accent-emerald-500 h-1 rounded-lg cursor-pointer bg-slate-800"
            />
            <span id="player-time-total" class="text-[10px] text-slate-400">${movie.durationOrEpisodes.split('/')[0]}</span>
          </div>

          <!-- Bottom controls -->
          <div class="flex items-center justify-between">
            <div class="flex items-center gap-4">
              <button id="player-bottom-play-btn" class="text-emerald-400 hover:text-white transition text-xs font-bold cursor-pointer">
                暂停 ⏸
              </button>
              <div class="flex items-center gap-1.5 text-[10px] text-slate-500">
                <span>专线:</span>
                <span id="player-line-indicator" class="text-emerald-400 font-bold">${selectedPlaybackLine}</span>
              </div>
            </div>

            <!-- Volume controller -->
            <div class="flex items-center gap-2">
              <span class="text-[10px] text-slate-400">音量</span>
              <input 
                type="range" 
                id="player-volume-range" 
                min="0" 
                max="100" 
                value="${playerVolume}" 
                class="w-16 sm:w-24 accent-emerald-500 h-1 rounded-lg cursor-pointer bg-slate-800"
              />
              <span class="text-[10px] text-slate-400" id="player-vol-val">${playerVolume}%</span>
            </div>
          </div>

        </div>

      </div>

      <!-- Details zone of the movie -->
      <div class="p-6 sm:p-8 space-y-6">
        
        <div class="flex flex-col sm:flex-row sm:items-start justify-between gap-4 border-b border-emerald-950/20 pb-5">
          <div class="space-y-1.5">
            <div class="flex flex-wrap items-center gap-2">
              <span class="bg-emerald-500/10 text-emerald-400 border border-emerald-500/20 text-[10px] font-bold px-2.5 py-0.5 rounded-md font-mono">${movie.type}</span>
              <span class="text-xs text-slate-500 font-mono">${movie.genre}</span>
            </div>
            <h3 class="text-xl sm:text-2xl font-black text-white font-display leading-tight">${movie.title}</h3>
            <p class="text-[10px] text-slate-500 font-mono">导演: ${movie.director} &nbsp;|&nbsp; 领衔主演: ${movie.actors}</p>
          </div>

          <!-- Big AirCast click trigger -->
          <button id="player-aircast-btn" class="bg-[#03120d] hover:bg-emerald-950/20 border border-emerald-900/30 text-emerald-400 font-extrabold text-xs px-5 py-3.5 rounded-xl transition flex items-center justify-center gap-1.5 cursor-pointer shadow-md shrink-0">
            <span>📲 一键大屏魔镜投屏组件配对</span>
          </button>
        </div>

        <div class="grid grid-cols-1 md:grid-cols-12 gap-8">
          
          <!-- Left Column: Details -->
          <div class="md:col-span-8 space-y-4">
            <h5 class="text-white font-bold text-xs font-mono tracking-wider uppercase text-emerald-400">影片详情介绍 & 百度SEO快照概要</h5>
            <p class="text-xs sm:text-sm text-slate-400 leading-relaxed font-sans">
              ${movie.description}
            </p>
            <div class="p-4 bg-[#03120d] border border-emerald-500/10 rounded-2xl text-[11px] text-emerald-400 leading-relaxed font-mono">
              <strong>4399影视极速选路温馨指引：</strong> 本站秉持完全公益之原则。如果您在观看《${movie.title}》时遇网络阻塞，请调换下侧的“金箍棒加速专线分流中继”。本片支持免VIP投影大屏！
            </div>
          </div>

          <!-- Right Column: route selectors -->
          <div class="md:col-span-4 space-y-4">
            <h5 class="text-white font-bold text-xs font-mono tracking-wider uppercase text-emerald-400">5G金箍棒智能加速分流</h5>
            
            <div class="flex flex-col gap-2 font-mono text-[11px]">
              <button class="line-route-btn w-full px-4 py-3 rounded-xl text-left border transition cursor-pointer flex items-center justify-between bg-emerald-500/10 border-emerald-500/40 text-emerald-400" data-line-name="金箍棒 BGP 极速 4K 专线">
                <span>金箍棒 BGP 极速 4K 专线</span>
                <span class="text-[9px] text-emerald-400 font-bold">8ms (畅通)</span>
              </button>
              <button class="line-route-btn w-full px-4 py-3 rounded-xl text-left border transition cursor-pointer flex items-center justify-between bg-slate-900/80 border-emerald-950/40 text-slate-400 hover:text-white" data-line-name="华南千兆多路由骨干网">
                <span>华南千兆多路由骨干网</span>
                <span class="text-[9px] text-emerald-400 font-bold">14ms (正常)</span>
              </button>
              <button class="line-route-btn w-full px-4 py-3 rounded-xl text-left border transition cursor-pointer flex items-center justify-between bg-slate-900/80 border-emerald-950/40 text-slate-400 hover:text-white" data-line-name="5G 手机高速免卡加速道">
                <span>5G 手机高速免卡加速道</span>
                <span class="text-[9px] text-teal-400 font-bold">25ms (通畅)</span>
              </button>
            </div>
          </div>

        </div>

      </div>
    </div>
  `;

  // Hide the loading halo after 1.2s to simulate buffer completed
  setTimeout(() => {
    const halo = document.getElementById('video-canvas-halo');
    if (halo) {
      halo.classList.add('opacity-0');
      setTimeout(() => halo.classList.add('hidden'), 500);
    }
  }, 1200);

  // Bind controls inside modal
  setupPlayerControlListeners();
}

function setupPlayerControlListeners() {
  const midToggle = document.getElementById('player-mid-toggle');
  const bottomPlay = document.getElementById('player-bottom-play-btn');
  const progressRange = document.getElementById('player-progress-range') as HTMLInputElement;
  const volumeRange = document.getElementById('player-volume-range') as HTMLInputElement;
  const lineIndicator = document.getElementById('player-line-indicator');
  const aircastBtn = document.getElementById('player-aircast-btn');

  const togglePlay = () => {
    isPlayerPlaying = !isPlayerPlaying;
    
    // Update icons
    if (midToggle) {
      midToggle.innerHTML = `<span class="text-xl">${isPlayerPlaying ? '⏸' : '▶️'}</span>`;
    }
    if (bottomPlay) {
      bottomPlay.innerText = isPlayerPlaying ? '暂停 ⏸' : '播放 ▶️';
    }
    
    const bufferingMsg = document.getElementById('player-buffering-msg');
    if (bufferingMsg) {
      bufferingMsg.innerText = isPlayerPlaying ? "金箍棒5G专线硬解码极速缓冲中..." : "播放已暂停";
    }
  };

  midToggle?.addEventListener('click', togglePlay);
  bottomPlay?.addEventListener('click', togglePlay);

  progressRange?.addEventListener('input', (e) => {
    playerProgress = parseInt((e.target as HTMLInputElement).value, 10);
    updatePlayerTimeDisplay();
  });

  volumeRange?.addEventListener('input', (e) => {
    playerVolume = parseInt((e.target as HTMLInputElement).value, 10);
    const volVal = document.getElementById('player-vol-val');
    if (volVal) volVal.innerText = `${playerVolume}%`;
  });

  // Switch line routes
  const routeBtns = document.querySelectorAll('.line-route-btn');
  routeBtns.forEach(btn => {
    btn.addEventListener('click', (e) => {
      const target = e.currentTarget as HTMLElement;
      const lineName = target.getAttribute('data-line-name') || '';
      selectedPlaybackLine = lineName;

      if (lineIndicator) lineIndicator.innerText = lineName;

      // Update button visual highlights
      routeBtns.forEach(b => {
        b.className = "line-route-btn w-full px-4 py-3 rounded-xl text-left border transition cursor-pointer flex items-center justify-between bg-slate-900/80 border-emerald-950/40 text-slate-400 hover:text-white";
      });
      target.className = "line-route-btn w-full px-4 py-3 rounded-xl text-left border transition cursor-pointer flex items-center justify-between bg-emerald-500/10 border-emerald-500/40 text-emerald-400";

      showToast("专线切换成功", `4399金箍棒加速节点已极速换路重构为: [${lineName}]`);
    });
  });

  // AirCast投屏
  aircastBtn?.addEventListener('click', () => {
    showToast("大屏投屏配对成功", "智能魔镜无线大屏连播投屏系统已启动，DLNA大屏交互信流已推送完毕，请查看您的客厅百吋大屏！");
  });
}

function initPlayerTicker(movie: Movie) {
  if (playerTimerInterval) clearInterval(playerTimerInterval);

  playerTimerInterval = setInterval(() => {
    if (isPlayerPlaying) {
      playerProgress = (playerProgress + 0.1) % 100;
      const range = document.getElementById('player-progress-range') as HTMLInputElement;
      if (range) range.value = playerProgress.toString();
      updatePlayerTimeDisplay();
    }
  }, 1000);
}

function updatePlayerTimeDisplay() {
  const currEl = document.getElementById('player-time-curr');
  if (!currEl) return;

  const totalMinutes = 120; // fallback duration total
  const elapsedSecs = Math.floor((playerProgress / 100) * totalMinutes * 60);
  
  const h = Math.floor(elapsedSecs / 3600).toString().padStart(2, '0');
  const m = Math.floor((elapsedSecs % 3600) / 60).toString().padStart(2, '0');
  const s = (elapsedSecs % 60).toString().padStart(2, '0');

  currEl.innerText = `${h}:${m}:${s}`;
}

// Procedural dynamic equalizer canvas visualization inside movie player
function startVisualizerAnimation() {
  if (visualizerAnimationId) cancelAnimationFrame(visualizerAnimationId);

  const canvas = document.getElementById('movie-stream-canvas') as HTMLCanvasElement;
  if (!canvas) return;

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

  const resizeCanvas = () => {
    const rect = canvas.getBoundingClientRect();
    if (canvas.width !== rect.width || canvas.height !== rect.height) {
      canvas.width = rect.width;
      canvas.height = rect.height;
    }
  };

  resizeCanvas();

  let tick = 0;
  const barsCount = 48;
  const bars: { x: number; targetH: number; currH: number }[] = [];

  for (let i = 0; i < barsCount; i++) {
    bars.push({ x: 0, targetH: 0, currH: 0 });
  }

  const render = () => {
    resizeCanvas();
    tick++;

    const w = canvas.width;
    const h = canvas.height;

    // Draw tech mesh background
    ctx.fillStyle = '#010503';
    ctx.fillRect(0, 0, w, h);

    // Draw decorative grid
    ctx.strokeStyle = 'rgba(16, 185, 129, 0.04)';
    ctx.lineWidth = 1;
    const gSize = 25;
    for (let gx = 0; gx < w; gx += gSize) {
      ctx.beginPath();
      ctx.moveTo(gx, 0);
      ctx.lineTo(gx, h);
      ctx.stroke();
    }
    for (let gy = 0; gy < h; gy += gSize) {
      ctx.beginPath();
      ctx.moveTo(0, gy);
      ctx.lineTo(w, gy);
      ctx.stroke();
    }

    // Glowing nebula circle in the middle representing video
    const cx = w / 2;
    const cy = h / 2;
    const pulseRadius = 70 + Math.sin(tick * 0.05) * 8;
    
    const grad = ctx.createRadialGradient(cx, cy, 10, cx, cy, pulseRadius + 40);
    grad.addColorStop(0, 'rgba(4, 30, 20, 0.6)');
    grad.addColorStop(0.5, 'rgba(16, 185, 129, 0.05)');
    grad.addColorStop(1, 'rgba(0,0,0,0)');
    ctx.fillStyle = grad;
    ctx.beginPath();
    ctx.arc(cx, cy, pulseRadius + 50, 0, Math.PI * 2);
    ctx.fill();

    // Orbiting particles or scanning laser
    ctx.strokeStyle = 'rgba(52, 211, 153, 0.15)';
    ctx.lineWidth = 0.5;
    ctx.beginPath();
    ctx.arc(cx, cy, pulseRadius, 0, Math.PI * 2);
    ctx.stroke();

    // Scanner beam
    const angle = (tick * 0.02) % (Math.PI * 2);
    ctx.strokeStyle = 'rgba(16, 185, 129, 0.4)';
    ctx.lineWidth = 1.5;
    ctx.beginPath();
    ctx.moveTo(cx, cy);
    ctx.lineTo(cx + Math.cos(angle) * pulseRadius, cy + Math.sin(angle) * pulseRadius);
    ctx.stroke();

    // Procedural equalizer bars at bottom
    const barW = (w / barsCount) - 3;
    ctx.fillStyle = 'rgba(16, 185, 129, 0.35)';
    
    for (let i = 0; i < barsCount; i++) {
      if (isPlayerPlaying) {
        // dynamic heights with sin frequencies
        bars[i].targetH = 20 + Math.abs(Math.sin(tick * 0.1 + i * 0.4)) * (h * 0.35);
        bars[i].targetH += Math.abs(Math.cos(tick * 0.05 + i * 0.7)) * 15;
      } else {
        // settle to baseline flat line if paused
        bars[i].targetH = 2;
      }
      // linear interpolation for smooth motion
      bars[i].currH += (bars[i].targetH - bars[i].currH) * 0.2;

      const bx = i * (barW + 3) + 1.5;
      const by = h - bars[i].currH - 35; // offset above seeker controller overlay

      // Draw rounded rect bar
      ctx.fillRect(bx, by, barW, bars[i].currH);
    }

    // Glowing text overlay indicating streaming details
    ctx.fillStyle = '#a7f3d0';
    ctx.font = '9px monospace';
    ctx.textAlign = 'center';
    ctx.fillText(`[4399影视 5G-A安全加密传输通道正常] 线路负载: ${(30 + Math.sin(tick * 0.03) * 8).toFixed(1)}% &bull; 天眼AI 8K超分画质输出`, w / 2, cy);

    // Dynamic timer watermark
    const now = new Date();
    ctx.fillText(`${now.toLocaleDateString()} ${now.toLocaleTimeString()} UTC`, w / 2, cy + 20);

    visualizerAnimationId = requestAnimationFrame(render);
  };

  render();
}

function closeStreamingModal() {
  if (elements.videoStreamDialog) {
    elements.videoStreamDialog.classList.add('hidden');
    elements.videoStreamDialog.classList.remove('flex');
    document.body.classList.remove('overflow-hidden');
  }

  if (playerTimerInterval) clearInterval(playerTimerInterval);
  if (visualizerAnimationId) cancelAnimationFrame(visualizerAnimationId);
}

// ==================== GLOBAL TOAST HELPER ====================

function showToast(title: string, desc: string) {
  const toast = elements.globalSuccessToast;
  if (!toast) return;

  if (elements.toastTitle) elements.toastTitle.innerText = title;
  if (elements.toastDesc) elements.toastDesc.innerText = desc;

  toast.classList.remove('hidden');
  toast.classList.add('flex');

  // Auto-hide after 5 seconds
  setTimeout(() => {
    toast.classList.add('hidden');
  }, 5000);
}

// ==================== EVENT LISTENERS SETUP ====================

function setupEventListeners() {
  // Desktop Tab Navigation clicks
  const navTabs = document.querySelectorAll('.nav-tab');
  navTabs.forEach(tab => {
    tab.addEventListener('click', () => {
      const target = tab.getAttribute('data-tab');
      if (target) switchTab(target);
    });
  });

  // Mobile drawer tabs clicks
  const mobileTabBtns = document.querySelectorAll('.mobile-tab-btn');
  mobileTabBtns.forEach(btn => {
    btn.addEventListener('click', () => {
      const target = btn.getAttribute('data-tab');
      if (target) switchTab(target);
    });
  });

  // Footer tab triggers
  const footerTabBtns = document.querySelectorAll('.footer-tab-btn');
  footerTabBtns.forEach(btn => {
    btn.addEventListener('click', () => {
      const target = btn.getAttribute('data-tab');
      if (target) switchTab(target);
    });
  });

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

  // Mobile search trigger
  elements.mobileSearchTrigger?.addEventListener('click', () => {
    switchTab('products');
    setTimeout(() => {
      elements.catalogSearchInput?.focus();
    }, 200);
  });

  // Mobile contact trigger
  elements.mobileContactTrigger?.addEventListener('click', () => {
    switchTab('contact');
  });

  // Logo clicks
  elements.headerLogoBtn?.addEventListener('click', () => switchTab('home'));
  elements.footerLogoBtn?.addEventListener('click', () => switchTab('home'));

  // Quick shortcuts trigger
  elements.searchShortcutBtn?.addEventListener('click', () => {
    switchTab('products');
    setTimeout(() => {
      elements.catalogSearchInput?.focus();
    }, 200);
  });

  elements.headerCollaborationBtn?.addEventListener('click', () => {
    switchTab('contact');
  });

  // Play banner play trigger
  elements.heroPlayTrigger?.addEventListener('click', () => {
    openStreamingModal('m1'); // Play featured movie
  });

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

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

  const viewMoreBtns = document.querySelectorAll('.view-more-popular-btn');
  viewMoreBtns.forEach(btn => {
    btn.addEventListener('click', () => {
      switchTab('products');
    });
  });

  // Catalog tab search fields interaction
  elements.catalogSearchInput?.addEventListener('input', (e) => {
    searchQuery = (e.target as HTMLInputElement).value;
    
    if (elements.catalogSearchClear) {
      if (searchQuery.trim() !== '') {
        elements.catalogSearchClear.classList.remove('hidden');
      } else {
        elements.catalogSearchClear.classList.add('hidden');
      }
    }

    currentPage = 1;
    renderCatalogGrid();
  });

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

  // Sorting drop down selection handler
  elements.catalogSortSelect?.addEventListener('change', (e) => {
    filterSort = (e.target as HTMLSelectElement).value;
    currentPage = 1;
    renderCatalogGrid();
  });

  // Catalog category filtering pill clicks
  const pills = document.querySelectorAll('.filter-pill');
  pills.forEach(pill => {
    pill.addEventListener('click', (e) => {
      const target = e.currentTarget as HTMLElement;
      const type = target.getAttribute('data-filter') || '';
      const val = target.getAttribute('data-value') || '';

      if (type === 'type') {
        filterType = val;
      } else if (type === 'region') {
        filterRegion = val;
      } else if (type === 'year') {
        filterYear = val;
      } else if (type === 'rating') {
        filterRating = val;
      }

      // Update styling
      updatePillsRowSelection(type, val);
      
      currentPage = 1;
      renderCatalogGrid();
    });
  });

  // Catalog reset
  elements.catalogEmptyReset?.addEventListener('click', () => {
    filterType = '全部';
    filterRegion = '全部';
    filterYear = '全部';
    filterRating = '全部';
    searchQuery = '';

    updatePillsRowSelection('type', '全部');
    updatePillsRowSelection('region', '全部');
    updatePillsRowSelection('year', '全部');
    updatePillsRowSelection('rating', '全部');

    if (elements.catalogSearchInput) {
      elements.catalogSearchInput.value = '';
    }
    if (elements.catalogSearchClear) {
      elements.catalogSearchClear.classList.add('hidden');
    }

    currentPage = 1;
    renderCatalogGrid();
  });

  // Pagination navigation clicks
  elements.btnPagePrev?.addEventListener('click', () => {
    if (currentPage > 1) {
      currentPage--;
      renderCatalogGrid();
      if (elements.tabProducts) {
        window.scrollTo({ top: elements.tabProducts.offsetTop - 40, behavior: 'smooth' });
      }
    }
  });

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

  // About team catalog load or view redirect
  elements.modalCloseTrigger?.addEventListener('click', closeStreamingModal);
  
  // Close modal click outside container
  elements.videoStreamDialog?.addEventListener('click', (e) => {
    if (e.target === elements.videoStreamDialog) {
      closeStreamingModal();
    }
  });

  // Contact form simulated submission with animation (表单提交)
  elements.contactForm?.addEventListener('submit', (e) => {
    e.preventDefault();

    if (elements.formSubmitSpinner && elements.formSubmitText && elements.formSubmitBtn) {
      elements.formSubmitSpinner.classList.remove('hidden');
      elements.formSubmitText.innerText = "正在通过 RSA 加密加密信通道上报中...";
      elements.formSubmitBtn.disabled = true;

      // Simulate network wait of 1.5 seconds
      setTimeout(() => {
        elements.formSubmitSpinner.classList.add('hidden');
        elements.formSubmitText.innerText = "📤 极速提交工单到 4399流媒体中枢";
        elements.formSubmitBtn.disabled = false;

        const nameInput = document.getElementById('form-name') as HTMLInputElement;
        const msgTypeSelect = document.getElementById('form-msg-type') as HTMLSelectElement;

        const name = nameInput ? nameInput.value : "访客";
        const type = msgTypeSelect ? msgTypeSelect.value : "常规事务提报";

        // Show global success toast
        showToast(
          "4399流媒体工单派发成功", 
          `感谢您 [${name}] 的反馈！关于: [${type}] 的业务提报已成功收录，请留意手机或Email，24小时内必定回复！`
        );

        elements.contactForm.reset();
      }, 1500);
    }
  });

  // Floating AI Chat triggers
  elements.floatingChatTrigger?.addEventListener('click', () => {
    if (elements.onlineChatWindow) {
      elements.onlineChatWindow.classList.toggle('hidden');
    }
  });

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

  elements.triggerOnlineChat?.addEventListener('click', () => {
    elements.onlineChatWindow?.classList.remove('hidden');
  });

  elements.footerTriggerChat?.addEventListener('click', () => {
    elements.onlineChatWindow?.classList.remove('hidden');
  });

  // Chat Submission Form
  elements.chatSubmitForm?.addEventListener('submit', (e) => {
    e.preventDefault();
    if (!elements.chatUserInput) return;

    const query = elements.chatUserInput.value.trim();
    if (query !== '') {
      handleUserChatQuery(query);
      elements.chatUserInput.value = '';
    }
  });

  // Toast close button
  elements.toastCloseBtn?.addEventListener('click', () => {
    elements.globalSuccessToast?.classList.add('hidden');
  });

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

// ==================== APP INITIALIZATION ENTRY POINT ====================

function init() {
  // 1. Initial renders of homepage columns
  renderHomeMovies();
  renderHomeNews();

  // 2. Initial renders of products library
  renderCatalogGrid();

  // 3. Render About Us static panels
  renderAboutTab();

  // 4. Register vector canvas map triggers
  setupMapControls();

  // 5. Build AI assistant messages & suggestions
  initOnlineChatHelper();

  // 6. Connect global actions and tab bindings
  setupEventListeners();

  // Show home view by default
  switchTab('home');

  console.log("4399影视-全新数字企业展示官网并网启动成功！2026-07-09");
}

// Trigger initializations
document.addEventListener('DOMContentLoaded', init);
// Run fallback if DOM is already fully ready
if (document.readyState === 'complete' || document.readyState === 'interactive') {
  init();
}
