import { useState, useMemo, useEffect, useCallback, CSSProperties } from 'react';
import {
  Layout,
  Typography,
  AutoComplete,
  Button,
  Badge,
  Radio,
  Table,
  List,
  Card,
  Pagination,
  Drawer,
  Select,
  InputNumber,
  Space,
  Skeleton,
  Avatar,
  Tag,
  message
} from 'antd';
import { FilterOutlined, TableOutlined, AppstoreOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import { useApi } from '@/hooks/useApi';
import { StockManagementService } from '@/services/stockManagement';
import { useAppContext } from '@/store/AppStore';
import { parseError } from '@/utils/errorHandler';
import { ROUTES } from '@/constants/routes';

interface Stock {
  id: string;
  ticker_symbol: string;
  company_name: string;
  current_price: number | null;
  opening_price: number | null;
  closing_price: number | null;
  high_price: number | null;
  low_price: number | null;
  volume: number | null;
  market_cap: number | null;
  sector_id: string;
  industry: string | null;
  exchange_id: string;
  currency: string;
  last_updated: string | null;
  description: string | null;
  logo_url: string | null;
  website_url: string | null;
  country: string | null;
  ipo_date: string | null;
  status: 'ACTIVE' | 'INACTIVE';
  created_at: string;
  updated_at: string;
}

interface Sector {
  id: string;
  name: string;
  description: string | null;
  icon_url: string | null;
  display_order: number;
  created_at: string;
  updated_at: string;
}

interface Exchange {
  id: string;
  name: string;
  code: string;
  country: string;
  timezone: string;
  trading_hours: string | null;
  currency: string;
  website_url: string | null;
  description: string | null;
  created_at: string;
  updated_at: string;
}

interface AutocompleteSuggestion {
  value: string;
  label: string;
  stock: Stock;
}

const StockListPage = () => {
  const [messageApi, contextHolder] = message.useMessage();
  const navigate = useNavigate();
  
  const {
    searchQuery,
    activeFilters,
    sortConfig,
    viewMode,
    currentPage,
    itemsPerPage
  } = useAppContext();

  const [stocks, setStocks] = useState<Stock[]>([]);
  const [sectors, setSectors] = useState<Sector[]>([]);
  const [exchanges, setExchanges] = useState<Exchange[]>([]);
  const [totalCount, setTotalCount] = useState<number>(0);
  const [loading, setLoading] = useState<boolean>(true);
  const [filterDrawerVisible, setFilterDrawerVisible] = useState<boolean>(false);
  const [autocompleteSuggestions, setAutocompleteSuggestions] = useState<AutocompleteSuggestion[]>([]);
  const [lastUpdated, setLastUpdated] = useState<string | null>(null);

  const activeFilterCount = useMemo(() => {
    let count = 0;
    if (activeFilters.sectors && activeFilters.sectors.length > 0) count++;
    if (activeFilters.exchanges && activeFilters.exchanges.length > 0) count++;
    if (activeFilters.priceMin !== null || activeFilters.priceMax !== null) count++;
    if (activeFilters.marketCapRange !== null) count++;
    if (activeFilters.volumeMin !== null || activeFilters.volumeMax !== null) count++;
    return count;
  }, [activeFilters]);

  const paginationOffset = useMemo(() => {
    return (currentPage - 1) * itemsPerPage;
  }, [currentPage, itemsPerPage]);

  const { data: stocksData, loading: stocksLoading, error: stocksError, execute: fetchStocks } = useApi(
    StockManagementService.getStocks
  );

  const { data: sectorsData, execute: fetchSectors } = useApi(
    StockManagementService.getSectors
  );

  const { data: exchangesData, execute: fetchExchanges } = useApi(
    StockManagementService.getExchanges
  );

  const { data: autocompleteData, execute: fetchAutocomplete } = useApi(
    StockManagementService.getStocksSearchAutocomplete
  );

  useEffect(() => {
    const loadStocks = async () => {
      setLoading(true);
      try {
        const queryParams: Record<string, unknown> = {
          limit: itemsPerPage,
          offset: paginationOffset
        };

        if (searchQuery) {
          queryParams.search = searchQuery;
        }
        if (activeFilters.sectors && activeFilters.sectors.length > 0) {
          queryParams.sector_id = activeFilters.sectors[0];
        }
        if (activeFilters.exchanges && activeFilters.exchanges.length > 0) {
          queryParams.exchange_id = activeFilters.exchanges[0];
        }
        if (activeFilters.priceMin !== null) {
          queryParams.min_price = activeFilters.priceMin;
        }
        if (activeFilters.priceMax !== null) {
          queryParams.max_price = activeFilters.priceMax;
        }

        await fetchStocks(queryParams);
      } catch (e) {
        const { message: errorMessage } = parseError(e);
        messageApi.error(errorMessage);
      } finally {
        setLoading(false);
      }
    };

    void loadStocks();
  }, [fetchStocks, itemsPerPage, paginationOffset, searchQuery, activeFilters, messageApi]);

  useEffect(() => {
    void fetchSectors({ limit: 100, offset: 0 });
  }, [fetchSectors]);

  useEffect(() => {
    void fetchExchanges({ limit: 100, offset: 0 });
  }, [fetchExchanges]);

  useEffect(() => {
    if (searchQuery) {
      void fetchAutocomplete({ search: searchQuery });
    } else {
      setAutocompleteSuggestions([]);
    }
  }, [searchQuery, fetchAutocomplete]);

  useEffect(() => {
    if (stocksData) {
      setStocks(Array.isArray(stocksData) ? stocksData : []);
      setTotalCount(Array.isArray(stocksData) ? stocksData.length : 0);
      setLastUpdated(new Date().toLocaleString());
    }
  }, [stocksData]);

  useEffect(() => {
    if (sectorsData) {
      setSectors(Array.isArray(sectorsData) ? sectorsData : []);
    }
  }, [sectorsData]);

  useEffect(() => {
    if (exchangesData) {
      setExchanges(Array.isArray(exchangesData) ? exchangesData : []);
    }
  }, [exchangesData]);

  useEffect(() => {
    if (autocompleteData && Array.isArray(autocompleteData)) {
      const suggestions = autocompleteData.slice(0, 10).map((stock: Stock) => ({
        value: stock.ticker_symbol,
        label: `${stock.ticker_symbol} - ${stock.company_name}`,
        stock
      }));
      setAutocompleteSuggestions(suggestions);
    }
  }, [autocompleteData]);

  useEffect(() => {
    if (stocksError) {
      const { message: errorMessage } = parseError(stocksError);
      messageApi.error(errorMessage);
    }
  }, [stocksError, messageApi]);

  const handleSearchChange = useCallback((value: string) => {
    useAppContext.setState({ searchQuery: value, currentPage: 1 });
  }, []);

  const handlePageChange = useCallback((page: number) => {
    useAppContext.setState({ currentPage: page });
  }, []);

  const handlePageSizeChange = useCallback((current: number, size: number) => {
    useAppContext.setState({ itemsPerPage: size, currentPage: 1 });
  }, []);

  const handleViewModeToggle = useCallback((e: { target: { value: string } }) => {
    useAppContext.setState({ viewMode: e.target.value as 'table' | 'grid' });
  }, []);

  const handleFilterDrawerOpen = useCallback(() => {
    setFilterDrawerVisible(true);
  }, []);

  const handleFilterDrawerClose = useCallback(() => {
    setFilterDrawerVisible(false);
  }, []);

  const handleSectorFilterChange = useCallback((value: string[]) => {
    useAppContext.setState({
      activeFilters: { ...activeFilters, sectors: value },
      currentPage: 1
    });
  }, [activeFilters]);

  const handleExchangeFilterChange = useCallback((value: string[]) => {
    useAppContext.setState({
      activeFilters: { ...activeFilters, exchanges: value },
      currentPage: 1
    });
  }, [activeFilters]);

  const handlePriceMinChange = useCallback((value: number | null) => {
    useAppContext.setState({
      activeFilters: { ...activeFilters, priceMin: value },
      currentPage: 1
    });
  }, [activeFilters]);

  const handlePriceMaxChange = useCallback((value: number | null) => {
    useAppContext.setState({
      activeFilters: { ...activeFilters, priceMax: value },
      currentPage: 1
    });
  }, [activeFilters]);

  const handleMarketCapFilterChange = useCallback((value: string) => {
    useAppContext.setState({
      activeFilters: { ...activeFilters, marketCapRange: value },
      currentPage: 1
    });
  }, [activeFilters]);

  const handleApplyFilters = useCallback(async () => {
    setFilterDrawerVisible(false);
    setLoading(true);
    try {
      const queryParams: Record<string, unknown> = {
        limit: itemsPerPage,
        offset: paginationOffset
      };

      if (searchQuery) queryParams.search = searchQuery;
      if (activeFilters.sectors && activeFilters.sectors.length > 0) {
        queryParams.sector_id = activeFilters.sectors[0];
      }
      if (activeFilters.exchanges && activeFilters.exchanges.length > 0) {
        queryParams.exchange_id = activeFilters.exchanges[0];
      }
      if (activeFilters.priceMin !== null) queryParams.min_price = activeFilters.priceMin;
      if (activeFilters.priceMax !== null) queryParams.max_price = activeFilters.priceMax;

      await fetchStocks(queryParams);
    } catch (e) {
      const { message: errorMessage } = parseError(e);
      messageApi.error(errorMessage);
    } finally {
      setLoading(false);
    }
  }, [fetchStocks, itemsPerPage, paginationOffset, searchQuery, activeFilters, messageApi]);

  const handleClearAllFilters = useCallback(async () => {
    useAppContext.setState({
      activeFilters: {
        sectors: [],
        exchanges: [],
        priceMin: null,
        priceMax: null,
        marketCapRange: null,
        volumeMin: null,
        volumeMax: null
      },
      currentPage: 1
    });
    messageApi.success('Filters cleared');
    
    setLoading(true);
    try {
      await fetchStocks({ limit: itemsPerPage, offset: 0 });
    } catch (e) {
      const { message: errorMessage } = parseError(e);
      messageApi.error(errorMessage);
    } finally {
      setLoading(false);
    }
  }, [fetchStocks, itemsPerPage, messageApi]);

  const navigateToStockDetail = useCallback((record: Stock) => {
    navigate(ROUTES.STOCK_DETAIL.replace(':stockId', record.id));
  }, [navigate]);

  const formatCurrency = useCallback((value: number | null, currency: string = 'USD') => {
    if (value === null) return '-';
    return new Intl.NumberFormat('en-US', {
      style: 'currency',
      currency: currency
    }).format(value);
  }, []);

  const formatNumberAbbreviated = useCallback((value: number | null) => {
    if (value === null) return '-';
    if (value >= 1e9) return `${(value / 1e9).toFixed(2)}B`;
    if (value >= 1e6) return `${(value / 1e6).toFixed(2)}M`;
    if (value >= 1e3) return `${(value / 1e3).toFixed(2)}K`;
    return value.toString();
  }, []);

  const getSectorName = useCallback((sectorId: string) => {
    const sector = sectors.find(s => s.id === sectorId);
    return sector ? sector.name : sectorId;
  }, [sectors]);

  const getExchangeName = useCallback((exchangeId: string) => {
    const exchange = exchanges.find(e => e.id === exchangeId);
    return exchange ? exchange.code : exchangeId;
  }, [exchanges]);

  const columns = useMemo(() => [
    {
      title: '',
      dataIndex: 'logo_url',
      key: 'logo',
      width: 48,
      render: (logoUrl: string | null) => (
        <Avatar src={logoUrl} size={32} shape="square">
          {!logoUrl && 'S'}
        </Avatar>
      )
    },
    {
      title: 'Ticker',
      dataIndex: 'ticker_symbol',
      key: 'ticker_symbol',
      sorter: true,
      width: 100
    },
    {
      title: 'Company Name',
      dataIndex: 'company_name',
      key: 'company_name',
      sorter: true,
      ellipsis: true
    },
    {
      title: 'Price',
      dataIndex: 'current_price',
      key: 'current_price',
      sorter: true,
      width: 120,
      render: (price: number | null, record: Stock) => formatCurrency(price, record.currency)
    },
    {
      title: 'Change',
      dataIndex: 'price_change',
      key: 'price_change',
      width: 140,
      render: (_: unknown, record: Stock) => {
        if (record.current_price === null || record.closing_price === null) return '-';
        const change = record.current_price - record.closing_price;
        const changePercent = (change / record.closing_price) * 100;
        const color = change >= 0 ? '#52c41a' : '#ff4d4f';
        return (
          <span style={{ color }}>
            {change >= 0 ? '+' : ''}{change.toFixed(2)} ({changePercent.toFixed(2)}%)
          </span>
        );
      }
    },
    {
      title: 'Volume',
      dataIndex: 'volume',
      key: 'volume',
      sorter: true,
      width: 120,
      render: (volume: number | null) => formatNumberAbbreviated(volume)
    },
    {
      title: 'Market Cap',
      dataIndex: 'market_cap',
      key: 'market_cap',
      sorter: true,
      width: 130,
      render: (marketCap: number | null) => formatNumberAbbreviated(marketCap)
    },
    {
      title: 'Sector',
      dataIndex: 'sector_id',
      key: 'sector_id',
      width: 130,
      render: (sectorId: string) => <Tag>{getSectorName(sectorId)}</Tag>
    },
    {
      title: 'Exchange',
      dataIndex: 'exchange_id',
      key: 'exchange_id',
      width: 110,
      render: (exchangeId: string) => <Tag color="blue">{getExchangeName(exchangeId)}</Tag>
    }
  ], [formatCurrency, formatNumberAbbreviated, getSectorName, getExchangeName]);

  const autocompleteOptions = useMemo(() => {
    return autocompleteSuggestions.map(suggestion => ({
      value: suggestion.value,
      label: suggestion.label
    }));
  }, [autocompleteSuggestions]);

  const sectorOptions = useMemo(() => {
    return sectors.map(sector => ({
      label: sector.name,
      value: sector.id
    }));
  }, [sectors]);

  const exchangeOptions = useMemo(() => {
    return exchanges.map(exchange => ({
      label: exchange.name,
      value: exchange.id
    }));
  }, [exchanges]);

  const rootStyle: CSSProperties = {
    minHeight: '100vh',
    height: '100%',
    width: '100%',
    display: 'flex',
    flexDirection: 'column'
  };

  return (
    <div style={rootStyle}>
      {contextHolder}
      <Layout style={{ minHeight: '100vh', width: '100%', background: '#f5f5f5' }}>
        <div style={{ padding: '24px 24px 0 24px' }}>
          <Typography.Title level={2} style={{ marginBottom: '0' }}>
            Stocks
          </Typography.Title>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: '8px' }}>
            <Typography.Text type="secondary">
              {totalCount} stocks found
            </Typography.Text>
            {lastUpdated && (
              <Typography.Text type="secondary" style={{ fontSize: '12px' }}>
                Last updated: {lastUpdated}
              </Typography.Text>
            )}
          </div>
        </div>

        <div style={{ padding: '16px 24px', display: 'flex', gap: '12px', alignItems: 'center', flexWrap: 'wrap' }}>
          <AutoComplete
            value={searchQuery}
            onChange={handleSearchChange}
            options={autocompleteOptions}
            placeholder="Search by ticker symbol or company name..."
            allowClear
            size="large"
            style={{ flex: '1', minWidth: '280px' }}
          />
          <Badge count={activeFilterCount} offset={[-5, 5]}>
            <Button
              icon={<FilterOutlined />}
              size="large"
              onClick={handleFilterDrawerOpen}
            >
              Filters
            </Button>
          </Badge>
          <Radio.Group
            value={viewMode}
            onChange={handleViewModeToggle}
            buttonStyle="solid"
            size="large"
          >
            <Radio.Button value="table">
              <TableOutlined /> Table
            </Radio.Button>
            <Radio.Button value="grid">
              <AppstoreOutlined /> Grid
            </Radio.Button>
          </Radio.Group>
        </div>

        <div style={{ padding: '0 24px 24px 24px' }}>
          {loading ? (
            <Skeleton active paragraph={{ rows: 10 }} />
          ) : viewMode === 'table' ? (
            <Table
              columns={columns}
              dataSource={stocks}
              rowKey="id"
              loading={stocksLoading}
              size="middle"
              scroll={{ x: 1000 }}
              pagination={false}
              onRow={(record) => ({
                onClick: () => navigateToStockDetail(record),
                style: { cursor: 'pointer' }
              })}
              showSorterTooltip
            />
          ) : (
            <List
              grid={{
                gutter: 16,
                xs: 1,
                sm: 2,
                md: 3,
                lg: 4,
                xl: 4
              }}
              dataSource={stocks}
              loading={stocksLoading}
              renderItem={(stock) => (
                <List.Item>
                  <Card
                    hoverable
                    size="small"
                    onClick={() => navigateToStockDetail(stock)}
                    style={{ cursor: 'pointer' }}
                  >
                    <div style={{ display: 'flex', alignItems: 'center', gap: '12px', marginBottom: '12px' }}>
                      <Avatar src={stock.logo_url} size={40} shape="square">
                        {!stock.logo_url && stock.ticker_symbol.charAt(0)}
                      </Avatar>
                      <div style={{ flex: 1 }}>
                        <Typography.Text strong>{stock.ticker_symbol}</Typography.Text>
                        <Typography.Text type="secondary" style={{ display: 'block', fontSize: '12px' }} ellipsis>
                          {stock.company_name}
                        </Typography.Text>
                      </div>
                    </div>
                    <div style={{ marginBottom: '8px' }}>
                      <Typography.Title level={4} style={{ margin: 0 }}>
                        {formatCurrency(stock.current_price, stock.currency)}
                      </Typography.Title>
                    </div>
                    <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: '12px' }}>
                      <span>Vol: {formatNumberAbbreviated(stock.volume)}</span>
                      <span>Cap: {formatNumberAbbreviated(stock.market_cap)}</span>
                    </div>
                  </Card>
                </List.Item>
              )}
            />
          )}
        </div>

        <div style={{ padding: '16px 24px', display: 'flex', justifyContent: 'center' }}>
          <Pagination
            current={currentPage}
            pageSize={itemsPerPage}
            total={totalCount}
            showSizeChanger
            pageSizeOptions={['25', '50', '100']}
            showTotal={(total) => `Total ${total} items`}
            showQuickJumper
            onChange={handlePageChange}
            onShowSizeChange={handlePageSizeChange}
          />
        </div>

        <Drawer
          title="Filter Stocks"
          placement="right"
          width={360}
          open={filterDrawerVisible}
          onClose={handleFilterDrawerClose}
        >
          <Space direction="vertical" size="middle" style={{ width: '100%' }}>
            <div>
              <Typography.Text>Sector</Typography.Text>
              <Select
                mode="multiple"
                placeholder="Select sectors"
                allowClear
                value={activeFilters.sectors}
                onChange={handleSectorFilterChange}
                options={sectorOptions}
                style={{ width: '100%', marginTop: '8px' }}
              />
            </div>

            <div>
              <Typography.Text>Exchange</Typography.Text>
              <Select
                mode="multiple"
                placeholder="Select exchanges"
                allowClear
                value={activeFilters.exchanges}
                onChange={handleExchangeFilterChange}
                options={exchangeOptions}
                style={{ width: '100%', marginTop: '8px' }}
              />
            </div>

            <div>
              <Typography.Text>Price Range</Typography.Text>
              <div style={{ display: 'flex', gap: '8px', marginTop: '8px' }}>
                <InputNumber
                  placeholder="Min"
                  min={0}
                  prefix="$"
                  value={activeFilters.priceMin}
                  onChange={handlePriceMinChange}
                  style={{ width: '100%' }}
                />
                <InputNumber
                  placeholder="Max"
                  min={0}
                  prefix="$"
                  value={activeFilters.priceMax}
                  onChange={handlePriceMaxChange}
                  style={{ width: '100%' }}
                />
              </div>
            </div>

            <div>
              <Typography.Text>Market Cap</Typography.Text>
              <Select
                placeholder="Select market cap range"
                allowClear
                value={activeFilters.marketCapRange}
                onChange={handleMarketCapFilterChange}
                options={[
                  { label: 'Small Cap (< $2B)', value: 'small' },
                  { label: 'Mid Cap ($2B - $10B)', value: 'mid' },
                  { label: 'Large Cap (> $10B)', value: 'large' }
                ]}
                style={{ width: '100%', marginTop: '8px' }}
              />
            </div>

            <Button type="primary" block onClick={handleApplyFilters}>
              Apply Filters
            </Button>
            <Button block onClick={handleClearAllFilters} style={{ marginTop: '8px' }}>
              Clear All
            </Button>
          </Space>
        </Drawer>
      </Layout>
    </div>
  );
};

export default StockListPage;