"use client";

import { useCallback, useMemo } from "react";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { ShieldCheck } from "lucide-react";

import { PageLayout } from "@/components/templates/PageLayout";
import { SubCard } from "@/components/molecules/SubCard/SubCard";
import { InlineToast } from "@/components/atoms/inline-toast";
import { AddressConfirmation } from "@/features/services/components/base/AddressConfirmation";
import { useCheckoutStore } from "@/features/checkout/stores/checkout.store";
import { ordersService } from "@/features/orders/api/orders.api";
import { usePaymentMethods } from "@/features/billing/hooks/useBilling";
import { usePaymentRefresh } from "@/features/billing/hooks/usePaymentRefresh";
import { billingService } from "@/features/billing/api/billing.api";
import { openSsoLink } from "@/features/billing/utils/sso";
import {
  useResidenceCardVerification,
  useSubmitResidenceCard,
} from "@/features/verification/hooks/useResidenceCardVerification";
import { useAuthSession } from "@/features/auth/stores/auth.store";
import { toOrderTypeValueFromCheckout, type OrderTypeValue } from "@customer-portal/domain/orders";
import { buildPaymentMethodDisplay, formatAddressLabel } from "@/shared/utils";

import { CheckoutStatusBanners } from "./CheckoutStatusBanners";
import {
  PaymentMethodSection,
  IdentityVerificationSection,
  OrderSubmitSection,
} from "./checkout-sections";
import { CheckoutErrorFallback } from "./CheckoutErrorFallback";
import {
  useCheckoutEligibility,
  useCheckoutFormState,
  useCheckoutToast,
  useCanSubmit,
} from "@/features/checkout/hooks";
import {
  buildConfigureBackUrl,
  buildVerificationRedirectUrl,
  buildOrderSuccessUrl,
  getShopHref,
} from "@/features/checkout/utils";

export function AccountCheckoutContainer() {
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const { user } = useAuthSession();

  const { cartItem, checkoutSessionId } = useCheckoutStore();

  const orderType: OrderTypeValue | null = useMemo(() => {
    return toOrderTypeValueFromCheckout(cartItem?.orderType);
  }, [cartItem?.orderType]);

  // Form state management
  const {
    formState,
    confirmAddress,
    unconfirmAddress,
    startSubmitting,
    stopSubmitting,
    setError,
    startOpeningPortal,
    stopOpeningPortal,
  } = useCheckoutFormState();

  // Eligibility management
  const { eligibility, eligibilityRequest, activeInternetWarning } = useCheckoutEligibility({
    orderType,
  });

  // Payment methods
  const {
    data: paymentMethods,
    isLoading: paymentMethodsLoading,
    error: paymentMethodsError,
    refetch: refetchPaymentMethods,
  } = usePaymentMethods();

  const paymentRefresh = usePaymentRefresh({
    refetch: refetchPaymentMethods,
    attachFocusListeners: false,
  });

  const { showToast } = useCheckoutToast({ setToast: paymentRefresh.setToast });

  const paymentMethodList = paymentMethods?.paymentMethods ?? [];
  const hasPaymentMethod = paymentMethodList.length > 0;
  const defaultPaymentMethod =
    paymentMethodList.find(method => method.isDefault) ?? paymentMethodList[0] ?? null;
  const paymentMethodDisplay = defaultPaymentMethod
    ? buildPaymentMethodDisplay(defaultPaymentMethod)
    : null;

  // Address
  const hasServiceAddress = Boolean(
    user?.address?.address1 &&
    user?.address?.city &&
    user?.address?.postcode &&
    (user?.address?.country || user?.address?.countryCode)
  );
  const addressLabel = useMemo(() => formatAddressLabel(user?.address), [user?.address]);

  // Residence card verification
  const residenceCardQuery = useResidenceCardVerification();
  const submitResidenceCard = useSubmitResidenceCard();
  const residenceStatus = residenceCardQuery.data?.status;
  const residenceSubmitted = residenceStatus === "pending" || residenceStatus === "verified";

  // Can submit calculation
  const canSubmit = useCanSubmit(formState.addressConfirmed, {
    paymentMethodsLoading,
    hasPaymentMethod,
    residenceSubmitted,
    eligibility,
  });

  const formatDateTime = useCallback((iso?: string | null) => {
    if (!iso) return null;
    const date = new Date(iso);
    if (Number.isNaN(date.getTime())) return null;
    return new Intl.DateTimeFormat(undefined, { dateStyle: "medium", timeStyle: "short" }).format(
      date
    );
  }, []);

  const navigateBackToConfigure = useCallback(() => {
    router.push(buildConfigureBackUrl(searchParams));
  }, [router, searchParams]);

  const handleSubmitOrder = useCallback(async () => {
    setError(null);
    if (!checkoutSessionId) {
      setError("Checkout session expired. Please restart checkout from the shop.");
      return;
    }

    try {
      startSubmitting();
      const result = await ordersService.createOrderFromCheckoutSession(checkoutSessionId);
      // Note: Cart is cleared on the order detail page (OrderDetail.tsx) when status=success
      // This ensures the cart isn't cleared if navigation fails
      router.push(buildOrderSuccessUrl(result.sfOrderId));
    } catch (error) {
      const message = error instanceof Error ? error.message : "Order submission failed";
      if (
        message.toLowerCase().includes("residence card submission required") ||
        message.toLowerCase().includes("residence card submission was rejected")
      ) {
        router.push(buildVerificationRedirectUrl(pathname, searchParams));
        return;
      }
      setError(message);
    } finally {
      stopSubmitting();
    }
  }, [
    checkoutSessionId,
    pathname,
    router,
    searchParams,
    setError,
    startSubmitting,
    stopSubmitting,
  ]);

  const handleManagePayment = useCallback(async () => {
    if (formState.openingPaymentPortal) return;
    startOpeningPortal();

    try {
      const data = await billingService.createPaymentMethodsSsoLink();
      if (!data.url) {
        throw new Error("No payment portal URL returned");
      }
      openSsoLink(data.url, { newTab: true });
    } catch (error) {
      const message = error instanceof Error ? error.message : "Unable to open the payment portal";
      showToast(message, "error");
    } finally {
      stopOpeningPortal();
    }
  }, [formState.openingPaymentPortal, showToast, startOpeningPortal, stopOpeningPortal]);

  const handleSubmitResidenceCard = useCallback(
    (file: File) => {
      submitResidenceCard.mutate(file);
    },
    [submitResidenceCard]
  );

  // Error state - no cart item
  if (!cartItem || !orderType) {
    return <CheckoutErrorFallback shopHref={getShopHref(pathname)} />;
  }

  return (
    <PageLayout
      title="Checkout"
      description="Verify your address, review totals, and submit your order"
      icon={<ShieldCheck className="h-6 w-6" />}
    >
      <div className="max-w-2xl mx-auto space-y-8">
        <InlineToast
          visible={paymentRefresh.toast.visible}
          text={paymentRefresh.toast.text}
          tone={paymentRefresh.toast.tone}
        />

        <CheckoutStatusBanners
          activeInternetWarning={activeInternetWarning}
          eligibility={{
            isLoading: eligibility.isLoading,
            isError: eligibility.isError,
            isPending: eligibility.isPending,
            isNotRequested: eligibility.isNotRequested,
            isIneligible: eligibility.isIneligible,
            notes: eligibility.notes,
            requestedAt: eligibility.requestedAt,
            refetch: eligibility.refetch,
          }}
          eligibilityRequest={{
            isPending: eligibilityRequest.isPending,
            mutate: (data: {
              address?: Partial<NonNullable<typeof user>["address"]> | undefined;
              notes?: string | undefined;
            }) => {
              const { notes, address: addr } = data;
              eligibilityRequest.mutate({
                ...(addr !== undefined && { address: addr }),
                ...(notes !== undefined && { notes }),
              });
            },
          }}
          hasServiceAddress={hasServiceAddress}
          addressLabel={addressLabel}
          userAddress={user?.address ?? {}}
          planSku={cartItem.planSku}
        />

        <div className="bg-card border border-border rounded-2xl p-6 md:p-7 shadow-[var(--cp-shadow-1)]">
          <div className="flex items-center gap-3 mb-6">
            <ShieldCheck className="w-6 h-6 text-primary" />
            <h2 className="text-lg font-semibold text-foreground">Checkout requirements</h2>
          </div>

          <div className="space-y-5">
            <SubCard>
              <AddressConfirmation
                embedded
                onAddressConfirmed={confirmAddress}
                onAddressIncomplete={unconfirmAddress}
                orderType={orderType}
              />
            </SubCard>

            <PaymentMethodSection
              isLoading={paymentMethodsLoading}
              isError={!!paymentMethodsError}
              hasPaymentMethod={hasPaymentMethod}
              paymentMethodDisplay={paymentMethodDisplay}
              onManagePayment={() => void handleManagePayment()}
              onRefresh={() => void paymentRefresh.triggerRefresh()}
              isOpeningPortal={formState.openingPaymentPortal}
            />

            <IdentityVerificationSection
              isLoading={residenceCardQuery.isLoading}
              isError={residenceCardQuery.isError}
              status={residenceStatus}
              data={
                residenceCardQuery.data ?? {
                  submittedAt: null,
                  reviewedAt: null,
                  reviewerNotes: null,
                }
              }
              onRefetch={() => void residenceCardQuery.refetch()}
              onSubmitFile={handleSubmitResidenceCard}
              isSubmitting={submitResidenceCard.isPending}
              submitError={submitResidenceCard.error ?? null}
              formatDateTime={formatDateTime}
            />
          </div>
        </div>

        <OrderSubmitSection
          pricing={cartItem.pricing}
          submitError={formState.submitError}
          isSubmitting={formState.submitting}
          canSubmit={canSubmit}
          onSubmit={() => void handleSubmitOrder()}
          onBack={navigateBackToConfigure}
        />
      </div>
    </PageLayout>
  );
}

export default AccountCheckoutContainer;
