
import React, { useState, useEffect } from 'react';
import { serialService } from './services/serialService';
import { JBDProtocol, CMD_BASIC_INFO, CMD_CELL_INFO, CMD_HW_VERSION } from './services/jbdProtocol';
import { BMSBasicInfo, BMSCellInfo, ConnectionState } from './types';
import Dashboard from './components/Dashboard';
import Settings from './components/Settings';
import Terminal from './components/Terminal';
import { LayoutDashboard, Settings as SettingsIcon, Usb, AlertCircle, RefreshCw, PanelRightClose, PanelRightOpen } from 'lucide-react';

const AdSenseBanner: React.FC = () => {
  useEffect(() => {
    try {
      // @ts-ignore
      (window.adsbygoogle = window.adsbygoogle || []).push({});
    } catch (e) {
      console.error("AdSense error", e);
    }
  }, []);

  return (
    <div className="w-full max-w-lg mt-4">
      {/* AppLeftSizeBox */}
      <ins className="adsbygoogle"
        style={{ display: "block" }}
        data-ad-client="ca-pub-4444852135420953"
        data-ad-slot="7799405796"
        data-ad-format="auto"
        data-full-width-responsive="true"></ins>
    </div>
  );
};

const App: React.FC = () => {
  const [connectionState, setConnectionState] = useState<ConnectionState>(ConnectionState.DISCONNECTED);
  const [basicInfo, setBasicInfo] = useState<BMSBasicInfo | null>(null);
  const [cellInfo, setCellInfo] = useState<BMSCellInfo | null>(null);
  const [hwVersion, setHwVersion] = useState<string | null>(null);
  const [activeTab, setActiveTab] = useState<'dashboard' | 'settings'>('dashboard');
  const [errorMsg, setErrorMsg] = useState<string | null>(null);
  const [isTerminalOpen, setIsTerminalOpen] = useState(false);



  useEffect(() => {
    let isMounted = true;
    let timeoutId: number;

    const runPoll = async () => {
      // ONLY POLL IF ON DASHBOARD AND CONNECTED
      if (connectionState !== ConnectionState.CONNECTED || activeTab !== 'dashboard') return;

      try {
        // 1. Get Basic Info
        const basicData = await serialService.sendCommand(CMD_BASIC_INFO);
        const parsedBasic = JBDProtocol.parseBasicInfo(basicData);
        if (isMounted) setBasicInfo(parsedBasic);

        // Delay 500ms
        await new Promise(r => setTimeout(r, 500));
        if (!isMounted) return;

        // 2. Get Cell Info
        const cellData = await serialService.sendCommand(CMD_CELL_INFO);
        const parsedCells = JBDProtocol.parseCellInfo(cellData);
        if (isMounted) setCellInfo(parsedCells);

        // Delay 500ms
        await new Promise(r => setTimeout(r, 500));
        if (!isMounted) return;

        // 3. Get Hardware Version (CMD 0x05)
        const hwData = await serialService.sendCommand(CMD_HW_VERSION);
        // CMD 0x05 usually returns raw ASCII string in payload
        const versionStr = new TextDecoder().decode(hwData);
        if (isMounted) setHwVersion(versionStr);

        if (isMounted) setErrorMsg(null);
      } catch (e: any) {
        console.error("Polling error:", e);
        // Log to terminal for debugging
        serialService.log('error', `Poll Fail: ${e.message}`);
        setIsTerminalOpen(true);
      } finally {
        // Schedule next poll cycle in 500ms
        if (isMounted && connectionState === ConnectionState.CONNECTED && activeTab === 'dashboard') {
          timeoutId = window.setTimeout(runPoll, 500);
        }
      }
    };

    if (connectionState === ConnectionState.CONNECTED && activeTab === 'dashboard') {
      runPoll();
    }

    return () => {
      isMounted = false;
      window.clearTimeout(timeoutId);
    };
  }, [connectionState, activeTab]);

  const handleConnect = async () => {
    try {
      setConnectionState(ConnectionState.CONNECTING);
      await serialService.connect();
      setConnectionState(ConnectionState.CONNECTED);
      setErrorMsg(null);
    } catch (e: any) {
      console.error(e);
      setConnectionState(ConnectionState.ERROR);
      setErrorMsg(e.message || "시리얼 포트 연결 실패");
      setIsTerminalOpen(true);
    }
  };

  const handleDisconnect = async () => {
    try {
      await serialService.disconnect();
      setConnectionState(ConnectionState.DISCONNECTED);
      setBasicInfo(null);
      setCellInfo(null);
      setHwVersion(null);
    } catch (e) {
      console.error(e);
    }
  };

  const toggleMosfet = async (type: 'charge' | 'discharge', currentState: boolean) => {
    if (!basicInfo) return;
    try {
      const newCharge = type === 'charge' ? !currentState : basicInfo.mosfetStatus.charge;
      const newDischarge = type === 'discharge' ? !currentState : basicInfo.mosfetStatus.discharge;

      await serialService.toggleMosfet(newCharge, newDischarge);
    } catch (e: any) {
      alert("MOSFET 제어 실패: " + e.message);
    }
  };

  const renderContent = () => {
    switch (activeTab) {
      case 'dashboard':
        return <Dashboard basicInfo={basicInfo} cellInfo={cellInfo} hwVersion={hwVersion} onToggleMosfet={toggleMosfet} />;
      case 'settings':
        return <Settings />;
      default:
        return null;
    }
  };

  return (
    <div className="flex flex-col lg:flex-row h-screen w-full bg-gray-50 text-gray-900 overflow-hidden">

      {/* Sidebar / Topbar */}
      <div className="w-full lg:w-64 flex-shrink-0 bg-white border-b lg:border-b-0 lg:border-r border-gray-200 flex flex-row lg:flex-col z-20 items-center lg:items-stretch justify-between lg:justify-start h-16 lg:h-auto px-4 lg:px-0">
        <div className="flex items-center justify-center lg:justify-start lg:p-6">
          <div className="h-8 w-8 bg-blue-600 rounded-lg flex items-center justify-center font-bold shadow-lg shadow-blue-900/50 text-white">
            J
          </div>
          <span className="ml-3 font-bold text-xl hidden lg:block tracking-tight text-gray-800">JBD Tool</span>
        </div>

        <nav className="flex lg:flex-1 flex-row lg:flex-col gap-2 lg:space-y-2 lg:mt-4 lg:px-4">
          <button
            onClick={() => setActiveTab('dashboard')}
            className={`flex items-center p-2 lg:p-3 rounded-xl transition-all ${activeTab === 'dashboard'
              ? 'bg-blue-600 text-white shadow-lg shadow-blue-900/20'
              : 'text-gray-600 hover:bg-gray-100 hover:text-gray-900'
              }`}
          >
            <LayoutDashboard size={20} />
            <span className="ml-3 hidden lg:block font-medium">Dashboard</span>
          </button>
          <button
            onClick={() => setActiveTab('settings')}
            className={`flex items-center p-2 lg:p-3 rounded-xl transition-all ${activeTab === 'settings'
              ? 'bg-blue-600 text-white shadow-lg shadow-blue-900/20'
              : 'text-gray-600 hover:bg-gray-100 hover:text-gray-900'
              }`}
          >
            <SettingsIcon size={20} />
            <span className="ml-3 hidden lg:block font-medium">EEPROM</span>
          </button>
        </nav>

        <div className="hidden lg:flex p-4 border-t border-gray-200 flex-col">
          {/* AdSense Area - Expanded */}
          <AdSenseBanner key={activeTab} />
        </div>
      </div>

      {/* Main Content Area */}
      <div className="flex-1 flex flex-col h-full overflow-hidden relative">
        {/* Header */}
        <header className="h-16 bg-white/80 backdrop-blur border-b border-gray-200 flex items-center justify-between px-6 z-10 flex-shrink-0">
          <h1 className="text-xl font-semibold text-gray-800">
            {activeTab === 'dashboard' ? 'Overview' : 'Configuration'}
          </h1>
          <div className="flex items-center gap-4">
            {connectionState === ConnectionState.CONNECTED ? (
              <button
                onClick={handleDisconnect}
                className="py-1.5 px-3 bg-red-100 text-red-600 border border-red-200 rounded-lg hover:bg-red-200 transition-colors flex items-center text-sm font-semibold"
              >
                <Usb size={16} className="mr-2" />
                Disconnect
              </button>
            ) : (
              <button
                onClick={handleConnect}
                disabled={connectionState === ConnectionState.CONNECTING}
                className="py-1.5 px-3 bg-green-600 text-white rounded-lg hover:bg-green-500 transition-colors flex items-center text-sm font-semibold shadow-sm"
              >
                {connectionState === ConnectionState.CONNECTING ? <RefreshCw className="animate-spin mr-2" size={16} /> : <Usb size={16} className="mr-2" />}
                Connect
              </button>
            )}


            <button
              onClick={() => setIsTerminalOpen(!isTerminalOpen)}
              className="p-2 text-gray-500 hover:bg-gray-100 rounded-lg transition-colors"
              title={isTerminalOpen ? "Hide Terminal" : "Show Terminal"}
            >
              {isTerminalOpen ? <PanelRightClose size={20} /> : <PanelRightOpen size={20} />}
            </button>
          </div>
        </header>

        {/* Content Body with Right Sidebar */}
        <div className="flex-1 flex overflow-hidden">
          {/* Main View */}
          <main className="flex-1 overflow-hidden bg-gray-50 relative">
            {errorMsg && (
              <div className="bg-red-900/80 text-white px-6 py-2 flex items-center justify-center text-sm font-medium backdrop-blur absolute top-0 left-0 right-0 z-30 animate-in slide-in-from-top-2">
                <AlertCircle size={16} className="mr-2" />
                {errorMsg}
              </div>
            )}

            {renderContent()}

            {/* Empty State Overlay */}
            {connectionState !== ConnectionState.CONNECTED && (
              <div className="absolute inset-0 bg-white/80 backdrop-blur-sm z-10 flex flex-col items-center justify-center p-6 text-center">
                <div className="w-16 h-16 bg-gray-100 rounded-2xl flex items-center justify-center mb-6 shadow-xl border border-gray-200">
                  <Usb size={32} className="text-gray-500" />
                </div>
                <h2 className="text-2xl font-bold text-gray-900 mb-2">장치가 연결되지 않았습니다</h2>
                <p className="text-gray-500 max-w-md mb-8">
                  JBD BMS를 UART-to-USB 어댑터로 연결하여 실시간 상태를 확인하고 설정을 변경하세요.
                </p>
                <AdSenseBanner />
              </div>
            )}
          </main>

          {/* Right Terminal Panel */}
          <aside className={`${isTerminalOpen ? 'w-80 lg:w-96 border-l' : 'w-0 border-l-0'} transition-all duration-300 ease-in-out border-gray-200 bg-white flex flex-col flex-shrink-0 z-20 overflow-hidden`}>
            <div className="w-80 lg:w-96 h-full flex flex-col">
              <Terminal />
            </div>
          </aside>
        </div>
      </div>
    </div>
  );
};

export default App;
