/**
 * 灵活屏组件
 * 用户可自定义添加关注的指数/个股，实时显示行情
 *
 * 功能：
 * 1. 添加/删除自选证券
 * 2. 显示实时行情（通过 WebSocket）
 * 3. 显示分时走势（结合 ClickHouse 历史数据）
 * 4. 显示五档盘口（上交所5档，深交所10档）
 * 5. 本地存储自选列表
 */
import React, { useState, useEffect, useCallback, useMemo } from 'react';
import {
  Box,
  Card,
  CardBody,
  VStack,
  HStack,
  Heading,
  Text,
  Input,
  InputGroup,
  InputLeftElement,
  InputRightElement,
  IconButton,
  SimpleGrid,
  Flex,
  Spacer,
  Icon,
  useColorModeValue,
  useToast,
  Badge,
  Tooltip,
  Collapse,
  List,
  ListItem,
  Spinner,
  Center,
  Menu,
  MenuButton,
  MenuList,
  MenuItem,
  Tag,
  TagLabel,
} from '@chakra-ui/react';
import {
  SearchIcon,
  CloseIcon,
  AddIcon,
  ChevronDownIcon,
  ChevronUpIcon,
  SettingsIcon,
} from '@chakra-ui/icons';
import {
  FaDesktop,
  FaTrash,
  FaSync,
  FaWifi,
  FaExclamationCircle,
} from 'react-icons/fa';

import { useRealtimeQuote } from './hooks';
import QuoteTile from './components/QuoteTile';
import { logger } from '@utils/logger';
import type { WatchlistItem, ConnectionStatus } from './types';

// 本地存储 key
const STORAGE_KEY = 'flexscreen_watchlist';

// 默认自选列表
const DEFAULT_WATCHLIST: WatchlistItem[] = [
  { code: '000001', name: '上证指数', isIndex: true },
  { code: '399001', name: '深证成指', isIndex: true },
  { code: '399006', name: '创业板指', isIndex: true },
];

// 热门推荐
const HOT_RECOMMENDATIONS: WatchlistItem[] = [
  { code: '000001', name: '上证指数', isIndex: true },
  { code: '399001', name: '深证成指', isIndex: true },
  { code: '399006', name: '创业板指', isIndex: true },
  { code: '399300', name: '沪深300', isIndex: true },
  { code: '600519', name: '贵州茅台', isIndex: false },
  { code: '000858', name: '五粮液', isIndex: false },
  { code: '300750', name: '宁德时代', isIndex: false },
  { code: '002594', name: '比亚迪', isIndex: false },
];

/** 搜索结果项 */
interface SearchResultItem {
  stock_code: string;
  stock_name: string;
  isIndex?: boolean;
  code?: string;
  name?: string;
}

/** 搜索 API 响应 */
interface SearchApiResponse {
  success: boolean;
  data?: SearchResultItem[];
}

/** 连接状态信息 */
interface ConnectionStatusInfo {
  color: string;
  text: string;
}

/**
 * FlexScreen 组件
 */
const FlexScreen: React.FC = () => {
  const toast = useToast();

  // 自选列表
  const [watchlist, setWatchlist] = useState<WatchlistItem[]>([]);
  // 搜索状态
  const [searchQuery, setSearchQuery] = useState('');
  const [searchResults, setSearchResults] = useState<SearchResultItem[]>([]);
  const [isSearching, setIsSearching] = useState(false);
  const [showResults, setShowResults] = useState(false);
  // 面板状态
  const [isCollapsed, setIsCollapsed] = useState(false);

  // 颜色主题
  const cardBg = useColorModeValue('white', '#1a1a1a');
  const borderColor = useColorModeValue('gray.200', '#333');
  const textColor = useColorModeValue('gray.800', 'white');
  const subTextColor = useColorModeValue('gray.600', 'gray.400');
  const searchBg = useColorModeValue('gray.50', '#2a2a2a');
  const hoverBg = useColorModeValue('gray.100', '#333');

  // 获取订阅的证券代码列表
  const subscribedCodes = useMemo(() => {
    return watchlist.map(item => item.code);
  }, [watchlist]);

  // WebSocket 实时行情
  const { quotes, connected } = useRealtimeQuote(subscribedCodes);

  // 从本地存储加载自选列表
  useEffect(() => {
    try {
      const saved = localStorage.getItem(STORAGE_KEY);
      if (saved) {
        const parsed = JSON.parse(saved) as WatchlistItem[];
        if (Array.isArray(parsed) && parsed.length > 0) {
          setWatchlist(parsed);
          return;
        }
      }
    } catch (e) {
      logger.warn('FlexScreen', '加载自选列表失败', e);
    }
    // 使用默认列表
    setWatchlist(DEFAULT_WATCHLIST);
  }, []);

  // 保存自选列表到本地存储
  useEffect(() => {
    if (watchlist.length > 0) {
      try {
        localStorage.setItem(STORAGE_KEY, JSON.stringify(watchlist));
      } catch (e) {
        logger.warn('FlexScreen', '保存自选列表失败', e);
      }
    }
  }, [watchlist]);

  // 搜索证券
  const searchSecurities = useCallback(async (query: string): Promise<void> => {
    if (!query.trim()) {
      setSearchResults([]);
      setShowResults(false);
      return;
    }

    setIsSearching(true);
    try {
      const response = await fetch(`/api/stocks/search?q=${encodeURIComponent(query)}&limit=10`);
      const data: SearchApiResponse = await response.json();

      if (data.success) {
        setSearchResults(data.data || []);
        setShowResults(true);
      } else {
        setSearchResults([]);
      }
    } catch (e) {
      logger.error('FlexScreen', '搜索失败', e);
      setSearchResults([]);
    } finally {
      setIsSearching(false);
    }
  }, []);

  // 防抖搜索
  useEffect(() => {
    const timer = setTimeout(() => {
      searchSecurities(searchQuery);
    }, 300);
    return () => clearTimeout(timer);
  }, [searchQuery, searchSecurities]);

  // 添加证券
  const addSecurity = useCallback(
    (security: SearchResultItem | WatchlistItem): void => {
      const code = 'stock_code' in security ? security.stock_code : security.code;
      const name = 'stock_name' in security ? security.stock_name : security.name;
      const isIndex =
        security.isIndex || code.startsWith('000') || code.startsWith('399');

      // 检查是否已存在
      if (watchlist.some(item => item.code === code)) {
        toast({
          title: '已在自选列表中',
          status: 'info',
          duration: 2000,
          isClosable: true,
        });
        return;
      }

      // 添加到列表
      setWatchlist(prev => [...prev, { code, name, isIndex }]);

      toast({
        title: `已添加 ${name}`,
        status: 'success',
        duration: 2000,
        isClosable: true,
      });

      // 清空搜索
      setSearchQuery('');
      setShowResults(false);
    },
    [watchlist, toast]
  );

  // 移除证券
  const removeSecurity = useCallback((code: string): void => {
    setWatchlist(prev => prev.filter(item => item.code !== code));
  }, []);

  // 清空自选列表
  const clearWatchlist = useCallback((): void => {
    setWatchlist([]);
    localStorage.removeItem(STORAGE_KEY);
    toast({
      title: '已清空自选列表',
      status: 'info',
      duration: 2000,
      isClosable: true,
    });
  }, [toast]);

  // 重置为默认列表
  const resetWatchlist = useCallback((): void => {
    setWatchlist(DEFAULT_WATCHLIST);
    toast({
      title: '已重置为默认列表',
      status: 'success',
      duration: 2000,
      isClosable: true,
    });
  }, [toast]);

  // 连接状态指示
  const isAnyConnected = connected.SSE || connected.SZSE;
  const connectionStatus = useMemo((): ConnectionStatusInfo => {
    if (connected.SSE && connected.SZSE) {
      return { color: 'green', text: '上交所/深交所 已连接' };
    }
    if (connected.SSE) {
      return { color: 'yellow', text: '上交所 已连接' };
    }
    if (connected.SZSE) {
      return { color: 'yellow', text: '深交所 已连接' };
    }
    return { color: 'red', text: '未连接' };
  }, [connected]);

  return (
    <Card bg={cardBg} borderWidth="1px" borderColor={borderColor}>
      <CardBody>
        {/* 头部 */}
        <Flex align="center" mb={4}>
          <HStack spacing={3}>
            <Icon as={FaDesktop} boxSize={6} color="purple.500" />
            <Heading size="md" color={textColor}>
              灵活屏
            </Heading>
            <Tooltip label={connectionStatus.text}>
              <Badge
                colorScheme={connectionStatus.color}
                variant="subtle"
                display="flex"
                alignItems="center"
                gap={1}
              >
                <Icon as={FaWifi} boxSize={3} />
                {isAnyConnected ? '实时' : '离线'}
              </Badge>
            </Tooltip>
          </HStack>
          <Spacer />
          <HStack spacing={2}>
            {/* 操作菜单 */}
            <Menu>
              <MenuButton
                as={IconButton}
                icon={<SettingsIcon />}
                size="sm"
                variant="ghost"
                aria-label="设置"
              />
              <MenuList>
                <MenuItem icon={<FaSync />} onClick={resetWatchlist}>
                  重置为默认
                </MenuItem>
                <MenuItem icon={<FaTrash />} onClick={clearWatchlist} color="red.500">
                  清空列表
                </MenuItem>
              </MenuList>
            </Menu>
            {/* 折叠按钮 */}
            <IconButton
              icon={isCollapsed ? <ChevronDownIcon /> : <ChevronUpIcon />}
              size="sm"
              variant="ghost"
              onClick={() => setIsCollapsed(!isCollapsed)}
              aria-label={isCollapsed ? '展开' : '收起'}
            />
          </HStack>
        </Flex>

        {/* 可折叠内容 */}
        <Collapse in={!isCollapsed} animateOpacity>
          {/* 搜索框 */}
          <Box position="relative" mb={4}>
            <InputGroup size="md">
              <InputLeftElement pointerEvents="none">
                <SearchIcon color="gray.400" />
              </InputLeftElement>
              <Input
                placeholder="搜索股票/指数代码或名称..."
                value={searchQuery}
                onChange={e => setSearchQuery(e.target.value)}
                bg={searchBg}
                borderRadius="lg"
                _focus={{
                  borderColor: 'purple.400',
                  boxShadow: '0 0 0 1px var(--chakra-colors-purple-400)',
                }}
              />
              {searchQuery && (
                <InputRightElement>
                  <IconButton
                    size="sm"
                    icon={<CloseIcon />}
                    variant="ghost"
                    onClick={() => {
                      setSearchQuery('');
                      setShowResults(false);
                    }}
                    aria-label="清空"
                  />
                </InputRightElement>
              )}
            </InputGroup>

            {/* 搜索结果下拉 */}
            <Collapse in={showResults} animateOpacity>
              <Box
                position="absolute"
                top="100%"
                left={0}
                right={0}
                mt={1}
                bg={cardBg}
                borderWidth="1px"
                borderColor={borderColor}
                borderRadius="lg"
                boxShadow="lg"
                maxH="300px"
                overflowY="auto"
                zIndex={10}
              >
                {isSearching ? (
                  <Center p={4}>
                    <Spinner size="sm" color="purple.500" />
                  </Center>
                ) : searchResults.length > 0 ? (
                  <List spacing={0}>
                    {searchResults.map((stock, index) => (
                      <ListItem
                        key={stock.stock_code}
                        px={4}
                        py={2}
                        cursor="pointer"
                        _hover={{ bg: hoverBg }}
                        onClick={() => addSecurity(stock)}
                        borderBottomWidth={index < searchResults.length - 1 ? '1px' : '0'}
                        borderColor={borderColor}
                      >
                        <HStack justify="space-between">
                          <VStack align="start" spacing={0}>
                            <Text fontWeight="medium" color={textColor}>
                              {stock.stock_name}
                            </Text>
                            <Text fontSize="xs" color={subTextColor}>
                              {stock.stock_code}
                            </Text>
                          </VStack>
                          <IconButton
                            icon={<AddIcon />}
                            size="xs"
                            colorScheme="purple"
                            variant="ghost"
                            aria-label="添加"
                          />
                        </HStack>
                      </ListItem>
                    ))}
                  </List>
                ) : (
                  <Center p={4}>
                    <Text color={subTextColor} fontSize="sm">
                      未找到相关证券
                    </Text>
                  </Center>
                )}
              </Box>
            </Collapse>
          </Box>

          {/* 快捷添加 */}
          {watchlist.length === 0 && (
            <Box mb={4}>
              <Text fontSize="sm" color={subTextColor} mb={2}>
                热门推荐（点击添加）
              </Text>
              <Flex flexWrap="wrap" gap={2}>
                {HOT_RECOMMENDATIONS.map(item => (
                  <Tag
                    key={item.code}
                    size="md"
                    variant="subtle"
                    colorScheme="purple"
                    cursor="pointer"
                    _hover={{ bg: 'purple.100' }}
                    onClick={() => addSecurity(item)}
                  >
                    <TagLabel>{item.name}</TagLabel>
                  </Tag>
                ))}
              </Flex>
            </Box>
          )}

          {/* 自选列表 */}
          {watchlist.length > 0 ? (
            <SimpleGrid columns={{ base: 1, md: 2, lg: 3 }} spacing={4}>
              {watchlist.map(item => (
                <QuoteTile
                  key={item.code}
                  code={item.code}
                  name={item.name}
                  quote={quotes[item.code] || {}}
                  isIndex={item.isIndex}
                  onRemove={removeSecurity}
                />
              ))}
            </SimpleGrid>
          ) : (
            <Center py={8}>
              <VStack spacing={3}>
                <Icon as={FaExclamationCircle} boxSize={10} color="gray.300" />
                <Text color={subTextColor}>自选列表为空，请搜索添加证券</Text>
              </VStack>
            </Center>
          )}
        </Collapse>
      </CardBody>
    </Card>
  );
};

export default FlexScreen;
