
import React, { useState, useEffect, useMemo, useCallback } from 'react';
import { HashRouter, Routes, Route, Link, useLocation } from 'react-router-dom';
import { 
  LayoutDashboard, 
  Settings as SettingsIcon, 
  Newspaper, 
  Cpu, 
  History,
  Terminal,
  ChevronDown,
  ShieldCheck,
  Server,
  Zap,
  Star,
  LayoutGrid,
  RotateCcw,
  Compass
} from 'lucide-react';
import { ApiSettings, StockItem, OrderType, MarketType, TradeOrder, AutoTradeConfig, WatchlistGroup, ReservedOrder, StockTick } from './types';
import { MOCK_STOCKS } from './constants';
import { KisService } from './services/kisService';
import { TelegramService } from './services/telegramService';
import { DbService } from './services/dbService';
import Dashboard from './pages/Dashboard';
import AutoTrading from './pages/AutoTrading';
import News from './pages/News';
import Settings from './pages/Settings';
import HistoryPage from './pages/History';
import WatchlistManagement from './pages/WatchlistManagement';
import Stocks from './pages/Stocks';
import Discovery from './pages/Discovery';

interface LogEntry {
  id: string;
  type: 'info' | 'error' | 'success' | 'warn';
  message: string;
  timestamp: Date;
}

const TopNavItem: React.FC<{ to: string, icon: React.ReactNode, label: string, active: boolean }> = ({ to, icon, label, active }) => (
  <Link to={to} className={`flex items-center gap-2 px-3 py-2 rounded-xl font-black text-[11px] uppercase tracking-wider transition-all ${active ? 'bg-blue-600 text-white shadow-md' : 'text-slate-400 hover:text-blue-600 hover:bg-blue-50'}`}>
    {/* Fix for line 43: Use React.isValidElement and cast to React.ReactElement<any> to allow the size prop for Lucide icons */}
    {React.isValidElement(icon) ? React.cloneElement(icon as React.ReactElement<any>, { size: 16 }) : icon}
    <span>{label}</span>
  </Link>
);

const AppContent: React.FC = () => {
  const [settings, setSettings] = useState<ApiSettings>(() => {
    const saved = localStorage.getItem('trader_settings');
    return saved ? JSON.parse(saved) : {
      appKey: '', appSecret: '', accountNumber: '',
      useTelegram: false, telegramToken: '', telegramChatId: '',
      useNaverNews: false, naverClientId: '', naverClientSecret: '',
      aiConfigs: [
        { id: 'def_gemini', name: 'Gemini 기본 분석기', providerType: 'gemini', modelName: 'gemini-3-flash-preview' }
      ],
      preferredNewsAiId: 'def_gemini',
      preferredStockAiId: 'def_gemini',
      preferredNewsJudgementAiId: 'def_gemini',
      preferredAutoBuyAiId: 'def_gemini',
      preferredAutoSellAiId: 'def_gemini'
    };
  });

  const [marketMode, setMarketMode] = useState<MarketType>(MarketType.DOMESTIC);
  const [masterStocks, setMasterStocks] = useState<StockItem[]>(() => {
    const saved = localStorage.getItem('batchukis_master_stocks');
    return saved ? JSON.parse(saved) : MOCK_STOCKS;
  });
  
  const [watchlistGroups, setWatchlistGroups] = useState<WatchlistGroup[]>([]);
  const [orders, setOrders] = useState<TradeOrder[]>([]);
  const [reservedOrders, setReservedOrders] = useState<ReservedOrder[]>([]);
  const [autoTrades, setAutoTrades] = useState<AutoTradeConfig[]>([]);
  const [logs, setLogs] = useState<LogEntry[]>([]);
  const [isConsoleOpen, setIsConsoleOpen] = useState(false);

  const location = useLocation();
  const kisService = useMemo(() => new KisService(settings), [settings]);
  const dbService = useMemo(() => new DbService(), []);

  const visibleStocks = useMemo(() => {
    return masterStocks.filter(s => !s.isHidden);
  }, [masterStocks]);

  useEffect(() => {
    localStorage.setItem('trader_settings', JSON.stringify(settings));
  }, [settings]);

  useEffect(() => {
    localStorage.setItem('batchukis_master_stocks', JSON.stringify(masterStocks));
  }, [masterStocks]);

  useEffect(() => {
    syncFromDb();
  }, [dbService]);

  const addLog = useCallback((message: string, type: LogEntry['type'] = 'info') => {
    setLogs(prev => [{
      id: Math.random().toString(36).substr(2, 9),
      type, message, timestamp: new Date()
    }, ...prev].slice(0, 100));
  }, []);

  const handleUpdateStockMetadata = (code: string, updates: Partial<StockItem>) => {
    setMasterStocks(prev => prev.map(s => s.code === code ? { ...s, ...updates } : s));
  };

  const syncFromDb = async () => {
    const configs = await dbService.getAutoConfigs();
    const groups = await dbService.getWatchlistGroups();
    const resOrders = await dbService.getReservedOrders();
    setAutoTrades(configs);
    setWatchlistGroups(groups);
    setReservedOrders(resOrders);
  };

  const handleSyncStocks = async () => {
    addLog(`${marketMode === MarketType.DOMESTIC ? '국내' : '해외'} 종목 마스터 동기화 시작...`, 'info');
    try {
      const serverStocks = await kisService.fetchMasterStocks(marketMode);
      setMasterStocks(prev => {
        const existingCodes = new Set(prev.map(s => s.code));
        const newStocks = serverStocks.filter(s => !existingCodes.has(s.code));
        if (newStocks.length === 0) return prev;
        addLog(`${newStocks.length}개의 신규 종목이 마스터 리스트에 추가되었습니다.`, 'success');
        return [...prev, ...newStocks];
      });
    } catch (e) {
      addLog("종목 동기화 실패", "error");
    }
  };

  const handleManualOrder = async (order: Omit<TradeOrder, 'id' | 'timestamp' | 'status'>) => {
    const res = await (order.stockCode.length > 6 
      ? kisService.orderOverseas(order.stockCode, order.type, order.quantity, order.price)
      : kisService.orderCash(order.stockCode, order.type, order.quantity, order.price)
    );
    if (res.success) {
      const newOrder: TradeOrder = { id: res.orderId, ...order, status: 'COMPLETED', timestamp: new Date() } as TradeOrder;
      await dbService.syncOrderToHolding(newOrder);
      setOrders(prev => [newOrder, ...prev]);
      addLog(`${order.stockName} ${order.type === OrderType.BUY ? '매수' : '매도'} 완료`, 'success');
    }
  };

  const handleAddToWatchlist = async (stock: StockItem) => {
    const groups = await dbService.getWatchlistGroups();
    const targetGroup = groups.find(g => g.market === stock.market);
    if (targetGroup) {
      const updated = targetGroup.codes.includes(stock.code)
        ? { ...targetGroup, codes: targetGroup.codes.filter(c => c !== stock.code) }
        : { ...targetGroup, codes: [...targetGroup.codes, stock.code] };
      await dbService.updateWatchlistGroup(updated);
      syncFromDb();
    }
  };

  const watchlistCodes = useMemo(() => watchlistGroups.flatMap(g => g.codes), [watchlistGroups]);
  const isActive = (path: string) => location.pathname === path;

  return (
    <div className="flex flex-col h-screen bg-[#F8FAFC] overflow-hidden font-sans text-slate-900">
      <header className="h-16 bg-white/80 backdrop-blur-xl border-b border-slate-100 flex items-center justify-between px-6 z-50 sticky top-0 shadow-sm">
        <div className="flex items-center gap-6">
          <div className="flex flex-col">
            <h1 className="text-xl font-black italic tracking-tighter text-blue-600 flex items-center gap-1.5">
              <Zap className="fill-blue-600" size={18} /> BATCHUKIS
            </h1>
            <span className="text-[8px] font-black text-slate-400 uppercase tracking-[0.2em] -mt-1">Trading Bot Engine</span>
          </div>
          <nav className="flex items-center gap-0.5">
            <TopNavItem to="/" icon={<LayoutDashboard />} label="대시보드" active={isActive('/')} />
            <TopNavItem to="/discovery" icon={<Compass />} label="종목발굴" active={isActive('/discovery')} />
            <TopNavItem to="/stocks" icon={<LayoutGrid />} label="종목" active={isActive('/stocks')} />
            <TopNavItem to="/auto" icon={<Cpu />} label="자동매매" active={isActive('/auto')} />
            <TopNavItem to="/watchlist" icon={<Star />} label="관심종목" active={isActive('/watchlist')} />
            <TopNavItem to="/news" icon={<Newspaper />} label="뉴스" active={isActive('/news')} />
            <TopNavItem to="/history" icon={<History />} label="기록" active={isActive('/history')} />
            <TopNavItem to="/settings" icon={<SettingsIcon />} label="설정" active={isActive('/settings')} />
          </nav>
        </div>
        <div className="flex items-center gap-4">
          <div className="flex bg-slate-100 p-0.5 rounded-xl border border-slate-200">
            <button onClick={() => setMarketMode(MarketType.DOMESTIC)} className={`px-3 py-1.5 rounded-lg text-[10px] font-black transition-all ${marketMode === MarketType.DOMESTIC ? 'bg-white text-blue-600 shadow-sm' : 'text-slate-400'}`}>국내</button>
            <button onClick={() => setMarketMode(MarketType.OVERSEAS)} className={`px-3 py-1.5 rounded-lg text-[10px] font-black transition-all ${marketMode === MarketType.OVERSEAS ? 'bg-white text-blue-600 shadow-sm' : 'text-slate-400'}`}>해외</button>
          </div>
          <button onClick={() => setIsConsoleOpen(!isConsoleOpen)} className={`p-2 rounded-xl transition-all border ${isConsoleOpen ? 'bg-slate-900 text-white border-slate-900' : 'bg-white text-slate-400 border-slate-200 hover:text-blue-600'}`}><Terminal size={18} /></button>
          <div className="w-8 h-8 rounded-xl bg-slate-900 flex items-center justify-center text-white shadow-md"><ShieldCheck size={16} /></div>
        </div>
      </header>

      <main className="flex-1 overflow-y-auto p-6 custom-scrollbar relative">
        <Routes>
          <Route path="/" element={<Dashboard marketMode={marketMode} watchlistGroups={watchlistGroups} stocks={visibleStocks} orders={orders} reservedOrders={reservedOrders} onManualOrder={handleManualOrder} onAddReservedOrder={async (o) => { await dbService.saveReservedOrder({id: 'res_'+Date.now(), ...o, status: 'WAITING', createdAt: new Date(), expiryDate: new Date()}); syncFromDb(); }} onDeleteReservedOrder={async (id) => { await dbService.deleteReservedOrder(id); syncFromDb(); }} onRefreshHoldings={syncFromDb} autoTrades={autoTrades} />} />
          <Route path="/discovery" element={<Discovery stocks={masterStocks} orders={orders} onUpdateStock={handleUpdateStockMetadata} settings={settings} />} />
          <Route path="/stocks" element={<Stocks marketMode={marketMode} stocks={visibleStocks} onTrade={(s, t) => addLog(`${s.name} ${t} 주문 패널 진입`, 'info')} onAddToWatchlist={handleAddToWatchlist} watchlistCodes={watchlistCodes} onSync={handleSyncStocks} />} />
          <Route path="/auto" element={<AutoTrading marketMode={marketMode} stocks={visibleStocks} configs={autoTrades} groups={watchlistGroups} onAddConfig={async (c) => { await dbService.saveAutoConfig({...c, id: 'auto_'+Date.now(), active: true}); syncFromDb(); }} onToggleConfig={async (id) => { const c = (await dbService.getAutoConfigs()).find(x => x.id === id); if(c) { await dbService.updateAutoConfig({...c, active: !c.active}); syncFromDb(); } }} onDeleteConfig={async (id) => { await dbService.deleteAutoConfig(id); syncFromDb(); }} />} />
          <Route path="/watchlist" element={<WatchlistManagement marketMode={marketMode} stocks={visibleStocks} groups={watchlistGroups} onRefresh={syncFromDb} />} />
          <Route path="/news" element={<News settings={settings} />} />
          <Route path="/history" element={<HistoryPage orders={orders} />} />
          <Route path="/settings" element={<Settings settings={settings} onSave={setSettings} />} />
        </Routes>
      </main>

      {isConsoleOpen && (
        <div className="fixed bottom-0 left-0 right-0 bg-slate-950 text-slate-300 transition-all duration-500 z-[100] border-t border-slate-800 h-64 flex flex-col shadow-2xl">
          <div className="flex items-center justify-between px-6 py-2.5 border-b border-slate-800 bg-slate-950">
             <div className="flex items-center gap-2"><Server size={12} className="text-blue-500" /><span className="text-[9px] font-black uppercase tracking-[0.15em]">Execution Console</span></div>
             <div className="flex gap-4 items-center">
                <button onClick={() => setLogs([])} className="text-[9px] font-black text-slate-500 hover:text-white flex items-center gap-1"><RotateCcw size={10} /> CLEAR</button>
                <button onClick={() => setIsConsoleOpen(false)} className="text-slate-500 hover:text-white"><ChevronDown size={14}/></button>
             </div>
          </div>
          <div className="p-4 flex-1 overflow-y-auto font-mono text-[10px] space-y-1.5 custom-scrollbar">
            {logs.map(log => (
              <div key={log.id} className="flex gap-3 animate-in slide-in-from-left-2">
                <span className="text-slate-600 shrink-0">[{log.timestamp.toLocaleTimeString()}]</span>
                <span className={`font-bold ${log.type === 'error' ? 'text-rose-500' : log.type === 'success' ? 'text-emerald-500' : log.type === 'warn' ? 'text-amber-500' : 'text-blue-400'}`}>{log.type.toUpperCase()}</span>
                <span className="text-slate-300">{log.message}</span>
              </div>
            ))}
            {logs.length === 0 && <div className="text-slate-600 italic">No logs available. System standby...</div>}
          </div>
        </div>
      )}
    </div>
  );
};

const App: React.FC = () => (
  <HashRouter>
    <AppContent />
  </HashRouter>
);

export default App;
