import storeConfig from "discovery.config";

import { OrderEntryLayout } from "../features/order-entry/layouts/OrderEntryLayout";
import { withErrorBoundary } from "../features/shared/components";
import { LOCALIZATION_ENTRY_IDS } from "../features/shared/localization/constants";
import { LocalizationProvider } from "../features/shared/localization/LocalizationContext";
import { getLocalizationLabelsService } from "../features/shared/localization/services/get-localization-labels.service";
import { validateOrderEntryAccessService } from "../features/shared/services";
import {
  withAuthLoader,
  withLoaderErrorBoundary,
} from "../features/shared/utils";

import type { LabelMap } from "../features/shared/localization/types";
import type { AuthRouteProps, LoaderData } from "../features/shared/types";

/**
 * Extracts the VTEX auth token value from a Cookie header string.
 * Returns only the cookie VALUE (JWT), never "CookieName=value".
 */
const getAuthCookieInfo = (
  cookieHeader: string
): {
  token: string;
  accountFromCookie?: string;
  session?: string;
  segment?: string;
} => {
  if (!cookieHeader) return { token: "" };

  const session = cookieHeader.match(/vtex_session=([^;]+)/);

  const segment = cookieHeader.match(/vtex_segment=([^;]+)/);

  // VtexIdclientAutCookie_<account>=<value>
  const authCookieRegex = cookieHeader.match(
    /VtexIdclientAutCookie_([a-zA-Z0-9-]+)=([^;]+)/
  );
  if (authCookieRegex?.[2])
    return {
      accountFromCookie: authCookieRegex[1],
      token: authCookieRegex[2],
      segment: segment?.[1] ?? "",
      session: session?.[1] ?? "",
    };

  // fallback: VtexIdclientAutCookie=<value>
  const fallBackAuthCookieRegex = cookieHeader.match(
    /VtexIdclientAutCookie=([^;]+)/
  );
  if (fallBackAuthCookieRegex?.[1])
    return {
      token: fallBackAuthCookieRegex[1],
      segment: segment?.[1] ?? "",
      session: session?.[1] ?? "",
    };

  return { token: "" };
};

type OrderEntryPageQuery = Record<string, never>;

type OrderEntryPageData = { localizationLabels: LabelMap };

const loaderFunction = async (
  data: LoaderData<OrderEntryPageQuery>
): Promise<AuthRouteProps<OrderEntryPageData>> => {
  return withAuthLoader(
    data,
    async () => {
      const localizationLabels = await getLocalizationLabelsService({
        entryIds: LOCALIZATION_ENTRY_IDS.orderEntry,
        locale: data.locale,
      });

      return { localizationLabels };
    },
    { validateAccess: validateOrderEntryAccessService }
  );
};

export const loader = withLoaderErrorBoundary(loaderFunction, {
  componentName: "OrderEntryPage",
  redirectToError: true,
});

const OrderEntryPage = (props: AuthRouteProps<OrderEntryPageData>) => {
  if (!props.authorized) return null;

  const cookieHeader = props.clientContext?.cookie ?? "";
  const tokenFromContext = props.clientContext?.vtexIdclientAutCookie ?? "";

  const {
    token: tokenFromCookie,
    accountFromCookie,
    segment,
    session,
  } = getAuthCookieInfo(cookieHeader);

  // Prefer a token-like value if available; otherwise extract from cookie header.
  const vtexIdclientAutCookie =
    tokenFromContext && !tokenFromContext.includes("=")
      ? tokenFromContext
      : tokenFromCookie;

  if (!vtexIdclientAutCookie) {
    throw new Error("Missing VTEX auth token for B2B Agent iframe");
  }

  // account/locale via discovery.config (recomendado)
  const account = storeConfig?.api?.storeId ?? accountFromCookie ?? "";
  const locale = storeConfig?.session?.locale ?? "en-US";

  const customerId = props.clientContext?.customerId;
  const userId = props.clientContext?.userId;

  return (
    <LocalizationProvider labels={props.data?.localizationLabels ?? {}}>
      <OrderEntryLayout
        vtexIdclientAutCookie={vtexIdclientAutCookie}
        vtexIdclientAutCookie_client={vtexIdclientAutCookie}
        segment={segment}
        session={session}
        account={account}
        locale={locale}
        customerId={customerId}
        userId={userId}
      />
    </LocalizationProvider>
  );
};

export default withErrorBoundary(OrderEntryPage, {
  onError: (error) => {
    console.error("onError", error);
  },
  tags: {
    component: "OrderEntryPage",
    errorType: "order_entry_error",
  },
});
