"use client";

import { useCallback, useEffect, useMemo, useRef, useState } 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 { Button } from "@/components/atoms/button";
import { AlertBanner } from "@/components/molecules/AlertBanner/AlertBanner";
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 { useActiveSubscriptions } from "@/features/subscriptions/hooks/useSubscriptions";
import { ACTIVE_INTERNET_SUBSCRIPTION_WARNING } from "@/features/checkout/constants";
import {
  useInternetEligibility,
  useRequestInternetEligibilityCheck,
} from "@/features/services/hooks/useInternetEligibility";
import {
  useResidenceCardVerification,
  useSubmitResidenceCard,
} from "@/features/verification/hooks/useResidenceCardVerification";
import { useAuthSession } from "@/features/auth/stores/auth.store";
import {
  ORDER_TYPE,
  type OrderTypeValue,
  toOrderTypeValueFromCheckout,
} from "@customer-portal/domain/orders";
import { buildPaymentMethodDisplay, formatAddressLabel } from "@/shared/utils";
import { CheckoutStatusBanners } from "./CheckoutStatusBanners";
import {
  PaymentMethodSection,
  IdentityVerificationSection,
  OrderSubmitSection,
} from "./checkout-sections";

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

  const { cartItem, checkoutSessionId, clear } = useCheckoutStore();

  const [submitting, setSubmitting] = useState(false);
  const [addressConfirmed, setAddressConfirmed] = useState(false);
  const [submitError, setSubmitError] = useState<string | null>(null);
  const [openingPaymentPortal, setOpeningPaymentPortal] = useState(false);
  const paymentToastTimeoutRef = useRef<number | null>(null);

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

  const isInternetOrder = orderType === ORDER_TYPE.INTERNET;

  // Active subscriptions check
  const { data: activeSubs } = useActiveSubscriptions();
  const hasActiveInternetSubscription = useMemo(() => {
    if (!Array.isArray(activeSubs)) return false;
    return activeSubs.some(
      subscription =>
        String(subscription.groupName || subscription.productName || "")
          .toLowerCase()
          .includes("internet") && String(subscription.status || "").toLowerCase() === "active"
    );
  }, [activeSubs]);

  const activeInternetWarning =
    isInternetOrder && hasActiveInternetSubscription ? ACTIVE_INTERNET_SUBSCRIPTION_WARNING : null;

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

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

  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;

  // Eligibility
  const eligibilityQuery = useInternetEligibility({ enabled: isInternetOrder });
  const eligibilityData = eligibilityQuery.data as
    | { eligibility?: string; status?: string; requestedAt?: string; notes?: string }
    | null
    | undefined;
  const eligibilityValue = eligibilityData?.eligibility;
  const eligibilityStatus = eligibilityData?.status;
  const eligibilityRequestedAt = eligibilityData?.requestedAt;
  const eligibilityNotes = eligibilityData?.notes;
  const eligibilityRequest = useRequestInternetEligibilityCheck();
  const eligibilityLoading = Boolean(isInternetOrder && eligibilityQuery.isLoading);
  const eligibilityNotRequested = Boolean(
    isInternetOrder && eligibilityQuery.isSuccess && eligibilityStatus === "not_requested"
  );
  const eligibilityPending = Boolean(
    isInternetOrder && eligibilityQuery.isSuccess && eligibilityStatus === "pending"
  );
  const eligibilityIneligible = Boolean(
    isInternetOrder && eligibilityQuery.isSuccess && eligibilityStatus === "ineligible"
  );
  const eligibilityError = Boolean(isInternetOrder && eligibilityQuery.isError);
  const isEligible =
    !isInternetOrder ||
    (eligibilityStatus === "eligible" &&
      typeof eligibilityValue === "string" &&
      eligibilityValue.trim().length > 0);

  // 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";

  // Toast handler
  const showPaymentToast = useCallback(
    (text: string, tone: "info" | "success" | "warning" | "error") => {
      if (paymentToastTimeoutRef.current) {
        clearTimeout(paymentToastTimeoutRef.current);
        paymentToastTimeoutRef.current = null;
      }
      paymentRefresh.setToast({ visible: true, text, tone });
      paymentToastTimeoutRef.current = window.setTimeout(() => {
        paymentRefresh.setToast(current => ({ ...current, visible: false }));
        paymentToastTimeoutRef.current = null;
      }, 2200);
    },
    [paymentRefresh]
  );

  useEffect(() => {
    return () => {
      if (paymentToastTimeoutRef.current) {
        clearTimeout(paymentToastTimeoutRef.current);
      }
    };
  }, []);

  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(() => {
    const params = new URLSearchParams(searchParams?.toString() ?? "");
    const type = (params.get("type") ?? "").toLowerCase();
    params.delete("type");
    const planSku = params.get("planSku")?.trim();
    if (!planSku) {
      params.delete("planSku");
    }

    if (type === "sim") {
      router.push(`/account/services/sim/configure?${params.toString()}`);
      return;
    }
    if (type === "internet" || type === "") {
      router.push(`/account/services/internet/configure?${params.toString()}`);
      return;
    }
    router.push("/account/services");
  }, [router, searchParams]);

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

    try {
      setSubmitting(true);
      const result = await ordersService.createOrderFromCheckoutSession(checkoutSessionId);
      clear();
      router.push(`/account/orders/${encodeURIComponent(result.sfOrderId)}?status=success`);
    } 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")
      ) {
        const next = `${pathname}${searchParams?.toString() ? `?${searchParams.toString()}` : ""}`;
        router.push(`/account/settings/verification?returnTo=${encodeURIComponent(next)}`);
        return;
      }
      setSubmitError(message);
    } finally {
      setSubmitting(false);
    }
  }, [checkoutSessionId, clear, pathname, router, searchParams]);

  const handleManagePayment = useCallback(async () => {
    if (openingPaymentPortal) return;
    setOpeningPaymentPortal(true);

    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";
      showPaymentToast(message, "error");
    } finally {
      setOpeningPaymentPortal(false);
    }
  }, [openingPaymentPortal, showPaymentToast]);

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

  // Calculate if form can be submitted
  const canSubmit =
    addressConfirmed &&
    !paymentMethodsLoading &&
    hasPaymentMethod &&
    residenceSubmitted &&
    isEligible &&
    !eligibilityLoading &&
    !eligibilityPending &&
    !eligibilityNotRequested &&
    !eligibilityIneligible &&
    !eligibilityError;

  // Error state - no cart item
  if (!cartItem || !orderType) {
    const shopHref = pathname.startsWith("/account") ? "/account/services" : "/services";
    return (
      <div className="max-w-2xl mx-auto py-8">
        <AlertBanner variant="error" title="Checkout Error" elevated>
          <div className="flex items-center justify-between">
            <span>Checkout data is not available</span>
            <Button as="a" href={shopHref} variant="link">
              Back to Services
            </Button>
          </div>
        </AlertBanner>
      </div>
    );
  }

  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: eligibilityLoading,
            isError: eligibilityError,
            isPending: eligibilityPending,
            isNotRequested: eligibilityNotRequested,
            isIneligible: eligibilityIneligible,
            notes: eligibilityNotes ?? null,
            requestedAt: eligibilityRequestedAt ?? null,
            refetch: () => void eligibilityQuery.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={() => setAddressConfirmed(true)}
                onAddressIncomplete={() => setAddressConfirmed(false)}
                orderType={orderType}
              />
            </SubCard>

            <PaymentMethodSection
              isLoading={paymentMethodsLoading}
              isError={!!paymentMethodsError}
              hasPaymentMethod={hasPaymentMethod}
              paymentMethodDisplay={paymentMethodDisplay}
              onManagePayment={() => void handleManagePayment()}
              onRefresh={() => void paymentRefresh.triggerRefresh()}
              isOpeningPortal={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={submitError}
          isSubmitting={submitting}
          canSubmit={canSubmit}
          onSubmit={() => void handleSubmitOrder()}
          onBack={navigateBackToConfigure}
        />
      </div>
    </PageLayout>
  );
}

export default AccountCheckoutContainer;
