import React, { useState, useEffect, useCallback, useRef } from 'react';
import {
  Paper,
  IconButton,
  Typography,
  Box,
  List,
  ListItem,
  ListItemText,
  Tooltip,
} from '@mui/material';
import {
  Close as CloseIcon,
  Notifications as NotificationsIcon,
  Info as InfoIcon,
  ShowChart as ShowChartIcon,
  FormatListBulleted as AlertListIcon,
  OpenInNew as OpenInNewIcon,
  Analytics as AnalyticsIcon,
} from '@mui/icons-material';
import { useNavigate } from 'react-router-dom';
import { useAlertNotification } from '../../contexts/AlertNotificationContext';
import { useNavigation } from '../../contexts/NavigationContext';
import { AlertNotificationDto, getNotificationDetail } from '../../services/alertApi';
import type { BacktestResult, TradeRecord } from '../../services/backtestApi';
import { TradeSignalDetailDialog } from '../TradeSignalDetailDialog';
import upbitApiService from '../../services/upbitApi';
import {
  extractStrategyNames,
  extractStockStrategyPairs,
  resolveStockStrategyPairRow,
  resolveSymbols,
} from '../../utils/alertMessageParser';
import {
  alertMarkerTimeIsoFromDto,
  inferAlertSignalFromNotification,
} from '../../utils/alertSignalInference';
import { getUpbitWebExchangeUrl } from '../../utils/upbitWebUrls';
import AlertDetailDialog from './AlertDetailDialog';
import {
  buildBacktestResultFromAlertDetail,
  buildTradeRecordFromAlertDetail,
} from '../../utils/alertTradeRecordFromDetail';

/**
 * 알림 팝업 컴포넌트
 * 우측 상단에서 아래로 차례대로 표시, 사용자가 닫을 때까지 유지
 */
const AlertSnackbar: React.FC = () => {
  const navigate = useNavigate();
  const { navigateToPage } = useNavigation();
  const { notifications, markNotificationAsRead, dismissNotification, loadNotifications } = useAlertNotification();
  const [detailDialogOpen, setDetailDialogOpen] = useState(false);
  const [detailNotificationId, setDetailNotificationId] = useState<number | null>(null);
  const [cryptoMap, setCryptoMap] = useState<Map<string, string>>(new Map());
  const [positions, setPositions] = useState<Record<string, { x: number; y: number }>>({});
  const dragStateRef = useRef<{ key: string; startX: number; startY: number; startLeft: number; startTop: number } | null>(null);
  const [signalDetailOpen, setSignalDetailOpen] = useState(false);
  const [signalDetailTrade, setSignalDetailTrade] = useState<TradeRecord | null>(null);
  const [signalDetailBacktestResult, setSignalDetailBacktestResult] = useState<BacktestResult | null>(null);

  useEffect(() => {
    upbitApiService.getActiveCryptos().then((cryptos) => {
      const map = new Map<string, string>();
      cryptos.forEach((c) => map.set(c.koreanName, c.symbol));
      setCryptoMap(map);
    }).catch(() => {});
  }, []);

  const getNotificationKey = useCallback((n: AlertNotificationDto, index: number) => n.id != null ? `n-${n.id}` : `n-${index}`, []);

  const handleTitleMouseDown = useCallback((e: React.MouseEvent, key: string) => {
    if ((e.target as HTMLElement).closest('button')) return;
    const el = (e.currentTarget as HTMLElement).closest('[data-notification-paper]') as HTMLElement;
    if (!el) return;
    const rect = el.getBoundingClientRect();
    const pos = positions[key];
    dragStateRef.current = {
      key,
      startX: e.clientX,
      startY: e.clientY,
      startLeft: pos ? pos.x : rect.left,
      startTop: pos ? pos.y : rect.top,
    };
  }, [positions]);

  useEffect(() => {
    const handleMouseMove = (e: MouseEvent) => {
      const state = dragStateRef.current;
      if (!state) return;
      const dx = e.clientX - state.startX;
      const dy = e.clientY - state.startY;
      setPositions(prev => ({
        ...prev,
        [state.key]: { x: state.startLeft + dx, y: state.startTop + dy },
      }));
    };
    const handleMouseUp = () => { dragStateRef.current = null; };
    window.addEventListener('mousemove', handleMouseMove);
    window.addEventListener('mouseup', handleMouseUp);
    return () => {
      window.removeEventListener('mousemove', handleMouseMove);
      window.removeEventListener('mouseup', handleMouseUp);
    };
  }, []);

  const handleShowDetail = (notification: AlertNotificationDto) => {
    if (notification.id != null) {
      setDetailNotificationId(notification.id);
      setDetailDialogOpen(true);
    }
  };

  const handleOpenSignalDetail = async (
    e: React.MouseEvent,
    notification: AlertNotificationDto,
    pair?: { koreanName: string; strategyName: string; navSymbol?: string; symbol?: string }
  ) => {
    e.stopPropagation();
    if (!notification.id) return;
    try {
      const rowSym = (pair?.navSymbol ?? pair?.symbol ?? notification.symbol ?? '').trim();
      const detail = await getNotificationDetail(
        notification.id,
        rowSym ? { symbol: rowSym } : undefined
      );
      const inferred =
        inferAlertSignalFromNotification(notification, pair?.koreanName) ?? 'BUY';
      const strategy =
        pair?.strategyName?.trim() ||
        (notification.conditionDescription || '').replace(/^전략:\s*/, '').trim() ||
        undefined;
      const trade = buildTradeRecordFromAlertDetail(detail, inferred, strategy);
      const backtestResult = buildBacktestResultFromAlertDetail(detail, trade);
      setSignalDetailTrade(trade);
      setSignalDetailBacktestResult(backtestResult);
      setSignalDetailOpen(true);
    } catch (err) {
      console.error(err);
      alert('신호 상세를 불러오지 못했습니다.');
    }
  };

  const handleCloseDetail = () => {
    setDetailDialogOpen(false);
    setDetailNotificationId(null);
    loadNotifications();
  };

  const handleShowChart = (notification: AlertNotificationDto) => {
    if (notification?.symbol && notification.id != null) {
      const n = notification as AlertNotificationDto & { englishName?: string };
      navigate('/candlestick-test', { 
        state: { 
          symbol: notification.symbol,
          koreanName: notification.koreanName,
          englishName: n.englishName
        } 
      });
      markNotificationAsRead(notification.id);
    }
  };

  const handleStockClick = (notification: AlertNotificationDto, koreanName: string, symbol?: string) => {
    const timeIso = alertMarkerTimeIsoFromDto(notification);
    const inferred = inferAlertSignalFromNotification(notification, koreanName);
    const extras: { alertSignal?: 'BUY' | 'SELL'; alertMarkerTime?: string } = {};
    if (inferred && timeIso) {
      extras.alertSignal = inferred;
      extras.alertMarkerTime = timeIso;
    }
    if (symbol) {
      navigateToPage('alert-list', { symbol, koreanName, ...extras });
      return;
    }
    const resolved = resolveSymbols([koreanName], cryptoMap);
    if (resolved.length > 0) {
      navigateToPage('alert-list', {
        symbol: resolved[0].symbol,
        koreanName: resolved[0].koreanName,
        ...extras,
      });
    }
  };

  /** 통합/단일 알림 모두에 대해 타이틀(전략명)과 종목 목록 반환 */
  const getTitleAndPairs = (notification: AlertNotificationDto): { title: string; pairs: Array<{ koreanName: string; strategyName: string; symbol?: string }> } => {
    if (!notification) return { title: '', pairs: [] };
    const msg = notification.message || '';

    // 통합 알림: "🎯 알림 조건 충족 (N개)\n종목1 × 전략1\n..."
    if (msg.includes('알림 조건 충족') && msg.includes('개)')) {
      const strategyNames = extractStrategyNames(msg);
      const pairs = extractStockStrategyPairs(msg) ?? [];
      const title = strategyNames && strategyNames.length > 0
        ? strategyNames.length <= 3
          ? strategyNames.join(', ')
          : `${strategyNames.slice(0, 2).join(', ')} 외 ${strategyNames.length - 2}개 전략`
        : '🎯 통합 알림';
      return { title, pairs: pairs.map((p) => ({ ...p, symbol: undefined })) };
    }

    // 단일 종목 알림: koreanName/symbol 있고 message에 전략 정보
    if (notification.koreanName) {
      const firstLine = msg.split('\n')[0]?.trim() || '';
      const strategyName = firstLine.replace(/^[\s🧪🎯✅]*/, '').trim() || '알림';
      const title = strategyName;
      const pairs = [{ koreanName: notification.koreanName, strategyName, symbol: notification.symbol }];
      return { title, pairs };
    }

    return { title: notification.symbol || '알림', pairs: [] };
  };

  if (notifications.length === 0) {
    return (
      <AlertDetailDialog
        open={detailDialogOpen}
        notificationId={detailNotificationId}
        onClose={handleCloseDetail}
        onMarkAsRead={loadNotifications}
      />
    );
  }

  return (
    <>
      <Box
        sx={{
          position: 'fixed',
          top: 72,
          right: 16,
          zIndex: 10000,
          display: 'flex',
          flexDirection: 'column',
          gap: 1.5,
          maxHeight: 'calc(100vh - 100px)',
          overflowY: 'auto',
        }}
      >
        {notifications.map((notification, index) => {
          const { title, pairs } = getTitleAndPairs(notification);
          const hasStockList = pairs.length > 0;
          // 표시용 symbol 보강 (통합 알림의 경우 resolve)
          const displayPairs = pairs.map((p) => resolveStockStrategyPairRow(p, cryptoMap));

          const nKey = getNotificationKey(notification, index);
          const pos = positions[nKey];

          return (
            <Paper
              key={notification.id ?? `n-${index}`}
              data-notification-paper
              elevation={8}
              sx={{
                minWidth: 360,
                maxWidth: 420,
                flexShrink: 0,
                overflow: 'hidden',
                borderRadius: 1.5,
                border: '1px solid',
                borderColor: '#829EF1',
                ...(pos && { position: 'fixed' as const, left: pos.x, top: pos.y, right: 'auto', zIndex: 10001 }),
              }}
            >
              {/* 타이틀바 (드래그로 이동) */}
              <Box
                sx={{
                  display: 'flex',
                  alignItems: 'center',
                  justifyContent: 'space-between',
                  px: 1.5,
                  py: 1.25,
                  bgcolor: 'action.hover',
                  borderBottom: '1px solid',
                  borderColor: 'divider',
                  cursor: 'move',
                  userSelect: 'none',
                }}
                onMouseDown={(e) => handleTitleMouseDown(e, nKey)}
              >
                <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, minWidth: 0 }}>
                  <NotificationsIcon sx={{ color: 'success.main', fontSize: 20 }} />
                  <Typography variant="subtitle2" fontWeight="bold" noWrap sx={{ flex: 1 }}>
                    {title}
                  </Typography>
                </Box>
                <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.25, flexShrink: 0 }}>
                  {notification.symbol && !hasStockList && (
                    <>
                      <IconButton size="small" onClick={() => handleShowChart(notification)} title="차트보기">
                        <ShowChartIcon fontSize="small" />
                      </IconButton>
                      {notification.id != null && (
                        <Tooltip
                          title="알림 발생 시점 기준 전략·신호 상세"
                          placement="top"
                          PopperProps={{ sx: { zIndex: 11050 } }}
                        >
                          <IconButton
                            size="small"
                            onClick={(e) => handleOpenSignalDetail(e, notification)}
                            aria-label="전략 신호 상세"
                            color="primary"
                          >
                            <AnalyticsIcon fontSize="small" />
                          </IconButton>
                        </Tooltip>
                      )}
                    </>
                  )}
                  {notification.id && (
                    <IconButton size="small" onClick={() => handleShowDetail(notification)} title="상세보기">
                      <InfoIcon fontSize="small" />
                    </IconButton>
                  )}
                  <IconButton size="small" onClick={() => dismissNotification(notification)} title="닫기">
                    <CloseIcon fontSize="small" />
                  </IconButton>
                </Box>
              </Box>

              {/* 바디: 목록 또는 메시지 */}
              <Box sx={{ maxHeight: 220, overflowY: 'auto' }}>
                {hasStockList ? (
                  <List dense disablePadding sx={{ py: 0 }}>
                    {displayPairs.map((pair, i) => {
                      const marketSym = pair.navSymbol ?? pair.symbol;
                      const upbitUrl = getUpbitWebExchangeUrl(marketSym, notification.timeInterval);
                      return (
                      <ListItem
                        key={`${pair.navSymbol ?? pair.displaySymbol}-${pair.koreanName}-${i}`}
                        sx={{
                          py: 0.5,
                          px: 1.5,
                          cursor: 'pointer',
                          '&:hover': { bgcolor: 'action.hover' },
                          borderBottom: i < displayPairs.length - 1 ? '1px solid' : 'none',
                          borderColor: 'divider',
                        }}
                        onClick={() => handleStockClick(notification, pair.koreanName, pair.navSymbol ?? pair.symbol)}
                        secondaryAction={
                          <Box
                            sx={{ display: 'flex', alignItems: 'center', gap: 0.25, mr: -0.5 }}
                            onClick={(e) => e.stopPropagation()}
                          >
                            <Tooltip
                              title="알림목록으로 이동"
                              placement="top"
                              PopperProps={{ sx: { zIndex: 11050 } }}
                            >
                              <IconButton
                                size="small"
                                edge="end"
                                onClick={(e) => {
                                  e.stopPropagation();
                                  handleStockClick(notification, pair.koreanName, pair.navSymbol ?? pair.symbol);
                                }}
                                aria-label="알림목록으로 이동"
                              >
                                <AlertListIcon fontSize="small" />
                              </IconButton>
                            </Tooltip>
                            {upbitUrl ? (
                              <Tooltip
                                placement="top"
                                PopperProps={{ sx: { zIndex: 11050 } }}
                                title={
                                  notification.timeInterval
                                    ? `업비트 웹 차트 (시간봉 ${notification.timeInterval})`
                                    : '업비트 웹에서 차트 보기'
                                }
                              >
                                <IconButton
                                  size="small"
                                  component="a"
                                  href={upbitUrl}
                                  target="_blank"
                                  rel="noopener noreferrer"
                                  onClick={(e) => e.stopPropagation()}
                                  aria-label="업비트에서 차트 열기"
                                  sx={{ color: 'success.main' }}
                                >
                                  <OpenInNewIcon fontSize="small" />
                                </IconButton>
                              </Tooltip>
                            ) : null}
                            <Tooltip
                              title="알림 발생 시점 기준 전략·신호 상세 (해당 행 종목)"
                              placement="top"
                              PopperProps={{ sx: { zIndex: 11050 } }}
                            >
                              <span>
                                <IconButton
                                  size="small"
                                  onClick={(e) => handleOpenSignalDetail(e, notification, pair)}
                                  aria-label="전략 신호 상세"
                                  color="primary"
                                >
                                  <AnalyticsIcon fontSize="small" />
                                </IconButton>
                              </span>
                            </Tooltip>
                          </Box>
                        }
                      >
                        <ListItemText
                          primary={pair.koreanName}
                          secondary={pair.displaySymbol}
                          primaryTypographyProps={{ fontSize: '13px', fontWeight: 500 }}
                          secondaryTypographyProps={{ fontSize: '11px', color: 'text.secondary' }}
                        />
                      </ListItem>
                      );
                    })}
                  </List>
                ) : (
                  <Box sx={{ px: 1.5, py: 1.5 }}>
                    <Typography variant="body2" color="text.secondary" sx={{ whiteSpace: 'pre-line' }}>
                      {(notification.message || '').split('\n')[0]?.substring(0, 80) || ''}
                    </Typography>
                  </Box>
                )}

                {notification.id && (
                  <Box
                    sx={{
                      px: 1.5,
                      py: 1,
                      borderTop: '1px solid',
                      borderColor: 'divider',
                    }}
                  >
                    <Typography
                      variant="caption"
                      sx={{
                        color: 'primary.main',
                        textDecoration: 'underline',
                        cursor: 'pointer',
                        '&:hover': { color: 'primary.dark' },
                      }}
                      onClick={() => handleShowDetail(notification)}
                    >
                      상세보기 →
                    </Typography>
                  </Box>
                )}
              </Box>
            </Paper>
          );
        })}
      </Box>

      <AlertDetailDialog
        open={detailDialogOpen}
        notificationId={detailNotificationId}
        onClose={handleCloseDetail}
        onMarkAsRead={loadNotifications}
      />

      <TradeSignalDetailDialog
        open={signalDetailOpen}
        trade={signalDetailTrade}
        backtestResult={signalDetailBacktestResult}
        onClose={() => {
          setSignalDetailOpen(false);
          setSignalDetailTrade(null);
          setSignalDetailBacktestResult(null);
        }}
      />
    </>
  );
};

export default AlertSnackbar;
