/**
 * ============================================================================
 * 公司详情页面 (Company Detail Page)
 * ============================================================================
 *
 * 📍 路由: /company?scode=000001
 *
 * 📋 功能概述:
 *   - 展示个股详情信息，包括股票行情、公司资料、财务数据等
 *   - 支持通过 URL 参数 `scode` 指定股票代码
 *   - 提供自选股添加/移除功能
 *   - 多 Tab 切换展示不同维度的公司信息
 *
 * 🎨 设计风格:
 *   - FUI (Futuristic User Interface) 科幻风格
 *   - Ash Thorp 风格 - 电影级 UI 设计美学
 *   - James Turrell 光影效果 - 环境光渲染
 *   - Glassmorphism 毛玻璃卡片效果
 *   - Linear.app 风格微交互动画
 *
 * 🏗️ 组件架构:
 *   CompanyIndex (本文件)
 *   ├── AmbientGlow - 全局环境光效果背景
 *   ├── CompanyHeader - 顶部区域 (页面标题 + 搜索栏)
 *   ├── StockQuoteCard - 股票实时行情卡片 (价格、涨跌幅等)
 *   └── SubTabContainer - Tab 切换容器
 *       ├── 概览 Tab
 *       ├── 财务 Tab
 *       ├── 公告 Tab
 *       └── ... 其他 Tab (由 TAB_CONFIG 配置)
 *
 * 📊 数据流:
 *   1. URL 参数 scode → stockCode 状态
 *   2. stockCode → useCompanyData Hook → 获取股票信息、自选股状态
 *   3. stockCode → useCompanyEvents Hook → 用户行为追踪
 *   4. 数据传递给子组件进行渲染
 *
 * 🔧 性能优化:
 *   - 使用 memo() 包装组件，避免父组件更新时不必要的重渲染
 *   - 使用 useCallback 缓存事件处理函数
 *   - 使用 useMemo 缓存传递给子组件的 props 对象
 *   - Tab 内容使用 isLazy 延迟加载，减少首屏渲染负担
 *   - 使用 useRef 追踪前一个股票代码，避免重复触发事件
 */

import React, { memo, useCallback, useRef, useEffect, useMemo } from 'react';

// ============================================
// 样式导入
// ============================================
// FUI 动画样式 - 包含扫描线、发光效果等科幻动画
import './theme/fui-animations.css';

// ============================================
// 第三方库导入
// ============================================
// React Router - 用于读取和修改 URL 查询参数
import { useSearchParams } from 'react-router-dom';
// Chakra UI - 基础布局组件
import { Box } from '@chakra-ui/react';

// ============================================
// 内部组件和工具导入
// ============================================
// 通用 Tab 切换容器组件 - 支持懒加载和主题配置
import SubTabContainer from '@components/SubTabContainer';
// FUI 风格组件 - 科幻容器和环境光效果
import { FuiContainer, AmbientGlow } from '@components/FUI';
// 动态网页标题 Hook - 根据股票名称更新浏览器标签页标题
import { useStockDocumentTitle } from '@hooks/useDocumentTitle';

// ============================================
// 页面级 Hooks
// ============================================
// 用户行为事件追踪 Hook - 发送分析数据到 PostHog
import { useCompanyEvents } from './hooks/useCompanyEvents';
// 公司数据获取 Hook - 封装股票信息和自选股相关 API
import { useCompanyData } from './hooks/useCompanyData';

// ============================================
// 页面子组件
// ============================================
// 顶部 Header - 包含页面标题和搜索框
import CompanyHeader from './components/CompanyHeader';
// 股票行情卡片 - 显示实时价格、涨跌幅、成交量等
import StockQuoteCard from './components/StockQuoteCard';

// ============================================
// 配置常量
// ============================================
// THEME - 页面主题配置 (背景色、文字色等)
// TAB_CONFIG - Tab 页签配置数组 (名称、图标、对应组件)
import { THEME, TAB_CONFIG } from './config';

// ============================================
// 主页面组件
// ============================================

/**
 * CompanyIndex - 公司详情页主组件
 *
 * 这是一个容器组件 (Container Component)，主要负责：
 * 1. 状态管理 - 管理 URL 参数、数据加载状态
 * 2. 数据获取 - 通过自定义 Hook 获取股票数据
 * 3. 事件处理 - 处理用户交互（搜索、Tab 切换、自选操作）
 * 4. 布局编排 - 组合子组件构成完整页面
 *
 * 具体的 UI 渲染和业务逻辑委托给各个子组件处理
 */
const CompanyIndex: React.FC = () => {
  // ==========================================
  // URL 参数管理
  // ==========================================
  /**
   * useSearchParams - React Router v6 的 Hook
   * 用于读取和修改 URL 中的查询参数 (query string)
   *
   * 示例 URL: /company?scode=600519
   * searchParams.get('scode') 返回 '600519'
   */
  const [searchParams, setSearchParams] = useSearchParams();

  /**
   * 当前股票代码
   * - 从 URL 参数 `scode` 读取
   * - 默认值 '000001' (平安银行) 作为兜底
   */
  const stockCode = searchParams.get('scode') || '000001';

  /**
   * 前一个股票代码的引用
   * - 用于检测股票代码是否发生变化
   * - 避免在股票未变化时重复触发追踪事件
   * - 使用 useRef 而非 useState，因为不需要触发重渲染
   */
  const prevStockCodeRef = useRef(stockCode);

  // ==========================================
  // 数据加载 Hook
  // ==========================================
  /**
   * useCompanyData - 自定义 Hook，封装公司数据获取逻辑
   *
   * 返回值说明：
   * @property {Object} stockInfo - 股票基础信息对象
   *   - stock_name: 股票名称 (如 "贵州茅台")
   *   - stock_code: 股票代码 (如 "600519")
   *   - industry: 所属行业
   *   - ... 其他字段
   *
   * @property {boolean} stockInfoLoading - 股票信息加载中状态
   *   - true: 正在请求数据，显示骨架屏/loading
   *   - false: 数据加载完成
   *
   * @property {boolean} isInWatchlist - 是否已添加到自选股
   *   - true: 已在自选列表中，显示"已自选"状态
   *   - false: 未添加，显示"添加自选"按钮
   *
   * @property {boolean} watchlistLoading - 自选股操作加载中
   *   - 用于禁用按钮，防止重复点击
   *
   * @property {Function} toggleWatchlist - 切换自选股状态
   *   - 异步函数，调用后台 API 添加/移除自选
   */
  const {
    stockInfo,
    isInWatchlist,
    watchlistLoading,
    toggleWatchlist,
  } = useCompanyData({ stockCode });

  // ==========================================
  // 事件追踪 Hook
  // ==========================================
  /**
   * useCompanyEvents - 用户行为追踪 Hook
   *
   * 用于记录用户在页面上的关键操作，发送到分析平台 (PostHog)
   * 这些数据用于产品分析、用户行为研究、功能优化等
   *
   * 追踪的事件类型：
   * - trackStockSearched: 用户搜索/切换股票
   * - trackTabChanged: 用户切换 Tab 页签
   * - trackWatchlistAdded: 用户添加自选股
   * - trackWatchlistRemoved: 用户移除自选股
   */
  const companyEvents = useCompanyEvents({ stockCode }) as {
    trackStockSearched: (newCode: string, oldCode: string | null) => void;
    trackTabChanged: (index: number, name: string, prevIndex: number) => void;
    trackWatchlistAdded: (code: string) => void;
    trackWatchlistRemoved: (code: string) => void;
  };

  // 解构追踪函数，方便使用
  const { trackStockSearched, trackTabChanged, trackWatchlistAdded, trackWatchlistRemoved } = companyEvents;

  // ==========================================
  // 副作用 Effects
  // ==========================================

  /**
   * 设置网页标题
   *
   * 根据当前股票代码和名称动态更新浏览器标签页标题
   * 示例: "600519 贵州茅台 - 公司详情"
   *
   * 这提升了用户体验，特别是当用户打开多个标签页时
   * 可以通过标题快速识别每个页面展示的股票
   */
  useStockDocumentTitle(stockCode, stockInfo?.stock_name);

  /**
   * 股票代码变化追踪
   *
   * 当股票代码发生变化时（通过 URL 参数改变），
   * 触发追踪事件记录用户的浏览行为
   *
   * 注意：
   * - 只在代码真正变化时触发，避免初始化时的重复追踪
   * - 使用 useRef 存储前值，而非 usePrevious Hook，减少依赖
   */
  useEffect(() => {
    // 只有当股票代码真正发生变化时才触发追踪
    if (stockCode !== prevStockCodeRef.current) {
      // 记录用户从哪只股票切换到哪只股票
      trackStockSearched(stockCode, prevStockCodeRef.current);
      // 更新引用值
      prevStockCodeRef.current = stockCode;
    }
  }, [stockCode, trackStockSearched]);

  // ==========================================
  // 事件处理函数
  // ==========================================

  /**
   * 处理股票切换
   *
   * 当用户通过搜索框选择新股票时调用
   * 1. 验证新代码有效且与当前不同
   * 2. 触发追踪事件
   * 3. 更新 URL 参数（触发组件重新渲染，加载新数据）
   *
   * @param {string} newCode - 用户选择的新股票代码
   *
   * 使用 useCallback 缓存函数引用，避免子组件不必要的重渲染
   */
  const handleStockChange = useCallback((newCode: string) => {
    // 验证: 新代码存在 且 与当前代码不同
    if (newCode && newCode !== stockCode) {
      // 追踪: 记录股票切换行为
      trackStockSearched(newCode, stockCode);
      // 更新 URL: 这会触发组件重新渲染，进而重新获取数据
      setSearchParams({ scode: newCode });
    }
  }, [stockCode, setSearchParams, trackStockSearched]);

  /**
   * 处理自选股切换（带追踪）
   *
   * 当用户点击"添加/移除自选"按钮时调用
   * 1. 记录操作前的状态（用于判断是添加还是移除）
   * 2. 调用 API 执行实际操作
   * 3. 根据操作类型触发对应的追踪事件
   *
   * 注意: 使用 async/await 确保 API 调用完成后再触发追踪
   */
  const handleWatchlistToggle = useCallback(async () => {
    // 记录操作前的状态
    const wasInWatchlist = isInWatchlist;

    // 执行 API 调用（添加或移除自选股）
    await toggleWatchlist();

    // 追踪事件（根据操作前的状态判断是添加还是移除）
    if (wasInWatchlist) {
      // 之前在自选中 → 现在移除了
      trackWatchlistRemoved(stockCode);
    } else {
      // 之前不在自选中 → 现在添加了
      trackWatchlistAdded(stockCode);
    }
  }, [stockCode, isInWatchlist, toggleWatchlist, trackWatchlistAdded, trackWatchlistRemoved]);

  /**
   * 处理 Tab 切换
   *
   * 当用户点击不同的 Tab 页签时调用
   * 记录用户查看了哪个 Tab，用于分析用户最关注的信息类型
   *
   * @param {number} index - Tab 的索引位置 (0, 1, 2, ...)
   * @param {string} tabKey - Tab 的唯一标识符
   */
  const handleTabChange = useCallback((index: number, tabKey: string) => {
    // 从配置中获取 Tab 的显示名称，如果没找到则使用 tabKey
    const tabName = TAB_CONFIG[index]?.name || tabKey;
    // 触发追踪事件
    trackTabChanged(index, tabName, index);
  }, [trackTabChanged]);

  // ==========================================
  // 性能优化: 缓存 Props
  // ==========================================

  /**
   * 缓存传递给 SubTabContainer 的 componentProps
   *
   * 为什么需要 useMemo?
   * - 每次组件渲染时，`{ stockCode }` 会创建一个新对象
   * - 即使 stockCode 值没变，新对象的引用也不同
   * - 这会导致 SubTabContainer 认为 props 变了，触发不必要的重渲染
   *
   * 使用 useMemo 后：
   * - 只有当 stockCode 真正变化时，才创建新对象
   * - 保持对象引用稳定，避免子组件重渲染
   */
  const memoizedComponentProps = useMemo(() => ({ stockCode }), [stockCode]);


  // ==========================================
  // 渲染 UI
  // ==========================================
  return (
    /**
     * 最外层容器
     * - position="relative": 为内部绝对定位元素提供定位上下文
     * - bg={THEME.bg}: 使用主题配置的背景色
     * - minH: 最小高度 = 视口高度 - 顶部导航栏高度 (60px)
     * - overflow="hidden": 隐藏溢出内容，配合光效动画使用
     */
    <Box
      position="relative"
      bg={THEME.bg}
      minH="calc(100vh - 60px)"
      overflow="hidden"
    >
      {/* ========================================
          全局环境光效果
          ========================================
          AmbientGlow 组件创建 James Turrell 风格的光影效果
          - 在页面背景上渲染柔和的渐变光晕
          - 增强科幻 UI 的氛围感
          - variant="default" 使用默认的光效配置
      */}
      <AmbientGlow variant="default" />

      {/* ========================================
          顶部搜索栏区域
          ========================================
          zIndex={1} 确保 Header 在环境光效果之上显示
      */}
      <Box position="relative" zIndex={1}>
        {/*
          CompanyHeader 组件
          负责展示：
          - 左侧：页面标题和副标题
          - 右侧：股票搜索框 (支持代码/名称搜索)

          Props 说明：
          - stockCode: 当前股票代码，用于搜索框默认值
          - onStockChange: 股票切换回调
        */}
        <CompanyHeader
          stockCode={stockCode}
          onStockChange={handleStockChange}
        />
      </Box>

      {/* ========================================
          主内容区
          ========================================
          包含股票行情卡片和 Tab 内容区
      */}
      <Box position="relative" zIndex={1}>

      {/*
        内容容器
        - maxW="container.xl": 最大宽度限制，保持内容可读性
        - mx="auto": 水平居中
        - px={4}: 左右内边距 16px
        - py={6}: 上下内边距 24px
      */}
      <Box maxW="container.xl" mx="auto" px={4} py={6}>
          {/* ========================================
              股票行情卡片
              ========================================
              放在 Tab 切换器上方，始终可见
              显示实时股价、涨跌幅、成交量、换手率等核心行情数据

              这个卡片独立于 Tab 系统，因为行情数据是用户
              无论查看哪个 Tab 都需要看到的核心信息

              mb={6}: 底部外边距 24px，与下方 Tab 区域保持间距
          */}
          <Box mb={6}>
            <StockQuoteCard
              stockCode={stockCode}
              isInWatchlist={isInWatchlist}
              isWatchlistLoading={watchlistLoading}
              onWatchlistToggle={handleWatchlistToggle}
            />
          </Box>

          {/* ========================================
              Tab 内容区
              ========================================
              FuiContainer 提供 FUI 风格的容器样式：
              - 毛玻璃背景效果
              - 边框发光效果
              - 科幻风格圆角

              SubTabContainer 是通用的 Tab 切换组件：
              - tabs: Tab 配置数组，定义每个 Tab 的名称、图标、组件
              - componentProps: 传递给每个 Tab 组件的共享 props
              - onTabChange: Tab 切换时的回调函数
              - themePreset: 主题预设 ("blackGold" = 黑金配色)
              - contentPadding: Tab 内容区内边距 (0 = 无内边距)
              - isLazy: 懒加载，只有激活的 Tab 才渲染内容
          */}
          <FuiContainer variant="default">
            <SubTabContainer
              tabs={TAB_CONFIG}
              componentProps={memoizedComponentProps}
              onTabChange={handleTabChange}
              themePreset="blackGold"
              contentPadding={0}
              isLazy={true}
            />
          </FuiContainer>
        </Box>
      </Box>
    </Box>
  );
};

/**
 * 导出组件
 *
 * 使用 React.memo 包装组件
 * memo 是一个高阶组件，用于性能优化：
 * - 当组件的 props 没有变化时，跳过重新渲染
 * - 对于这个页面级组件，可以避免父组件（如 MainLayout）
 *   更新时导致的不必要重渲染
 *
 * 注意: memo 只做浅比较，对于复杂 props 需要配合 useMemo
 */
export default memo(CompanyIndex);
