import React, { useEffect, useState } from 'react'
import { Loader2, TrendingUp, TrendingDown, Minus } from 'lucide-react'
import { fetchBatchPredictions, fetchStockInfo, BatchPredictionItem, StockInfo } from '../api/stockApi'

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

interface WatchlistEntry {
  code: string
  info: StockInfo | null
  prediction: BatchPredictionItem | null
  error: string | null
}

interface Props {
  onSelect: (code: string) => void
}

// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------

const DEFAULT_WATCHLIST = ['2330', '2317', '2454', '0050', '006208']

const SIGNAL_EMOJI: Record<string, string> = {
  BUY: '📈',
  SELL: '📉',
  HOLD: '➡️',
}

const SIGNAL_TEXT_CLASS: Record<string, string> = {
  BUY: 'text-green-400',
  SELL: 'text-red-400',
  HOLD: 'text-yellow-400',
}

const BUY_PROB_BG = (prob: number): string => {
  if (prob >= 0.6) return 'bg-green-600'
  if (prob <= 0.35) return 'bg-red-600'
  return 'bg-yellow-600'
}

// ---------------------------------------------------------------------------
// Component
// ---------------------------------------------------------------------------

export const WatchlistPanel: React.FC<Props> = ({ onSelect }) => {
  const [entries, setEntries] = useState<WatchlistEntry[]>(
    DEFAULT_WATCHLIST.map((code) => ({ code, info: null, prediction: null, error: null }))
  )
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    let cancelled = false
    let firstLoad = true

    const loadAll = async () => {
      if (firstLoad && !cancelled) setLoading(true)

      // Fetch info and batch predictions in parallel (single batch request instead of 5 individual ones)
      const [infoResults, batchResult] = await Promise.allSettled([
        Promise.allSettled(DEFAULT_WATCHLIST.map((code) => fetchStockInfo(code))),
        fetchBatchPredictions(DEFAULT_WATCHLIST),
      ])

      if (cancelled) return

      const infos = infoResults.status === 'fulfilled' ? infoResults.value : []
      const batchItems = batchResult.status === 'fulfilled' ? batchResult.value : []

      // Build a lookup map from batch results
      const predMap = new Map<string, BatchPredictionItem>()
      for (const item of batchItems) {
        predMap.set(item.code, item)
      }

      const resolved: WatchlistEntry[] = DEFAULT_WATCHLIST.map((code, i) => {
        const infoSettled = infos[i]
        const info = infoSettled?.status === 'fulfilled' ? infoSettled.value : null
        const batchItem = predMap.get(code) ?? null
        return {
          code,
          info,
          prediction: batchItem && !batchItem.error ? batchItem : null,
          error: batchItem?.error ?? null,
        }
      })

      setEntries(resolved)
      setLoading(false)
      firstLoad = false
    }

    loadAll()
    const id = setInterval(loadAll, 30_000)
    return () => {
      cancelled = true
      clearInterval(id)
    }
  }, [])

  return (
    <div className="bg-slate-900 border border-slate-700 rounded-xl p-4 space-y-3">
      <div className="flex items-center gap-2 mb-1">
        <TrendingUp size={16} className="text-blue-400" />
        <h3 className="text-sm font-bold text-slate-200">觀察清單</h3>
        <span className="text-xs text-slate-500 ml-auto">Watchlist</span>
      </div>

      {loading ? (
        <div className="flex items-center justify-center py-6 gap-2 text-slate-400">
          <Loader2 size={18} className="animate-spin" />
          <span className="text-sm">載入中...</span>
        </div>
      ) : (
        <ul className="space-y-1.5">
          {entries.map(({ code, info, prediction, error }) => (
            <li key={code}>
              <button
                onClick={() => onSelect(code)}
                className="w-full flex items-center gap-2 rounded-lg px-3 py-2 text-left bg-slate-800/60 hover:bg-slate-700/60 transition-colors group"
              >
                {/* Code + Name */}
                <div className="flex-1 min-w-0">
                  <span className="text-xs font-bold text-slate-100 group-hover:text-white">
                    {code}
                  </span>
                  {info?.name && info.name !== code && (
                    <span className="ml-1.5 text-xs text-slate-400 truncate">
                      {info.name}
                    </span>
                  )}
                </div>

                {/* Signal emoji */}
                {prediction && prediction.signal && !error ? (
                  <>
                    <span
                      className={`text-sm ${SIGNAL_TEXT_CLASS[prediction.signal] ?? 'text-slate-300'}`}
                      title={prediction.signal}
                    >
                      {SIGNAL_EMOJI[prediction.signal] ?? prediction.signal}
                    </span>

                    {/* Buy probability badge */}
                    {prediction.optimized === false ? (
                      <span className="text-[10px] font-semibold text-yellow-200 bg-yellow-700/70 rounded px-1.5 py-0.5">
                        計算中
                      </span>
                    ) : prediction.buy_prob != null && (
                      <span
                        className={`text-xs font-semibold text-white rounded px-1.5 py-0.5 ${BUY_PROB_BG(
                          prediction.buy_prob
                        )}`}
                      >
                        {Math.round(prediction.buy_prob * 100)}%
                      </span>
                    )}
                  </>
                ) : error ? (
                  <span className="text-xs text-red-400">—</span>
                ) : (
                  <Loader2 size={12} className="animate-spin text-slate-500" />
                )}
              </button>
            </li>
          ))}
        </ul>
      )}
    </div>
  )
}
