import { useCallback, useEffect, useState } from 'react';
import { Toast } from '@douyinfe/semi-ui';
import { api } from './api/client';
import type { VehicleServiceStatus } from './api/types';
import { buildAppHash, parseAppHash } from './domain/appRoute';
import { AppShell, type PageKey } from './layout/AppShell';
import { Dashboard } from './pages/Dashboard';
import { History } from './pages/History';
import { Mileage } from './pages/Mileage';
import { Quality } from './pages/Quality';
import { Realtime } from './pages/Realtime';
import { VehicleDetail } from './pages/VehicleDetail';
import { Vehicles } from './pages/Vehicles';

export default function App() {
  const initialRoute = parseAppHash(window.location.hash);
  const initialVehicleKey = initialRoute.keyword || 'LB9A32A24R0LS1426';
  const [activePage, setActivePage] = useState<PageKey>(initialRoute.page ?? 'dashboard');
  const [activeVin, setActiveVin] = useState(initialVehicleKey);
  const [analysisVin, setAnalysisVin] = useState(initialVehicleKey);
  const [activeProtocol, setActiveProtocol] = useState(initialRoute.protocol ?? '');
  const [linkIssueCount, setLinkIssueCount] = useState<number | null>(null);
  const [currentVehicleStatus, setCurrentVehicleStatus] = useState<VehicleServiceStatus | undefined>();
  const [currentVehicleLabel, setCurrentVehicleLabel] = useState('');

  const refreshOpsHealth = useCallback((showError = true) => {
    return api.opsHealth()
      .then((health) => {
        setLinkIssueCount(health.linkHealth.filter((item) => item.status !== 'ok').length);
        return health;
      })
      .catch((error: Error) => {
        if (showError) {
          Toast.error(error.message);
        }
      });
  }, []);

  useEffect(() => {
    refreshOpsHealth();
    const timer = window.setInterval(() => {
      refreshOpsHealth(false);
    }, 60000);
    return () => window.clearInterval(timer);
  }, [refreshOpsHealth]);

  useEffect(() => {
    const applyHashRoute = () => {
      const route = parseAppHash(window.location.hash);
      if (!route.page) {
        return;
      }
      setActivePage(route.page);
      if (route.keyword) {
        if (route.page === 'detail') {
          setActiveVin(route.keyword);
        }
        if (route.page === 'history' || route.page === 'mileage') {
          setAnalysisVin(route.keyword);
        }
      }
      setActiveProtocol(route.protocol ?? '');
    };
    window.addEventListener('hashchange', applyHashRoute);
    return () => window.removeEventListener('hashchange', applyHashRoute);
  }, []);

  const replaceHash = (page: PageKey, keyword?: string, protocol?: string) => {
    const nextHash = buildAppHash({ page, keyword, protocol });
    if (window.location.hash !== nextHash) {
      window.history.replaceState(null, '', nextHash);
    }
  };

  const navigatePage = (page: PageKey) => {
    setActivePage(page);
    if (page === 'detail') {
      replaceHash(page, activeVin, activeProtocol);
      return;
    }
    if (page === 'history' || page === 'mileage') {
      replaceHash(page, analysisVin, activeProtocol);
      return;
    }
    replaceHash(page);
  };

  const openVehicle = async (keyword: string, protocol?: string) => {
    const lookupKey = keyword.trim();
    const nextProtocol = protocol?.trim() ?? '';
    if (!lookupKey) {
      return;
    }
    try {
      const resolved = await api.vehicleResolve(new URLSearchParams({ keyword: lookupKey }));
      const nextKey = resolved.resolved && resolved.vin ? resolved.vin : lookupKey;
      setCurrentVehicleStatus(resolved.serviceStatus);
      setCurrentVehicleLabel(resolved.resolved ? [resolved.plate, resolved.vin || nextKey].filter(Boolean).join(' / ') : lookupKey);
      setActiveVin(nextKey);
      setActiveProtocol(nextProtocol);
      setActivePage('detail');
      replaceHash('detail', nextKey, nextProtocol);
      if (!resolved.resolved) {
        Toast.warning('未匹配到车辆身份，已打开问题排查视图');
      }
    } catch (error) {
      Toast.error(error instanceof Error ? error.message : '车辆查询失败');
    }
  };

  const openHistoryForVehicle = (vin: string, protocol?: string) => {
    const nextVin = vin.trim();
    const nextProtocol = protocol?.trim() ?? activeProtocol;
    if (!nextVin) {
      return;
    }
    setAnalysisVin(nextVin);
    setActiveProtocol(nextProtocol);
    setActivePage('history');
    replaceHash('history', nextVin, nextProtocol);
  };

  const openMileageForVehicle = (vin: string, protocol?: string) => {
    const nextVin = vin.trim();
    const nextProtocol = protocol?.trim() ?? activeProtocol;
    if (!nextVin) {
      return;
    }
    setAnalysisVin(nextVin);
    setActiveProtocol(nextProtocol);
    setActivePage('mileage');
    replaceHash('mileage', nextVin, nextProtocol);
  };

  const updateVehicleDetailQuery = (keyword: string, protocol?: string) => {
    const nextKeyword = keyword.trim();
    const nextProtocol = protocol?.trim() ?? '';
    if (!nextKeyword) {
      return;
    }
    setActiveVin(nextKeyword);
    setActiveProtocol(nextProtocol);
    replaceHash('detail', nextKeyword, nextProtocol);
  };

  const pages: Record<PageKey, JSX.Element> = {
    dashboard: <Dashboard onOpenVehicle={openVehicle} onOpenQuality={() => navigatePage('quality')} />,
    vehicles: <Vehicles onOpenVehicle={openVehicle} />,
    realtime: <Realtime onOpenVehicle={openVehicle} />,
    detail: <VehicleDetail vin={activeVin} protocol={activeProtocol} onOpenHistory={openHistoryForVehicle} onOpenMileage={openMileageForVehicle} onQueryChange={updateVehicleDetailQuery} />,
    history: <History initialVin={analysisVin} initialProtocol={activeProtocol} onOpenVehicle={openVehicle} />,
    mileage: <Mileage initialVin={analysisVin} initialProtocol={activeProtocol} onOpenVehicle={openVehicle} />,
    quality: <Quality onOpenVehicle={openVehicle} onHealthLoaded={(health) => setLinkIssueCount(health.linkHealth.filter((item) => item.status !== 'ok').length)} />
  };

  return (
    <AppShell activePage={activePage} linkIssueCount={linkIssueCount} currentVehicleStatus={currentVehicleStatus} currentVehicleLabel={currentVehicleLabel} onChange={navigatePage} onVehicleSearch={openVehicle}>
      {pages[activePage]}
    </AppShell>
  );
}
