import React, {
  useEffect,
  useState,
  Component,
  ErrorInfo,
  ReactNode,
  Suspense,
} from "react";
import { QueryClientProvider } from "@tanstack/react-query";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import { logger } from "@/utils/logger";
import { Routes, Route, useLocation } from "react-router-dom";
import { initializeStores } from "./stores/storeInitializer";
import { queryClient, isDevMode } from "./lib/query/queryClient";
import { Toaster } from "./components/ui/toaster";
import { SentryErrorBoundary, captureError, trackPageView } from "./lib/sentry";
import { initializePWA } from "./utils/pwa";
import { EnvTest } from "./components/debug/EnvTest";
// import { setupChunkErrorHandler, resetRetryCount } from "./utils/chunkErrorHandler"; // 임시 비활성화
import { createLazyComponent } from "./utils/lazyWithRetry";
import {
  isChunkLoadError,
  isClerkChunkError,
  handleChunkLoadError,
} from "./utils/chunkErrorProtection";
import {
  ClerkProvider,
  ClerkDebugInfo,
} from "./components/providers/ClerkProvider";
import { BudgetProvider } from "./contexts/budget/BudgetContext";

// 페이지 컴포넌트들을 개선된 레이지 로딩으로 변경 (ChunkLoadError 재시도 포함)
const Index = createLazyComponent(() => import("./pages/Index"));
const Login = createLazyComponent(() => import("./pages/Login"));
const Register = createLazyComponent(() => import("./pages/Register"));
const Settings = createLazyComponent(() => import("./pages/Settings"));
const Transactions = createLazyComponent(() => import("./pages/Transactions"));
const Analytics = createLazyComponent(() => import("./pages/Analytics"));
const ProfileManagement = createLazyComponent(
  () => import("./pages/ProfileManagement")
);
const NotFound = createLazyComponent(() => import("./pages/NotFound"));
const PaymentMethods = createLazyComponent(
  () => import("./pages/PaymentMethods")
);
const HelpSupport = createLazyComponent(() => import("./pages/HelpSupport"));
const SecurityPrivacySettings = createLazyComponent(
  () => import("./pages/SecurityPrivacySettings")
);
const NotificationSettings = createLazyComponent(
  () => import("./pages/NotificationSettings")
);
const ForgotPassword = createLazyComponent(
  () => import("./pages/ForgotPassword")
);
const PWADebugPage = createLazyComponent(() => import("./pages/PWADebugPage"));

// 중요하지 않은 컴포넌트들도 개선된 레이지 로딩 적용
const BackgroundSync = createLazyComponent(
  () => import("./components/sync/BackgroundSync")
);
const QueryCacheManager = createLazyComponent(
  () => import("./components/query/QueryCacheManager")
);
const OfflineManager = createLazyComponent(
  () => import("./components/offline/OfflineManager")
);
const SentryTestButton = createLazyComponent(
  () => import("./components/SentryTestButton")
);
const ClerkDebugControl = createLazyComponent(
  () => import("./components/debug/ClerkDebugControl")
);

// Clerk 인증 컴포넌트 (다시 활성화)
const SignIn = createLazyComponent(() =>
  import("./components/auth/SignIn").then((module) => ({
    default: module.SignIn,
  }))
);
const SignUp = createLazyComponent(() =>
  import("./components/auth/SignUp").then((module) => ({
    default: module.SignUp,
  }))
);

// 간단한 오류 경계 컴포넌트 구현
interface ErrorBoundaryProps {
  children: ReactNode;
  fallback?: ReactNode;
}

interface ErrorBoundaryState {
  hasError: boolean;
  error: Error | null;
}

class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
  constructor(props: ErrorBoundaryProps) {
    super(props);
    this.state = { hasError: false, error: null };
  }

  static getDerivedStateFromError(error: Error): ErrorBoundaryState {
    return { hasError: true, error };
  }

  componentDidCatch(error: Error, errorInfo: ErrorInfo): void {
    logger.error("애플리케이션 오류:", {
      error: error.message,
      componentStack: errorInfo.componentStack,
    });

    // ChunkLoadError 처리
    if (isChunkLoadError(error)) {
      if (isClerkChunkError(error)) {
        logger.warn("Error Boundary에서 Clerk 청크 오류 감지. 자동 복구 시도");
        // Clerk 자동 비활성화
        sessionStorage.setItem("disableClerk", "true");
        // 3초 후 새로고침
        setTimeout(() => {
          const url = new URL(window.location.href);
          url.searchParams.set("noClerk", "true");
          url.searchParams.set("_t", Date.now().toString());
          window.location.href = url.toString();
        }, 3000);
        return;
      } else {
        // 일반 청크 오류 처리
        handleChunkLoadError(error);
        return;
      }
    }

    // Sentry에 에러 리포팅 (청크 오류가 아닌 경우만)
    captureError(error, { errorInfo });
  }

  render(): ReactNode {
    if (this.state.hasError) {
      // ChunkLoadError인 경우 특별한 UI 표시
      if (this.state.error && isChunkLoadError(this.state.error)) {
        const isClerkError = isClerkChunkError(this.state.error);

        return (
          <div className="flex flex-col items-center justify-center min-h-screen p-4 text-center">
            <div className={`text-4xl mb-4 ${isClerkError ? "🔧" : "⚠️"}`}>
              {isClerkError ? "🔧" : "⚠️"}
            </div>
            <h2 className="text-xl font-bold mb-4">
              {isClerkError ? "Clerk 로딩 오류" : "앱 로딩 오류"}
            </h2>
            <p className="mb-4 text-gray-600">
              {isClerkError
                ? "Supabase 인증으로 자동 전환 중입니다. 잠시만 기다려주세요..."
                : "앱을 복구하고 있습니다. 잠시만 기다려주세요..."}
            </p>
            {!isClerkError && (
              <button
                onClick={() => {
                  sessionStorage.clear();
                  window.location.reload();
                }}
                className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
              >
                수동 새로고침
              </button>
            )}
          </div>
        );
      }

      // 일반 오류 처리
      return (
        this.props.fallback || (
          <div className="flex flex-col items-center justify-center min-h-screen p-4 text-center">
            <h2 className="text-xl font-bold mb-4">
              앱 로딩 중 오류가 발생했습니다
            </h2>
            <p className="mb-4">잠시 후 다시 시도해주세요.</p>
            <button
              onClick={() => window.location.reload()}
              className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
            >
              새로고침
            </button>
          </div>
        )
      );
    }

    return this.props.children;
  }
}

// 로딩 상태 표시 컴포넌트
const LoadingScreen: React.FC = () => (
  <div className="flex flex-col items-center justify-center min-h-screen p-4 text-center bg-neuro-background">
    <div className="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-blue-500 mb-4"></div>
    <h2 className="text-xl font-bold mb-2">Zellyy Finance</h2>
    <p className="text-gray-600">앱을 로딩하고 있습니다...</p>
    <div className="mt-4 text-xs text-gray-500">
      환경: {import.meta.env.MODE} | Clerk:{" "}
      {import.meta.env.VITE_CLERK_PUBLISHABLE_KEY ? "✓" : "✗"} | Supabase:{" "}
      {import.meta.env.VITE_SUPABASE_URL ? "✓" : "✗"}
    </div>
  </div>
);

// 페이지 로딩 컴포넌트 (코드 스플리팅용)
const PageLoadingSpinner: React.FC = () => (
  <div className="flex flex-col items-center justify-center min-h-[50vh] p-4 text-center">
    <div className="animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-blue-500 mb-2"></div>
    <p className="text-gray-600 text-sm">페이지를 로딩하고 있습니다...</p>
  </div>
);

// 페이지 전환 추적 컴포넌트
const PageTracker = () => {
  const location = useLocation();

  useEffect(() => {
    // 페이지 이름 매핑
    const getPageName = (pathname: string) => {
      const pageMap: Record<string, string> = {
        "/": "홈",
        "/login": "로그인",
        "/register": "회원가입",
        "/forgot-password": "비밀번호 찾기",
        "/analytics": "분석",
        "/transactions": "거래내역",
        "/settings": "설정",
        "/profile": "프로필",
        "/help": "도움말",
      };
      return pageMap[pathname] || pathname;
    };

    const pageName = getPageName(location.pathname);
    trackPageView(pageName, location.pathname + location.search);
  }, [location]);

  return null;
};

// 오류 화면 컴포넌트
const ErrorScreen: React.FC<{ error: Error | null; retry: () => void }> = ({
  error,
  retry,
}) => (
  <div className="flex flex-col items-center justify-center min-h-screen p-4 text-center bg-neuro-background">
    <div className="text-red-500 text-5xl mb-4">⚠️</div>
    <h2 className="text-xl font-bold mb-4">애플리케이션 오류</h2>
    <p className="text-center mb-6">
      {error?.message || "애플리케이션 로딩 중 오류가 발생했습니다."}
    </p>
    <button
      onClick={retry}
      className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
    >
      재시도
    </button>
  </div>
);

// 기본 레이아웃 컴포넌트 - 인증 없이도 표시 가능
const BasicLayout: React.FC<{ children: React.ReactNode }> = ({ children }) => (
  <div className="App">
    {children}
    <Toaster />
  </div>
);

function App() {
  const [appState, setAppState] = useState<"loading" | "error" | "ready">(
    "loading"
  );
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    document.title = "Zellyy Finance";
    // eslint-disable-next-line no-console
    console.log("🚀 App useEffect 실행됨");

    // 프로덕션 환경에서 간단한 초기화 테스트
    const simpleInitialize = async () => {
      try {
        // eslint-disable-next-line no-console
        console.log("🔧 간단한 초기화 시작");
        // eslint-disable-next-line no-console
        console.log("환경:", import.meta.env.MODE);
        // eslint-disable-next-line no-console
        console.log("모든 환경변수:", import.meta.env);
        // eslint-disable-next-line no-console
        console.log(
          "VITE_CLERK_PUBLISHABLE_KEY:",
          import.meta.env.VITE_CLERK_PUBLISHABLE_KEY || "없음"
        );
        // eslint-disable-next-line no-console
        console.log(
          "VITE_SUPABASE_URL:",
          import.meta.env.VITE_SUPABASE_URL || "없음"
        );

        // 매우 간단한 초기화만 수행
        await new Promise((resolve) => setTimeout(resolve, 100));

        // eslint-disable-next-line no-console
        console.log("✅ 간단한 초기화 완료 - ready 상태로 변경");
        setAppState("ready");
      } catch (error) {
        console.error("❌ 간단한 초기화 실패:", error);
        setError(error instanceof Error ? error : new Error("초기화 실패"));
        setAppState("error");
      }
    };

    simpleInitialize();

    // 컴포넌트 언마운트 시 정리
    return () => {
      // eslint-disable-next-line no-console
      console.log("🧹 App 컴포넌트 정리");
    };
  }, []);

  // 재시도 기능
  const handleRetry = async () => {
    setAppState("loading");
    setError(null);

    try {
      // 재시도 시 PWA 및 스토어 재초기화
      await initializePWA();
      await initializeStores();
      setAppState("ready");
    } catch (error) {
      logger.error(
        "재시도 실패",
        error instanceof Error
          ? { message: error.message, stack: error.stack }
          : String(error)
      );
      setError(error instanceof Error ? error : new Error("재시도 실패"));
      setAppState("error");
    }
  };

  // 로딩 상태 표시
  if (appState === "loading") {
    return (
      <ErrorBoundary
        fallback={<ErrorScreen error={error} retry={handleRetry} />}
      >
        <LoadingScreen />
      </ErrorBoundary>
    );
  }

  // 오류 상태 표시
  if (appState === "error") {
    return <ErrorScreen error={error} retry={handleRetry} />;
  }

  return (
    <ClerkProvider>
      <QueryClientProvider client={queryClient}>
        <SentryErrorBoundary
          fallback={<ErrorScreen error={error} retry={handleRetry} />}
          showDialog={false}
        >
          <BudgetProvider>
            <BasicLayout>
              <PageTracker />
              <Suspense fallback={<PageLoadingSpinner />}>
                <Routes>
                  <Route path="/" element={<Index />} />
                  {/* Clerk 라우트 다시 활성화 */}
                  <Route path="/sign-in/*" element={<SignIn />} />
                  <Route path="/sign-up/*" element={<SignUp />} />
                  <Route path="/login" element={<Login />} />
                  <Route path="/register" element={<Register />} />
                  <Route path="/settings" element={<Settings />} />
                  <Route path="/transactions" element={<Transactions />} />
                  <Route path="/analytics" element={<Analytics />} />
                  <Route path="/profile" element={<ProfileManagement />} />
                  <Route path="/payment-methods" element={<PaymentMethods />} />
                  <Route path="/help-support" element={<HelpSupport />} />
                  <Route
                    path="/security-privacy"
                    element={<SecurityPrivacySettings />}
                  />
                  <Route
                    path="/notifications"
                    element={<NotificationSettings />}
                  />
                  <Route path="/forgot-password" element={<ForgotPassword />} />
                  <Route path="/pwa-debug" element={<PWADebugPage />} />
                  <Route path="*" element={<NotFound />} />
                </Routes>
              </Suspense>
              {/* React Query 캐시 관리 */}
              <Suspense fallback={null}>
                <QueryCacheManager
                  cleanupIntervalMinutes={30}
                  enableOfflineCache={true}
                  enableCacheAnalysis={isDevMode}
                />
              </Suspense>

              {/* 오프라인 상태 관리 */}
              <Suspense fallback={null}>
                <OfflineManager
                  showOfflineToast={true}
                  autoSyncOnReconnect={true}
                />
              </Suspense>

              {/* 백그라운드 자동 동기화 - 성능 최적화로 30초 간격으로 조정 */}
              <Suspense fallback={null}>
                <BackgroundSync
                  intervalMinutes={0.5}
                  syncOnFocus={true}
                  syncOnOnline={true}
                />
              </Suspense>

              {/* 개발환경에서 Sentry 테스트 버튼 */}
              <Suspense fallback={null}>
                <SentryTestButton />
              </Suspense>

              {/* 개발환경에서 Clerk 상태 디버깅 */}
              <ClerkDebugInfo />

              {/* 개발환경에서 환경 변수 테스트 */}
              {isDevMode && <EnvTest />}

              {/* Clerk 디버그 및 제어 */}
              <Suspense fallback={null}>
                <ClerkDebugControl />
              </Suspense>
            </BasicLayout>
          </BudgetProvider>
          {isDevMode && <ReactQueryDevtools initialIsOpen={false} />}
        </SentryErrorBoundary>
      </QueryClientProvider>
    </ClerkProvider>
  );
}

export default App;
