/**
 * GetStartedView - Main view for the get-started flow
 *
 * Supports multiple handoff scenarios from eligibility check:
 *
 * 1. Verified handoff (?verified=true):
 *    - User already completed OTP on eligibility page
 *    - SessionStorage has: sessionToken, accountStatus, prefill, email
 *    - Skip directly to complete-account step
 *
 * 2. Unverified handoff (?handoff=true):
 *    - User came from eligibility check success page or SF email
 *    - Email is pre-filled but NOT verified yet
 *    - User must complete OTP verification
 *    - SessionStorage may have: handoff-token for prefill data
 */

"use client";

import { useState, useCallback, useEffect } from "react";
import { useSearchParams } from "next/navigation";
import { AuthLayout } from "@/components/templates/AuthLayout";
import { GetStartedForm } from "../components";
import { getSafeRedirect } from "@/features/auth/utils/route-protection";
import {
  useGetStartedStore,
  type GetStartedStep,
  type GetStartedAddress,
} from "../stores/get-started.store";
import type { AccountStatus, VerifyCodeResponse } from "@customer-portal/domain/get-started";

// Session data staleness threshold (5 minutes)
const SESSION_STALE_THRESHOLD_MS = 5 * 60 * 1000;

// SessionStorage key constants
const SESSION_KEY_TOKEN = "get-started-session-token";
const SESSION_KEY_ACCOUNT_STATUS = "get-started-account-status";
const SESSION_KEY_PREFILL = "get-started-prefill";
const SESSION_KEY_EMAIL = "get-started-email";
const SESSION_KEY_TIMESTAMP = "get-started-timestamp";
const SESSION_KEY_HANDOFF_TOKEN = "get-started-handoff-token";

function clearGetStartedSessionStorage(): void {
  sessionStorage.removeItem(SESSION_KEY_TOKEN);
  sessionStorage.removeItem(SESSION_KEY_ACCOUNT_STATUS);
  sessionStorage.removeItem(SESSION_KEY_PREFILL);
  sessionStorage.removeItem(SESSION_KEY_EMAIL);
  sessionStorage.removeItem(SESSION_KEY_TIMESTAMP);
  sessionStorage.removeItem(SESSION_KEY_HANDOFF_TOKEN);
}

interface SessionData {
  sessionToken: string | null;
  accountStatus: string | null;
  prefillRaw: string | null;
  email: string | null;
  timestamp: string | null;
}

function readVerifiedHandoffData(): SessionData {
  return {
    sessionToken: sessionStorage.getItem(SESSION_KEY_TOKEN),
    accountStatus: sessionStorage.getItem(SESSION_KEY_ACCOUNT_STATUS),
    prefillRaw: sessionStorage.getItem(SESSION_KEY_PREFILL),
    email: sessionStorage.getItem(SESSION_KEY_EMAIL),
    timestamp: sessionStorage.getItem(SESSION_KEY_TIMESTAMP),
  };
}

function isSessionStale(timestamp: string | null): boolean {
  if (!timestamp) return true;
  return Date.now() - Number.parseInt(timestamp, 10) > SESSION_STALE_THRESHOLD_MS;
}

function parsePrefillData(prefillRaw: string | null): VerifyCodeResponse["prefill"] | null {
  if (!prefillRaw) return null;
  try {
    return JSON.parse(prefillRaw);
  } catch {
    return null;
  }
}

export function GetStartedView(): React.JSX.Element {
  const searchParams = useSearchParams();
  const {
    updateFormData,
    goToStep,
    setHandoffToken,
    setSessionToken,
    setAccountStatus,
    setPrefill,
    setRedirectTo,
  } = useGetStartedStore();
  const [meta, setMeta] = useState({
    title: "Get Started",
    subtitle: "Enter your email to begin",
  });
  const [initialized, setInitialized] = useState(false);

  useEffect(() => {
    if (initialized) return;

    handleRedirectParam();
    const handledVerified = handleVerifiedHandoff();
    if (!handledVerified) {
      handleUnverifiedHandoff();
    }
    setInitialized(true);

    function handleRedirectParam(): void {
      const redirectParam = searchParams.get("redirect");
      if (redirectParam) {
        const safeRedirect = getSafeRedirect(redirectParam, "/account/dashboard");
        setRedirectTo(safeRedirect);
      }
    }

    function handleVerifiedHandoff(): boolean {
      const verifiedParam = searchParams.get("verified");
      if (verifiedParam !== "true") return false;

      const sessionData = readVerifiedHandoffData();
      clearGetStartedSessionStorage();

      if (!sessionData.sessionToken || isSessionStale(sessionData.timestamp)) {
        return false;
      }

      setSessionToken(sessionData.sessionToken);
      if (sessionData.accountStatus) {
        setAccountStatus(sessionData.accountStatus as AccountStatus);
      }

      const prefill = parsePrefillData(sessionData.prefillRaw);
      if (prefill) {
        setPrefill(prefill);
        updateFormData({
          email: sessionData.email || prefill.email || "",
          firstName: prefill.firstName || "",
          lastName: prefill.lastName || "",
          phone: prefill.phone || "",
          address: (prefill.address as GetStartedAddress) || {},
        });
      } else if (sessionData.email) {
        updateFormData({ email: sessionData.email });
      }

      goToStep("complete-account");
      return true;
    }

    function handleUnverifiedHandoff(): void {
      const emailParam = searchParams.get("email");
      const handoffParam = searchParams.get("handoff");
      const storedHandoffToken = sessionStorage.getItem(SESSION_KEY_HANDOFF_TOKEN);
      const storedEmail = sessionStorage.getItem(SESSION_KEY_EMAIL);

      sessionStorage.removeItem(SESSION_KEY_HANDOFF_TOKEN);
      sessionStorage.removeItem(SESSION_KEY_EMAIL);

      const email = emailParam || storedEmail;
      const isHandoff = handoffParam === "true" || !!storedHandoffToken;

      if (email && isHandoff) {
        updateFormData({ email });
        if (storedHandoffToken) {
          setHandoffToken(storedHandoffToken);
        }
      } else if (email) {
        updateFormData({ email });
      }
    }
  }, [
    initialized,
    searchParams,
    updateFormData,
    setHandoffToken,
    goToStep,
    setSessionToken,
    setAccountStatus,
    setPrefill,
    setRedirectTo,
  ]);

  const handleStepChange = useCallback(
    (_step: GetStartedStep, stepMeta: { title: string; subtitle: string }) => {
      setMeta(stepMeta);
    },
    []
  );

  return (
    <AuthLayout title={meta.title} subtitle={meta.subtitle} wide>
      <GetStartedForm onStepChange={handleStepChange} />
    </AuthLayout>
  );
}

export default GetStartedView;
