import { Alert, CssBaseline, Snackbar, ThemeProvider } from "@mui/material";
import { useCallback, useEffect, useState } from "react";

// Local imports
import { DemoView } from "./components/DemoView";
import { InitialForm } from "./components/InitialForm";
import { CustomThemeProvider, useThemeMode } from "./contexts/ThemeContext";
import { FormData, SnackbarState, UserInfo } from "./types";
import { preloadDefaultMcp } from "./utils/api";
import { useStartDemo } from "./hooks/useStartDemo";

const AppContent = () => {
  const { theme } = useThemeMode();

  // Authentication state
  const [userInfo, setUserInfo] = useState<UserInfo | null>(null);
  const [accessToken, setAccessToken] = useState<string | null>(null);
  const [loginLabel, setLoginLabel] = useState<string>(
    "Login with Hugging Face",
  );

  // Form state
  const [formData, setFormData] = useState<FormData>({
    model: "",
    provider: "",
    mcpFile: null,
  });

  // UI state
  const [snackbar, setSnackbar] = useState<SnackbarState>({
    open: false,
    message: "",
    severity: "info",
  });
  const [defaultMcpFile, setDefaultMcpFile] = useState<File | null>(null);

  // Demo management hook
  const {
    isStarting,
    iframeUrl,
    iframeLoading,
    healthCheckProgress,
    startDemoSession,
    resetDemo,
    setIframeLoaded,
  } = useStartDemo();

  // Determine if we're in demo mode (iframe is loaded)
  const isDemoActive = Boolean(iframeUrl);

  // Utility functions
  const showSnackbar = useCallback(
    (message: string, severity: "success" | "error" | "info" = "info") => {
      setSnackbar({ open: true, message, severity });
    },
    [],
  );

  const handleSnackbarClose = () => {
    setSnackbar((prev: SnackbarState) => ({ ...prev, open: false }));
  };

  const handleIframeLoad = () => {
    setIframeLoaded();
  };

  // Authentication handlers
  const handleLoginStateChange = useCallback(
    (
      newUserInfo: UserInfo | null,
      newAccessToken: string | null,
      newLoginLabel: string,
    ) => {
      setUserInfo(newUserInfo);
      setAccessToken(newAccessToken);
      setLoginLabel(newLoginLabel);
    },
    [],
  );

  // Form handlers
  const handleFormChange = (newFormData: FormData) => {
    setFormData(newFormData);
  };

  const handleFormSubmit = async () => {
    await startDemoSession(formData, loginLabel, accessToken, {
      logPrefix: "Initial startup",
      onError: (error) => {
        showSnackbar(error.message, "error");
      },
    });
  };

  const handleRestart = () => {
    resetDemo();
  };

  const handleSettingsRestart = async () => {
    await startDemoSession(formData, loginLabel, accessToken, {
      logPrefix: "Settings restart",
      onError: (error) => {
        showSnackbar(error.message, "error");
      },
    });
  };

  // Initialize default MCP file on mount
  useEffect(() => {
    const loadDefaultMcp = async () => {
      const mcpFile = await preloadDefaultMcp();
      if (mcpFile) {
        setFormData((prev: FormData) => ({ ...prev, mcpFile: mcpFile }));
        setDefaultMcpFile(mcpFile);
      }
    };
    loadDefaultMcp();
  }, []);

  return (
    <ThemeProvider theme={theme}>
      <CssBaseline />

      {/* Conditional rendering based on demo state */}
      {isDemoActive ? (
        <DemoView
          iframeUrl={iframeUrl}
          iframeLoading={iframeLoading}
          healthCheckProgress={healthCheckProgress}
          formData={formData}
          onIframeLoad={handleIframeLoad}
          onRestart={handleRestart}
          onFormChange={handleFormChange}
          onSettingsRestart={handleSettingsRestart}
          defaultMcpFile={defaultMcpFile}
        />
      ) : (
        <InitialForm
          formData={formData}
          userInfo={userInfo}
          accessToken={accessToken}
          loginLabel={loginLabel}
          isStarting={isStarting}
          onFormChange={handleFormChange}
          onSubmit={handleFormSubmit}
          onLoginStateChange={handleLoginStateChange}
          defaultMcpFile={defaultMcpFile}
        />
      )}

      {/* Snackbar for notifications */}
      <Snackbar
        open={snackbar.open}
        autoHideDuration={4000}
        onClose={handleSnackbarClose}
        anchorOrigin={{ vertical: "bottom", horizontal: "center" }}
      >
        <Alert
          onClose={handleSnackbarClose}
          severity={snackbar.severity}
          sx={{ width: "100%" }}
        >
          {snackbar.message}
        </Alert>
      </Snackbar>
    </ThemeProvider>
  );
};

function App() {
  return (
    <CustomThemeProvider>
      <AppContent />
    </CustomThemeProvider>
  );
}

export default App;
