import { Suspense, lazy, useEffect, useContext } from "react";
import { Switch, Route, Redirect } from "wouter";
import { UserProtectedRoute, ParentProtectedRoute } from "./components/routes/ProtectedRoute";
import { queryClient } from "./lib/queryClient";
import { QueryClientProvider } from "@tanstack/react-query";
import { Toaster } from "./components/ui/toaster";
import { LoadingRocket } from "./components/ui/loading-rocket";
import { TeacherProvider } from "./context/TeacherContext";
import TeacherContext from "./context/TeacherContext";
import SimpleErrorBoundary from "./components/ui/SimpleErrorBoundary";
import LoadingScreen from "./components/loading-screen";

// Performance tracking
const markRouteLoad = (routeName) => {
  if (window.trackResourceLoaded) {
    window.trackResourceLoaded(`route:${routeName}`);
  }
};

// Enhanced lazy loading with performance tracking
const enhancedLazy = (importFn, name) => {
  return lazy(() => {
    // Mark the start of loading this component
    if (window.trackResourceLoaded) {
      window.trackResourceLoaded(`lazyLoad:${name}:start`);
    }

    return importFn().then((module) => {
      // Mark the completion of loading this component
      if (window.trackResourceLoaded) {
        window.trackResourceLoaded(`lazyLoad:${name}:complete`);
      }
      return module;
    });
  });
};

// High-priority routes - load these immediately after initial render
const ActivityList = enhancedLazy(
  () => import("./pages/activitylist"),
  "ActivityList",
);

// Lower-priority routes - load these after the critical path is established
const NotFound = enhancedLazy(() => import("./pages/not-found"), "NotFound");
const Login = enhancedLazy(() => import("./pages/login"), "Login");
const ParentLogin = enhancedLazy(
  () => import("./pages/parent-login"),
  "ParentLogin",
);
const ParentActivityForm = enhancedLazy(
  () =>
    import("./pages/ParentActivityForm").then((module) => ({
      default: module.ParentActivityForm,
    })),
  "ParentActivityForm",
);
const ParentReportViewPage = enhancedLazy(
  () => import("./pages/ParentReportView"),
  "ParentReportViewPage",
);
const Profile = enhancedLazy(() => import("./pages/profile"), "Profile");
const EditProfile = enhancedLazy(() => import("./pages/edit-profile"), "EditProfile");

const ActivityDetail = enhancedLazy(() => import("./pages/activity-detail"), "ActivityDetail");
const CanvaCallback = enhancedLazy(() => import("./pages/canva-callback"), "CanvaCallback");
const Reports = enhancedLazy(() => import("./pages/reports"), "Reports");
const PermissionError = enhancedLazy(() => import("./pages/permission-error"), "PermissionError");

// Custom component to handle redirection from old routes
const DashboardRedirect = () => {
  useEffect(() => {
    markRouteLoad("DashboardRedirect");
  }, []);
  return <Redirect to="/activities" />;
};

// Route-level performance tracking wrapper
const TrackedRoute = ({ path, component: Component, name }) => {
  useEffect(() => {
    markRouteLoad(name || path);
  }, [path, name]);

  return <Route path={path} component={Component} />;
};

// Role-based protected route component
const RoleProtectedRoute = ({ component: Component, allowedRoles, excludedRoles, path, name }) => {
  const context = useContext(TeacherContext);
  const teacherData = context?.teacherData;
  const loading = context?.loading;
  
  useEffect(() => {
    markRouteLoad(name || path);
  }, [path, name]);

  const hasPermission = () => {
    if (!teacherData || !teacherData.roles) return false;
    
    // If excludedRoles is provided, check that user doesn't have any of those roles
    if (excludedRoles) {
      // Check if user has any role that's in the excluded list
      const hasExcludedRole = teacherData.roles.some(role => 
        excludedRoles.includes(role.role_name)
      );
      
      // If the user ONLY has excluded roles, deny access
      if (hasExcludedRole && !teacherData.roles.some(role => !excludedRoles.includes(role.role_name))) {
        return false;
      }
    }
    
    // If allowedRoles is provided, check that user has at least one of those roles
    if (allowedRoles) {
      return teacherData.roles.some(role => 
        allowedRoles.includes(role.role_name)
      );
    }
    
    // If we're only using excludedRoles, and user doesn't have any excluded role, allow access
    return true;
  };

  return (
    <Route 
      path={path} 
      component={() => {
        // Show loading while teacher data is being fetched
        if (loading) {
          return <LoadingScreen message="Checking permissions..." />;
        }
        
        // Once loaded, check if user has permission
        if (hasPermission()) {
          return <Component />;
        } else {
          return <PermissionError excludedRoles={excludedRoles} allowedRoles={allowedRoles} />;
        }
      }} 
    />
  );
};

function Router() {
  return (
    <Switch>
      {/* Critical path routes - require normal user authentication */}
      <UserProtectedRoute path="/" component={ActivityList} name="root" />
      <UserProtectedRoute
        path="/activities"
        component={ActivityList}
        name="activities"
      />
      <UserProtectedRoute
        path="/activities/:id"
        component={ActivityDetail}
        name="activity-detail"
      />
      <UserProtectedRoute path="/profile" component={Profile} name="profile" />
      <UserProtectedRoute path="/edit-profile" component={EditProfile} name="edit-profile" />
      
      {/* Role-protected route - exclude Subject Teacher */}
      <RoleProtectedRoute 
        path="/reports" 
        component={Reports} 
        name="reports" 
        excludedRoles={["Subject Teacher"]} 
      />

      {/* Parent routes - require parent authentication */}
      <ParentProtectedRoute
        path="/parent-activity-form"
        component={ParentActivityForm}
        name="parent-form"
      />

      <ParentProtectedRoute
        path="/parent-reportview"
        component={ParentReportViewPage}
        name="parent-reportview"
      />
      {/* Public routes - no authentication required */}
      <TrackedRoute
        path="/login/parent/:id"
        component={ParentLogin}
        name="parent-login-with-id"
      />
      <TrackedRoute
        path="/login/parent"
        component={ParentLogin}
        name="parent-login"
      />
      <TrackedRoute path="/login/:id" component={Login} name="login-with-id" />
      <TrackedRoute path="/login" component={Login} name="login" />
      
      {/* Permission error route */}
      <TrackedRoute path="/permission-error" component={PermissionError} name="permission-error" />
      
      {/* Integration routes */}
      <TrackedRoute
        path="/canva/callback"
        component={CanvaCallback}
        name="canva-callback"
      />

      {/* Utility routes */}
      <Route path="/dashboard" component={DashboardRedirect} />

      {/* Fallback route */}
      <Route component={NotFound} />
    </Switch>
  );
}

// Enhanced app component with React.StrictMode disabled for performance
function App() {
  // Track when App component is mounted
  useEffect(() => {
    if (window.trackResourceLoaded) {
      window.trackResourceLoaded("App:mounted");
    }

    // Preserve QR URLs immediately when app loads (before any redirects)
    const preserveQRUrl = () => {
      const currentUrl = window.location.href;
      const hasTaskId = window.location.search.includes('task_id');
      const hasActivityPath = window.location.pathname.includes('/activities/');
      const isLoginPath = window.location.pathname.includes('/login');
      
      // If this looks like a QR code URL, preserve it for post-login redirect
      if ((hasTaskId || hasActivityPath) && !isLoginPath) {
        //console.log('App-level: Preserving QR URL before any redirects:', currentUrl);
        sessionStorage.setItem('postLoginRedirect', currentUrl);
      }
    };

    preserveQRUrl();

    return () => {
      if (window.trackResourceLoaded) {
        window.trackResourceLoaded("App:unmounted");
      }
    };
  }, []);

  return (
    <SimpleErrorBoundary message="We are having trouble processing your request. It might be a temporary issue.">
      <QueryClientProvider client={queryClient}>
        <TeacherProvider>
          <Suspense
            fallback={
              <div className="w-full h-screen flex items-center justify-center">
                {/* <LoadingRocket size="lg" text="Loading data..." /> */}
                <img src="/login/rocket.gif" alt="Loading" className="w-16 h-16" />
              </div>
            }
          >
            <Router />
          </Suspense>
          <Toaster />
        </TeacherProvider>
      </QueryClientProvider>
    </SimpleErrorBoundary>
  );
}

export default App;
