"use client";

import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { usePathname, useSearchParams, useRouter } from "next/navigation";
import type { CartItem } from "@customer-portal/domain/checkout";
import type { CheckoutCartSummary, OrderTypeValue } from "@customer-portal/domain/orders";
import { toCheckoutOrderType } from "@customer-portal/domain/orders";
import { checkoutService } from "@/features/checkout/api/checkout.api";
import { CheckoutParamsService } from "@/features/checkout/api/checkout-params.api";
import { useCheckoutStore } from "@/features/checkout/stores/checkout.store";
import { AccountCheckoutContainer } from "@/features/checkout/components/AccountCheckoutContainer";
import { AlertBanner } from "@/components/molecules/AlertBanner/AlertBanner";
import { Button } from "@/components/atoms/button";
import { Spinner } from "@/components/atoms";
import { EmptyCartRedirect } from "@/features/checkout/components/EmptyCartRedirect";
import { useAuthSession, useAuthStore } from "@/features/auth/stores/auth.store";
import { logger } from "@/core/logger";

const signatureFromSearchParams = (params: URLSearchParams): string => {
  const entries = [...params.entries()].sort(([a], [b]) => a.localeCompare(b));
  return entries.map(([key, value]) => `${key}=${value}`).join("&");
};

const cartItemFromCheckoutCart = (
  cart: CheckoutCartSummary,
  orderType: OrderTypeValue
): CartItem => {
  const checkoutOrderType = toCheckoutOrderType(orderType);
  if (!checkoutOrderType) {
    throw new Error(`Unsupported order type: ${orderType}`);
  }
  const planItem = cart.items.find(item => item.itemType === "plan") ?? cart.items[0];
  const planSku = planItem?.sku;
  if (!planSku) {
    throw new Error("Checkout cart did not include a plan. Please re-select your plan.");
  }
  const addonSkus = [
    ...new Set(cart.items.map(item => item.sku).filter(sku => sku && sku !== planSku)),
  ];

  return {
    orderType: checkoutOrderType,
    planSku,
    planName: planItem?.name ?? planSku,
    addonSkus,
    configuration: {},
    pricing: {
      monthlyTotal: cart.totals.monthlyTotal,
      oneTimeTotal: cart.totals.oneTimeTotal,
      breakdown: cart.items.map(item => ({
        label: item.name,
        sku: item.sku,
        monthlyPrice: item.monthlyPrice,
        oneTimePrice: item.oneTimePrice,
        quantity: item.quantity,
      })),
    },
  };
};

export function CheckoutEntry() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const pathname = usePathname();
  const { isAuthenticated } = useAuthSession();
  const hasCheckedAuth = useAuthStore(state => state.hasCheckedAuth);
  const paramsKey = useMemo(() => searchParams.toString(), [searchParams]);
  const signature = useMemo(
    () => signatureFromSearchParams(new URLSearchParams(paramsKey)),
    [paramsKey]
  );

  const {
    cartItem,
    cartParamsSignature,
    checkoutSessionId,
    setCartItem,
    setCartItemFromParams,
    setCheckoutSession,
    isCartStale,
    clear,
  } = useCheckoutStore();

  const [status, setStatus] = useState<"idle" | "loading" | "error">("idle");
  const [errorMessage, setErrorMessage] = useState<string | null>(null);

  useEffect(() => {
    if (!paramsKey) {
      return;
    }

    let mounted = true;
    setStatus("loading");
    setErrorMessage(null);

    void (async () => {
      try {
        const snapshot = CheckoutParamsService.buildSnapshot(new URLSearchParams(paramsKey));
        if (snapshot.warnings.length > 0) {
          logger.warn("Checkout params normalization warnings", {
            warnings: snapshot.warnings,
          });
        }
        if (!snapshot.planReference) {
          throw new Error("No plan selected. Please go back and select a plan.");
        }

        const session = await checkoutService.createSession(
          snapshot.orderType,
          snapshot.selections,
          snapshot.configuration
        );
        if (!mounted) return;

        const nextCartItem = cartItemFromCheckoutCart(session.cart, session.orderType);
        setCartItemFromParams(nextCartItem, signature);
        setCheckoutSession({ id: session.sessionId, expiresAt: session.expiresAt });
        setStatus("idle");
      } catch (error) {
        if (!mounted) return;
        setStatus("error");
        setErrorMessage(error instanceof Error ? error.message : "Failed to load checkout");
      }
    })();

    return () => {
      mounted = false;
    };
  }, [paramsKey, setCartItemFromParams, setCheckoutSession, signature]);

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

    if (isCartStale()) {
      clear();
      return;
    }

    if (!checkoutSessionId) {
      return;
    }

    let mounted = true;
    setStatus("loading");
    setErrorMessage(null);

    void (async () => {
      try {
        const session = await checkoutService.getSession(checkoutSessionId);
        if (!mounted) return;
        setCheckoutSession({ id: session.sessionId, expiresAt: session.expiresAt });
        const nextCartItem = cartItemFromCheckoutCart(session.cart, session.orderType);
        // Session-based entry: don't tie progress to URL params.
        setCartItem(nextCartItem);
        setStatus("idle");
      } catch (error) {
        if (!mounted) return;
        setStatus("error");
        setErrorMessage(error instanceof Error ? error.message : "Failed to load checkout");
      }
    })();

    return () => {
      mounted = false;
    };
  }, [checkoutSessionId, clear, isCartStale, paramsKey, setCartItem, setCheckoutSession]);

  // Redirect unauthenticated users to login
  // Cart data is preserved in localStorage, so they can continue after logging in
  const shouldRedirectToLogin = !isAuthenticated && hasCheckedAuth;

  useEffect(() => {
    if (!shouldRedirectToLogin) return;

    const currentUrl = pathname + (paramsKey ? `?${paramsKey}` : "");
    const orderUrl = "/account/order" + (paramsKey ? `?${paramsKey}` : "");
    const returnTo = encodeURIComponent(pathname.startsWith("/account") ? currentUrl : orderUrl);
    router.replace(`/auth/login?returnTo=${returnTo}`);
  }, [shouldRedirectToLogin, pathname, paramsKey, router]);

  const shouldWaitForCart =
    (Boolean(paramsKey) && (!cartItem || cartParamsSignature !== signature)) ||
    (!paramsKey && Boolean(checkoutSessionId) && !cartItem);

  if (status === "loading" && shouldWaitForCart) {
    return (
      <div className="max-w-2xl mx-auto py-12">
        <div className="bg-card rounded-xl border border-border p-8 shadow-[var(--cp-shadow-1)] text-center">
          <Spinner className="mx-auto mb-4" />
          <p className="text-sm text-muted-foreground">Preparing your checkout…</p>
        </div>
      </div>
    );
  }

  if (status === "error") {
    const shopHref = pathname.startsWith("/account") ? "/account/services" : "/services";
    return (
      <div className="max-w-2xl mx-auto py-8">
        <AlertBanner variant="error" title="Unable to start checkout" elevated>
          <div className="space-y-3">
            <div className="text-sm text-foreground/80">{errorMessage}</div>
            <div className="flex flex-col sm:flex-row gap-3">
              <Button as="a" href={shopHref} size="sm">
                Back to Services
              </Button>
              <Link href="/contact" className="text-sm text-primary hover:underline self-center">
                Contact support
              </Link>
            </div>
          </div>
        </AlertBanner>
      </div>
    );
  }

  if (!paramsKey && !checkoutSessionId) {
    return <EmptyCartRedirect />;
  }

  if (shouldRedirectToLogin) {
    return (
      <div className="max-w-2xl mx-auto py-12">
        <div className="bg-card rounded-xl border border-border p-8 shadow-[var(--cp-shadow-1)] text-center">
          <Spinner className="mx-auto mb-4" />
          <p className="text-sm text-muted-foreground">Redirecting to sign in…</p>
        </div>
      </div>
    );
  }

  // Wait for auth check
  if (!hasCheckedAuth) {
    return (
      <div className="max-w-2xl mx-auto py-12">
        <div className="bg-card rounded-xl border border-border p-8 shadow-[var(--cp-shadow-1)] text-center">
          <Spinner className="mx-auto mb-4" />
          <p className="text-sm text-muted-foreground">Loading…</p>
        </div>
      </div>
    );
  }

  return <AccountCheckoutContainer />;
}
