import React, { useState, useEffect, useCallback, useRef } from 'react';
import { setMarketNames } from '../utils/marketNameCache';
import {
  getFavorites,
  toggleFavorite,
  FAVORITES_CHANGED_EVENT,
} from '../utils/marketStorage';

// ─── Types ───────────────────────────────────────────────────────────────────
interface MarketInfo {
  market:       string;   // "KRW-BTC"
  korean_name:  string;   // "비트코인"
  english_name: string;   // "Bitcoin"
  symbol:       string;   // "BTC"
}

interface TickerInfo {
  trade_price:          number;
  signed_change_rate:   number;   // 전일 대비 변화율 (소수, e.g. 0.015 = +1.5%)
  acc_trade_price_24h:  number;   // 24h 거래대금 (KRW)
}

// ─── Constants ───────────────────────────────────────────────────────────────
const UPBIT_API  = import.meta.env.DEV ? '/upbit-api/v1' : 'https://api.upbit.com/v1';
const TICKER_TTL = 3000;   // 3초마다 시세 갱신

function formatVol(vol: number): string {
  if (vol >= 1e12) return `${(vol / 1e12).toFixed(1)}조`;
  if (vol >= 1e8)  return `${(vol / 1e8).toFixed(0)}억`;
  if (vol >= 1e4)  return `${(vol / 1e4).toFixed(0)}만`;
  return vol.toLocaleString();
}

// ─── Component ───────────────────────────────────────────────────────────────
interface MarketSearchPanelProps {
  currentMarket: string;
  onSelect:      (market: string) => void;
  onClose:       () => void;
  /**
   * 슬롯 내 심볼 버튼 클릭 시 전달되는 슬롯 컨테이너 rect.
   * 제공되면 해당 슬롯 영역 안에서 패널이 표시된다.
   * 없으면 기본(전체화면 좌측 고정) 위치로 표시된다.
   */
  anchorRect?:   DOMRect | null;
  /** 외부 입력과 검색어 동기화 */
  initialQuery?: string;
}

export const MarketSearchPanel: React.FC<MarketSearchPanelProps> = ({
  currentMarket, onSelect, onClose, anchorRect, initialQuery = '',
}) => {
  const [markets, setMarkets] = useState<MarketInfo[]>([]);
  const [tickers, setTickers] = useState<Record<string, TickerInfo>>({});
  const [query,   setQuery]   = useState(initialQuery);
  const [favs,    setFavs]    = useState<Set<string>>(() => new Set(getFavorites()));
  const [loading, setLoading] = useState(true);

  const refreshFavs = useCallback(() => {
    setFavs(new Set(getFavorites()));
  }, []);

  const inputRef      = useRef<HTMLInputElement>(null);
  const tickerTimer   = useRef<ReturnType<typeof setInterval> | null>(null);
  const marketCodesRef = useRef<string>('');

  // ── 1. 마켓 목록 로드 ─────────────────────────────────────────────────────
  useEffect(() => {
    setLoading(true);
    fetch(`${UPBIT_API}/market/all?isDetails=false`)
      .then(r => r.json())
      .then((data: Array<{ market: string; korean_name: string; english_name: string }>) => {
        const krw = data
          .filter(m => m.market.startsWith('KRW-'))
          .map(m => ({ ...m, symbol: m.market.replace('KRW-', '') }));
        setMarkets(krw);
        marketCodesRef.current = krw.map(m => m.market).join(',');

        // 한글명 캐시 저장 (Toolbar 등에서 사용)
        const nameMap: Record<string, string> = {};
        for (const m of krw) nameMap[m.market] = m.korean_name;
        setMarketNames(nameMap);

        setLoading(false);
      })
      .catch(() => setLoading(false));

    setTimeout(() => inputRef.current?.focus(), 50);
    refreshFavs();
  }, [refreshFavs]);

  useEffect(() => {
    setQuery(initialQuery);
  }, [initialQuery]);

  // 좌측 마켓 패널 등에서 관심종목 변경 시 별표 동기화
  useEffect(() => {
    const onChanged = () => refreshFavs();
    window.addEventListener(FAVORITES_CHANGED_EVENT, onChanged);
    return () => window.removeEventListener(FAVORITES_CHANGED_EVENT, onChanged);
  }, [refreshFavs]);

  // ── 2. 시세 데이터 폴링 (100개씩 배치 요청) ─────────────────────────────
  const fetchTickers = useCallback(async () => {
    const codes = marketCodesRef.current;
    if (!codes) return;
    const allCodes = codes.split(',');
    const BATCH    = 100;
    const results: Array<{ market: string } & TickerInfo> = [];

    for (let i = 0; i < allCodes.length; i += BATCH) {
      const batch = allCodes.slice(i, i + BATCH).join(',');
      try {
        const data: Array<{ market: string } & TickerInfo> =
          await fetch(`${UPBIT_API}/ticker?markets=${batch}`).then(r => r.json());
        results.push(...data);
      } catch { /* ignore partial failures */ }
    }

    setTickers(prev => {
      const map: Record<string, TickerInfo> = { ...prev };
      for (const t of results) map[t.market] = t;
      return map;
    });
  }, []);

  useEffect(() => {
    if (markets.length === 0) return;
    fetchTickers();
    tickerTimer.current = setInterval(fetchTickers, TICKER_TTL);
    return () => { if (tickerTimer.current) clearInterval(tickerTimer.current); };
  }, [markets, fetchTickers]);

  // ── 3. 즐겨찾기 토글 ─────────────────────────────────────────────────────
  const toggleFav = useCallback(async (market: string, e: React.MouseEvent) => {
    e.stopPropagation();
    const row = markets.find(m => m.market === market);
    try {
      const next = await toggleFavorite(market, {
        koreanName:  row?.korean_name,
        englishName: row?.english_name,
      });
      setFavs(new Set(next));
    } catch (err) {
      console.warn('[MarketSearchPanel] watchlist toggle failed', err);
    }
  }, [markets]);

  // ── 4. 필터 + 정렬 ───────────────────────────────────────────────────────
  const q = query.trim();
  const filtered = markets.filter(m => {
    if (!q) return true;
    return (
      m.korean_name.includes(q) ||
      m.symbol.toUpperCase().includes(q.toUpperCase()) ||
      m.english_name.toLowerCase().includes(q.toLowerCase()) ||
      m.market.toUpperCase().includes(q.toUpperCase())
    );
  });

  const sorted = [...filtered].sort((a, b) => {
    const fa = favs.has(a.market) ? 1 : 0;
    const fb = favs.has(b.market) ? 1 : 0;
    if (fb !== fa) return fb - fa;
    // 즐겨찾기 동순위: 24h 거래대금 내림차순
    const va = tickers[a.market]?.acc_trade_price_24h ?? 0;
    const vb = tickers[b.market]?.acc_trade_price_24h ?? 0;
    return vb - va;
  });

  // ── Render ────────────────────────────────────────────────────────────────
  // anchorRect 제공 시: 슬롯 영역 안에 패널을 위치시킨다.
  const HEADER_H = 30; // 슬롯 헤더 높이 (약 30px)
  const MIN_W    = 260;

  // LWC v5 canvas 레이어가 내부적으로 높은 z-index를 사용하므로
  // 인라인 스타일로 z-index를 명시해 패널이 항상 최상단에 렌더되게 보장한다.
  const PANEL_Z = 99999;

  const panelStyle: React.CSSProperties | undefined = anchorRect
    ? {
        position:   'fixed',
        top:        anchorRect.top  + HEADER_H,
        left:       anchorRect.left,
        width:      Math.max(anchorRect.width, MIN_W),
        height:     anchorRect.height - HEADER_H,
        maxWidth:   anchorRect.width,
        zIndex:     PANEL_Z,
        // document.body 포털 시 CSS var()가 상속되지 않아 배경이 투명해지는 문제 방지
        background: 'var(--bg2, #24283b)',
        color:      'var(--text, #c0caf5)',
        border:     '1px solid var(--border, rgba(122,162,247,0.15))',
      }
    : undefined; // undefined → CSS 기본값(.msp-panel) 그대로 사용

  // 슬롯 전용 backdrop: 해당 슬롯 영역만 반투명 오버레이로 덮어 패널이 명확히 보이게 함
  const backdropStyle: React.CSSProperties | undefined = anchorRect
    ? {
        position:        'fixed',
        top:             anchorRect.top,
        left:            anchorRect.left,
        width:           anchorRect.width,
        height:          anchorRect.height,
        zIndex:          PANEL_Z - 1,
        background:      'rgba(0,0,0,0.45)',
        backdropFilter:  'none',
      }
    : undefined;

  return (
    <>
      {/* 배경 오버레이 (클릭 시 닫기) */}
      <div
        className="msp-backdrop"
        style={backdropStyle}
        onClick={onClose}
      />

      {/* 패널: anchorRect 있으면 인라인 스타일로 위치·z-index override */}
      <div
        className={`msp-panel${anchorRect ? ' msp-panel--slot' : ''}`}
        style={panelStyle}
      >

        {/* 검색 입력 */}
        <div className="msp-search-row">
          <span className="msp-search-icon">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
              <circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>
            </svg>
          </span>
          <input
            ref={inputRef}
            className="msp-input"
            placeholder="종목명 또는 심볼 검색"
            value={query}
            onChange={e => setQuery(e.target.value)}
            onKeyDown={e => {
              if (e.key === 'Escape') onClose();
              if (e.key === 'Enter' && sorted.length > 0) {
                onSelect(sorted[0].market);
                onClose();
              }
            }}
          />
          {query && (
            <button className="msp-btn-icon" title="초기화" onClick={() => setQuery('')}>
              <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
                <line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
              </svg>
            </button>
          )}
          <button className="msp-btn-icon" title="닫기" onClick={onClose}>
            <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
              <polyline points="18 15 12 9 6 15"/>
            </svg>
          </button>
        </div>

        {/* 컬럼 헤더 */}
        <div className="msp-header">
          <span className="msp-col msp-col-fav" />
          <span className="msp-col msp-col-name">한글명</span>
          <span className="msp-col msp-col-price">현재가</span>
          <span className="msp-col msp-col-change">전일대비</span>
          <span className="msp-col msp-col-vol">거래대금</span>
        </div>

        {/* 목록 */}
        <div className="msp-list">
          {loading && (
            <div className="msp-empty">마켓 목록 로딩 중...</div>
          )}
          {!loading && sorted.length === 0 && (
            <div className="msp-empty">검색 결과가 없습니다</div>
          )}
          {sorted.map(m => {
            const tk        = tickers[m.market];
            const isFav     = favs.has(m.market);
            const isActive  = m.market === currentMarket;
            const rate      = tk ? tk.signed_change_rate * 100 : null;
            const isUp      = rate !== null && rate >= 0;

            return (
              <div
                key={m.market}
                className={`msp-item${isActive ? ' active' : ''}`}
                onClick={() => { onSelect(m.market); onClose(); }}
              >
                {/* 즐겨찾기 */}
                <span
                  className={`msp-col msp-col-fav msp-star${isFav ? ' starred' : ''}`}
                  onClick={e => toggleFav(m.market, e)}
                  title={isFav ? '즐겨찾기 해제' : '즐겨찾기 추가'}
                >
                  {isFav ? '★' : '☆'}
                </span>

                {/* 이름 */}
                <span className="msp-col msp-col-name">
                  <span className="msp-kor">{m.korean_name}</span>
                  <span className="msp-sym">{m.symbol}</span>
                </span>

                {/* 현재가 */}
                <span className="msp-col msp-col-price">
                  {tk ? tk.trade_price.toLocaleString() : '-'}
                </span>

                {/* 전일대비 */}
                <span className={`msp-col msp-col-change ${rate === null ? '' : isUp ? 'up' : 'down'}`}>
                  {rate === null
                    ? '-'
                    : `${isUp ? '+' : ''}${rate.toFixed(2)}%`}
                </span>

                {/* 거래대금 */}
                <span className="msp-col msp-col-vol">
                  {tk?.acc_trade_price_24h ? formatVol(tk.acc_trade_price_24h) : '-'}
                </span>
              </div>
            );
          })}
        </div>

      </div>
    </>
  );
};

export default MarketSearchPanel;
