export const runtime = "nodejs";
import type { GetServerSidePropsContext } from "next";
import { getServerSession } from "next-auth";
import { useSession } from "next-auth/react";
import type { Session } from "next-auth";
import { authOptions } from "@/lib/auth";
import SessionHelper from "@/lib/SessionHelper";

import Headline, { PageState } from "@/components/Headline";
import HomePage from "../components/webpage/Home";
import ProfilPage from "../components/Profil/Profil";
import Webpage from "../components/Webpage";
import LoginRequiredPopup from "@/components/LoginRequiredPopup";
import { useRouter } from "next/router";
import { useCallback, useEffect, useState } from "react";

export async function getServerSideProps(context: GetServerSidePropsContext) {
  const session = await getServerSession(context.req, context.res, authOptions);

  const safeSession = session
    ? {
        ...session,
        user: {
          id: session.user?.id ?? null,
          name: session.user?.name ?? null,
          email: session.user?.email ?? null,
          image: session.user?.image ?? null,
        },
      }
    : null;

  // Server-side Abkürzung: Wenn bereits eingeloggt und postLoginAction=startSession,
  // erstelle die Session sofort und leite direkt weiter.
  const actionParam = context.query.postLoginAction;
  const postLoginAction = Array.isArray(actionParam) ? actionParam[0] : actionParam;

  if (postLoginAction === "startSession" && safeSession?.user?.id) {
    try {
      const newSession = await SessionHelper.createSession(
        Number(safeSession.user.id)
      );
      return {
        redirect: {
          destination: `/session/${newSession.Session_Code}`,
          permanent: false,
        },
      };
    } catch (err) {
      console.error("SSR create session failed", err);
      // fällt durch und rendert Seite mit Popup; Client-Flow übernimmt
    }
  }

  return {
    props: {
      session: safeSession,
    },
  };
}

const buildCallbackUrl = (
  asPath: string,
  action?: "startSession" | "profile" | null
) => {
  const [pathname, rawQuery] = (asPath || "/").split("?");
  const params = new URLSearchParams(rawQuery ?? "");

  if (action) {
    params.set("postLoginAction", action);
  } else {
    params.delete("postLoginAction");
  }

  const query = params.toString();
  return query ? `${pathname}?${query}` : pathname;
};

function Home({ session }: { session?: Session | null }) {
  const router = useRouter();
  const { data: clientSession } = useSession();
  const displaySession = clientSession ?? session ?? null;
  const isAuthenticated = !!displaySession?.user;

  const [pageState, setPageState] = useState<PageState>(PageState.Start);
  const [showLoginPopup, setShowLoginPopup] = useState(false);
  const [pendingLoginAction, setPendingLoginAction] = useState<
    "startSession" | "profile" | null
  >(null);
  const [hasProcessedPostLoginAction, setHasProcessedPostLoginAction] =
    useState(false);

  useEffect(() => {
    if (!isAuthenticated && pageState !== PageState.Start) {
      setPageState(PageState.Start);
    }
  }, [isAuthenticated, pageState]);

  const handleRequireLogin = (action?: "startSession" | "profile") => {
    setPendingLoginAction(action ?? null);
    setHasProcessedPostLoginAction(false);
    setShowLoginPopup(true);
  };

  const handleChangePage = (page: PageState) => {
    if (page === PageState.Profil && !isAuthenticated) {
      handleRequireLogin("profile");
      return;
    }
    setPageState(page);
  };

  const clearPostLoginAction = useCallback(() => {
    if (!router.isReady) return;
    const rest = { ...router.query };
    delete rest.postLoginAction;
    setHasProcessedPostLoginAction(false);
    router.replace({ pathname: router.pathname, query: rest }, undefined, {
      shallow: true,
    });
  }, [router, setHasProcessedPostLoginAction]);

  const startSessionAfterLogin = useCallback(async () => {
    try {
      const res = await fetch("/api/ws/new", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
      });

      if (!res.ok) {
        const json = await res.json().catch(() => null);
        throw new Error(json?.message ?? "Fehler beim Starten der Session");
      }

      const { sessionCode } = await res.json();
      await router.push(
        { pathname: "/session", query: { id: sessionCode } },
        `/session/${sessionCode}`
      );
    } catch (err) {
      console.error("Konnte Session nach Login nicht starten", err);
    } finally {
      clearPostLoginAction();
    }
  }, [clearPostLoginAction, router]);

  useEffect(() => {
    if (!router.isReady || !isAuthenticated || hasProcessedPostLoginAction) {
      return;
    }

    const actionParam = router.query.postLoginAction;
    const action = Array.isArray(actionParam) ? actionParam[0] : actionParam;
    if (!action) return;

    if (action === "startSession") {
      setHasProcessedPostLoginAction(true);
      startSessionAfterLogin();
    } else if (action === "profile") {
      setHasProcessedPostLoginAction(true);
      setPageState(PageState.Profil);
      clearPostLoginAction();
    } else {
      clearPostLoginAction();
    }
  }, [
    clearPostLoginAction,
    hasProcessedPostLoginAction,
    isAuthenticated,
    router.isReady,
    router.query.postLoginAction,
    startSessionAfterLogin,
  ]);

  return (
    <Webpage>
      <Headline
        pageState={pageState}
        onChangePage={handleChangePage}
        isAuthenticated={isAuthenticated}
      />

      {pageState === PageState.Start && (
        <HomePage
          isAuthenticated={isAuthenticated}
          onRequireLogin={handleRequireLogin}
        />
      )}

      {pageState === PageState.Profil && isAuthenticated && <ProfilPage />}

      <LoginRequiredPopup
        open={showLoginPopup}
        onClose={() => {
          setShowLoginPopup(false);
          setPendingLoginAction(null);
        }}
        callbackUrl={buildCallbackUrl(
          router.asPath ?? "/",
          pendingLoginAction
        )}
      />
    </Webpage>
  );
}

export default Home;
