import "@shopify/ui-extensions/preact";
import { render } from "preact";
import { useEffect, useRef, useState } from "preact/hooks";
import {
  useApplyDiscountCodeChange,
  useAttributes,
  useApi,
  useAppliedGiftCards,
  useBuyerJourneyActiveStep,
  useBuyerJourneyIntercept,
  useCartLines,
  useCheckoutToken,
  useCurrency,
  useDiscountCodes,
  useLanguage,
  useLocalizationCountry,
  useNote,
  useShippingAddress,
  useShop,
} from "@shopify/ui-extensions/checkout/preact";
import { BACKEND_URL_FROM_ENV } from "./backend-url.generated";

const INSTANCE_KEY_PREFIX = "__discount_banner_test_primary_instance__";
const CONFLICT_RESOLUTION_LOCK_KEY = `${INSTANCE_KEY_PREFIX}:discount-gift-card-conflict`;
const EXTENSION_SOURCE = "discount-banner-test";
const EXTENSION_TARGET = "purchase.checkout.reductions.render-after";
const VALIDATION_PENDING_MESSAGE =
  "Validating discount code. Please wait a moment.";
const VALIDATION_ERROR_MESSAGE =
  "We couldn't validate this discount code. Please remove it or try again.";
const REMOVING_DISCOUNT_MESSAGE =
  "Removing a discount code that isn't allowed for this checkout.";
const GIFT_CARD_VALIDATION_PENDING_MESSAGE =
  "Validating gift card. Please wait a moment.";
const REMOVING_GIFT_CARD_MESSAGE =
  "Removing a gift card that isn't allowed for this checkout.";
const DISCOUNT_GIFT_CARD_CONFLICT_MESSAGE =
  "You can use either a discount code or a gift card, but not both at the same time.";
const DISCOUNT_BLOCKED_BY_GIFT_CARD_MESSAGE =
  "A gift card is already applied, so discount codes can't be used at the same time.";
const GIFT_CARD_BLOCKED_BY_DISCOUNT_MESSAGE =
  "A discount code is already applied, so gift cards can't be used at the same time.";

function toSerializable(value, seen = new WeakSet(), depth = 0) {
  if (
    value == null ||
    typeof value === "string" ||
    typeof value === "number" ||
    typeof value === "boolean"
  ) {
    return value ?? null;
  }

  if (typeof value === "function" || typeof value === "symbol") {
    return undefined;
  }

  if (depth > 6) {
    return "[Max depth reached]";
  }

  if (typeof value === "object") {
    if (seen.has(value)) {
      return "[Circular]";
    }

    seen.add(value);

    if (Array.isArray(value)) {
      return value.map((item) => toSerializable(item, seen, depth + 1));
    }

    return Object.entries(value).reduce((result, [key, entry]) => {
      const serialized = toSerializable(entry, seen, depth + 1);
      if (serialized !== undefined) {
        result[key] = serialized;
      }

      return result;
    }, {});
  }

  return String(value);
}

function serializeCartLine(line) {
  const merchandise = line.merchandise;

  return {
    id: line.id,
    quantity: line.quantity,
    cost: toSerializable(line.cost),
    attributes: toSerializable(line.attributes ?? []),
    discountAllocations: toSerializable(line.discountAllocations ?? []),
    lineComponents: toSerializable(line.lineComponents ?? []),
    parentRelationship: toSerializable(line.parentRelationship),
    merchandise: merchandise
      ? {
          id: merchandise.id || null,
          type: merchandise.type || null,
          title: merchandise.title || null,
          subtitle: merchandise.subtitle || null,
          sku: merchandise.sku || null,
          requiresShipping: merchandise.requiresShipping ?? null,
          image: toSerializable(merchandise.image),
          selectedOptions: toSerializable(merchandise.selectedOptions ?? []),
          sellingPlan: toSerializable(merchandise.sellingPlan),
          product: merchandise.product
            ? {
                id: merchandise.product.id || null,
                vendor: merchandise.product.vendor || null,
                productType: merchandise.product.productType || null,
              }
            : null,
        }
      : null,
    raw: toSerializable(line),
  };
}

export default function () {
  render(<Extension />, document.body);
}

async function logEvent(shop, level, eventType, message, payload = {}) {
  const backendUrl = String(BACKEND_URL_FROM_ENV || "")
    .trim()
    .replace(/\/$/, "");
  if (!backendUrl || !shop) return;

  try {
    await fetch(`${backendUrl}/api/app-event-log`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        shop,
        source: EXTENSION_SOURCE,
        extensionTarget: payload.extensionTarget ?? EXTENSION_TARGET,
        level,
        eventType,
        message,
        checkoutToken: payload.checkoutToken ?? null,
        customerEmail: payload.customerEmail ?? null,
        customerName: payload.customerName ?? null,
        customerId: payload.customerId ?? null,
        payload,
      }),
    });
  } catch (error) {
    console.error("Discount banner log failed", error);
  }
}

function Extension() {
  const api = useApi();
  const extensionTarget = api?.extension?.target || EXTENSION_TARGET;
  const instanceKey = `${INSTANCE_KEY_PREFIX}:${extensionTarget}`;
  const [isPrimaryInstance] = useState(() => {
    if (globalThis[instanceKey]) {
      return false;
    }

    globalThis[instanceKey] = true;
    return true;
  });
  const discountCodes = useDiscountCodes();
  const appliedGiftCards = useAppliedGiftCards();
  const cartLines = useCartLines();
  const shop = useShop();
  const checkoutToken = useCheckoutToken();
  const activeStep = useBuyerJourneyActiveStep();
  const shippingAddress = useShippingAddress();
  const attributes = useAttributes();
  const note = useNote();
  const language = useLanguage();
  const currency = useCurrency();
  const country = useLocalizationCountry();
  const applyDiscountCodeChange = useApplyDiscountCodeChange();
  const applyGiftCardChange = api?.applyGiftCardChange;
  const [bannerMessage, setBannerMessage] = useState("");
  const [giftCardBannerMessage, setGiftCardBannerMessage] = useState("");
  const [validatedCodesKey, setValidatedCodesKey] = useState("");
  const [validatedGiftCardsKey, setValidatedGiftCardsKey] = useState("");
  const [isValidating, setIsValidating] = useState(false);
  const [isGiftCardValidating, setIsGiftCardValidating] = useState(false);
  const [isRemovingDiscount, setIsRemovingDiscount] = useState(false);
  const [isRemovingGiftCard, setIsRemovingGiftCard] = useState(false);
  const [conflictMessage, setConflictMessage] = useState("");
  const [isResolvingConflict, setIsResolvingConflict] = useState(false);
  const [exclusiveDiscountOrGiftCard, setExclusiveDiscountOrGiftCard] =
    useState(false);
  const previousAppliedCodesRef = useRef([]);
  const previousAppliedGiftCardsRef = useRef([]);
  const previousConflictCodesRef = useRef([]);
  const previousConflictGiftCardsRef = useRef([]);
  const customer = api?.buyerIdentity?.customer?.value;
  const customerEmail = api?.buyerIdentity?.email?.value || customer?.email;
  const customerName =
    customer?.fullName ||
    [customer?.firstName, customer?.lastName].filter(Boolean).join(" ") ||
    null;
  const customerId = customer?.id || null;

  const appliedCodes = discountCodes
    .map((entry) => entry?.code)
    .filter(Boolean);
  const appliedGiftCardCodes = appliedGiftCards
    .map((entry) => entry?.lastCharacters)
    .filter(Boolean);
  const appliedCodesKey = appliedCodes
    .map((code) => String(code).trim().toUpperCase())
    .filter(Boolean)
    .sort()
    .join("|");
  const appliedGiftCardsKey = appliedGiftCardCodes
    .map((code) => String(code).trim().toUpperCase())
    .filter(Boolean)
    .sort()
    .join("|");
  const currentCodesValidated = appliedCodesKey === validatedCodesKey;
  const currentGiftCardsValidated =
    appliedGiftCardsKey === validatedGiftCardsKey;
  const checkoutData = {
    checkoutToken,
    activeStep: activeStep?.handle || activeStep?.id || null,
    discountCodeCount: appliedCodes.length,
    discountCodes: appliedCodes,
    giftCardCount: appliedGiftCardCodes.length,
    giftCards: appliedGiftCards.map((giftCard) => ({
      lastCharacters: giftCard?.lastCharacters || null,
      amountUsed: toSerializable(giftCard?.amountUsed),
      balance: toSerializable(giftCard?.balance),
    })),
    note: note || null,
    attributes: Array.isArray(attributes)
      ? attributes.map((attribute) => ({
          key: attribute.key,
          value: attribute.value,
        }))
      : [],
    language: language?.isoCode || language?.name || null,
    currency: currency?.isoCode || null,
    country: country?.isoCode || country?.name || null,
    lineCount: cartLines.length,
    lines: cartLines.map(serializeCartLine),
    shippingAddress: shippingAddress
      ? {
          firstName: shippingAddress.firstName || null,
          lastName: shippingAddress.lastName || null,
          company: shippingAddress.company || null,
          address1: shippingAddress.address1 || null,
          address2: shippingAddress.address2 || null,
          city: shippingAddress.city || null,
          provinceCode: shippingAddress.provinceCode || null,
          zip: shippingAddress.zip || null,
          countryCode: shippingAddress.countryCode || null,
          phone: shippingAddress.phone || null,
        }
      : null,
  };

  useEffect(() => {
    return () => {
      if (isPrimaryInstance) {
        delete globalThis[instanceKey];
      }
    };
  }, [instanceKey, isPrimaryInstance]);

  useEffect(() => {
    void loadGiftCardConfig();
  }, [shop.myshopifyDomain]);

  useEffect(() => {
    void validateBlockedCodes();
  }, [appliedCodes.join(","), shop.myshopifyDomain]);

  useEffect(() => {
    void validateGiftCards();
  }, [appliedGiftCardCodes.join(","), shop.myshopifyDomain]);

  useEffect(() => {
    void resolveDiscountGiftCardConflict();
  }, [
    appliedCodesKey,
    appliedGiftCardsKey,
    isPrimaryInstance,
    exclusiveDiscountOrGiftCard,
  ]);

  useEffect(() => {
    if (!isPrimaryInstance || !shop.myshopifyDomain) return;

    const previousCodes = previousAppliedCodesRef.current;
    const addedCodes = appliedCodes.filter(
      (code) => !previousCodes.includes(code),
    );
    const removedCodes = previousCodes.filter(
      (code) => !appliedCodes.includes(code),
    );

    for (const code of addedCodes) {
      void logEvent(
        shop.myshopifyDomain,
        "info",
        "discount_code_applied",
        "Discount code was applied at checkout.",
        {
          code,
          appliedCodes,
          extensionTarget,
          checkoutToken,
          customerEmail,
          customerName,
          customerId,
          checkoutData,
        },
      );
    }

    for (const code of removedCodes) {
      void logEvent(
        shop.myshopifyDomain,
        "info",
        "discount_code_removed",
        "Discount code was removed from checkout.",
        {
          code,
          appliedCodes,
          extensionTarget,
          checkoutToken,
          customerEmail,
          customerName,
          customerId,
          checkoutData,
        },
      );
    }

    previousAppliedCodesRef.current = appliedCodes;
  }, [appliedCodes.join(","), isPrimaryInstance, shop.myshopifyDomain]);

  useEffect(() => {
    if (!isPrimaryInstance || !shop.myshopifyDomain) return;

    const previousGiftCards = previousAppliedGiftCardsRef.current;
    const addedGiftCards = appliedGiftCardCodes.filter(
      (code) => !previousGiftCards.includes(code),
    );
    const removedGiftCards = previousGiftCards.filter(
      (code) => !appliedGiftCardCodes.includes(code),
    );

    for (const code of addedGiftCards) {
      void logEvent(
        shop.myshopifyDomain,
        "info",
        "gift_card_applied",
        "Gift card was applied at checkout.",
        {
          code,
          appliedGiftCards: appliedGiftCardCodes,
          extensionTarget,
          checkoutToken,
          customerEmail,
          customerName,
          customerId,
          checkoutData,
        },
      );
    }

    for (const code of removedGiftCards) {
      void logEvent(
        shop.myshopifyDomain,
        "info",
        "gift_card_removed",
        "Gift card was removed from checkout.",
        {
          code,
          appliedGiftCards: appliedGiftCardCodes,
          extensionTarget,
          checkoutToken,
          customerEmail,
          customerName,
          customerId,
          checkoutData,
        },
      );
    }

    previousAppliedGiftCardsRef.current = appliedGiftCardCodes;
  }, [appliedGiftCardCodes.join(","), isPrimaryInstance, shop.myshopifyDomain]);

  useBuyerJourneyIntercept(({ canBlockProgress }) => {
    if (!canBlockProgress) {
      return { behavior: "allow" };
    }

    if (
      exclusiveDiscountOrGiftCard &&
      (isResolvingConflict ||
        conflictMessage ||
        (appliedCodes.length && appliedGiftCardCodes.length))
    ) {
      return {
        behavior: "block",
        reason: "discount_code_gift_card_conflict",
        errors: [
          {
            message: conflictMessage || DISCOUNT_GIFT_CARD_CONFLICT_MESSAGE,
            target: "$.cart",
          },
        ],
      };
    }

    if (
      appliedCodes.length &&
      (isValidating || isRemovingDiscount || !currentCodesValidated)
    ) {
      return {
        behavior: "block",
        reason: "discount_code_validation_pending",
        errors: [
          {
            message: isRemovingDiscount
              ? REMOVING_DISCOUNT_MESSAGE
              : VALIDATION_PENDING_MESSAGE,
            target: "$.cart",
          },
        ],
      };
    }

    if (
      appliedGiftCardCodes.length &&
      (isGiftCardValidating ||
        isRemovingGiftCard ||
        !currentGiftCardsValidated)
    ) {
      return {
        behavior: "block",
        reason: "gift_card_validation_pending",
        errors: [
          {
            message: isRemovingGiftCard
              ? REMOVING_GIFT_CARD_MESSAGE
              : GIFT_CARD_VALIDATION_PENDING_MESSAGE,
            target: "$.cart",
          },
        ],
      };
    }

    if (bannerMessage) {
      return {
        behavior: "block",
        reason: "blocked_discount_code_present",
        errors: [
          {
            message: bannerMessage,
            target: "$.cart",
          },
        ],
      };
    }

    if (giftCardBannerMessage) {
      return {
        behavior: "block",
        reason: "blocked_gift_card_present",
        errors: [
          {
            message: giftCardBannerMessage,
            target: "$.cart",
          },
        ],
      };
    }

    return { behavior: "allow" };
  });

  async function loadGiftCardConfig() {
    const backendUrl = String(BACKEND_URL_FROM_ENV || "")
      .trim()
      .replace(/\/$/, "");

    if (!backendUrl || !shop.myshopifyDomain) return;

    try {
      const response = await fetch(
        `${backendUrl}/api/gift-card-config?shop=${encodeURIComponent(
          shop.myshopifyDomain,
        )}`,
      );

      if (!response.ok) {
        console.error(
          "Gift card config request failed",
          await response.text(),
        );
        void logEvent(
          shop.myshopifyDomain,
          "error",
          "gift_card_config_error",
          "Gift card config request failed.",
          {
            extensionTarget,
            checkoutToken,
            customerEmail,
            customerName,
            customerId,
          },
        );
        return;
      }

      const json = await response.json();
      setExclusiveDiscountOrGiftCard(
        Boolean(json?.exclusiveDiscountOrGiftCard),
      );
    } catch (error) {
      console.error("Gift card config error", error);
      void logEvent(
        shop.myshopifyDomain,
        "error",
        "gift_card_config_error",
        error instanceof Error
          ? error.message
          : "Unknown gift card config error.",
        {
          extensionTarget,
          checkoutToken,
          customerEmail,
          customerName,
          customerId,
        },
      );
    }
  }

  async function resolveDiscountGiftCardConflict() {
    if (!isPrimaryInstance) return;

    const previousCodes = previousConflictCodesRef.current;
    const previousGiftCards = previousConflictGiftCardsRef.current;
    const addedCodes = appliedCodes.filter(
      (code) => !previousCodes.includes(code),
    );
    const addedGiftCards = appliedGiftCardCodes.filter(
      (code) => !previousGiftCards.includes(code),
    );

    previousConflictCodesRef.current = appliedCodes;
    previousConflictGiftCardsRef.current = appliedGiftCardCodes;

    // When the merchant allows both, gift cards and discount codes can be
    // combined and nothing needs to be removed.
    if (!exclusiveDiscountOrGiftCard) {
      setConflictMessage("");
      return;
    }

    if (!appliedCodes.length || !appliedGiftCardCodes.length) {
      setConflictMessage("");
      return;
    }

    let codesToRemove = [];
    let giftCardsToRemove = [];
    let message = DISCOUNT_GIFT_CARD_CONFLICT_MESSAGE;
    let eventType = "discount_gift_card_conflict_detected";

    if (addedCodes.length && previousGiftCards.length) {
      codesToRemove = addedCodes;
      message = DISCOUNT_BLOCKED_BY_GIFT_CARD_MESSAGE;
      eventType = "discount_code_blocked_by_gift_card";
    } else if (addedGiftCards.length && previousCodes.length) {
      giftCardsToRemove = addedGiftCards;
      message = GIFT_CARD_BLOCKED_BY_DISCOUNT_MESSAGE;
      eventType = "gift_card_blocked_by_discount_code";
    } else {
      // If checkout loads with both already present, keep the discount code
      // and remove gift cards so checkout cannot continue with both.
      giftCardsToRemove = appliedGiftCardCodes;
      message = GIFT_CARD_BLOCKED_BY_DISCOUNT_MESSAGE;
      eventType = "gift_card_blocked_by_existing_discount_code";
    }

    setConflictMessage(message);

    if (globalThis[CONFLICT_RESOLUTION_LOCK_KEY]) {
      return;
    }

    globalThis[CONFLICT_RESOLUTION_LOCK_KEY] = true;
    setIsResolvingConflict(true);

    void logEvent(shop.myshopifyDomain, "warning", eventType, message, {
      appliedCodes,
      appliedGiftCards: appliedGiftCardCodes,
      codesToRemove,
      giftCardsToRemove,
      extensionTarget,
      checkoutToken,
      customerEmail,
      customerName,
      customerId,
      checkoutData,
    });

    try {
      if (codesToRemove.length) {
        await removeInvalidDiscountCodes(codesToRemove, message);
      }

      if (giftCardsToRemove.length) {
        await removeInvalidGiftCards(giftCardsToRemove, message);
      }
    } finally {
      delete globalThis[CONFLICT_RESOLUTION_LOCK_KEY];
      setIsResolvingConflict(false);
    }
  }

  async function validateBlockedCodes() {
    if (!appliedCodes.length) {
      setBannerMessage("");
      setValidatedCodesKey("");
      return;
    }

    const validationCodes = [...appliedCodes];
    const validationCodesKey = appliedCodesKey;
    setValidatedCodesKey("");

    try {
      setIsValidating(true);
      const backendUrl = String(BACKEND_URL_FROM_ENV || "")
        .trim()
        .replace(/\/$/, "");

      if (!backendUrl || !shop.myshopifyDomain) {
        //setBannerMessage(VALIDATION_ERROR_MESSAGE);
        setValidatedCodesKey(validationCodesKey);
        return;
      }

      const response = await fetch(`${backendUrl}/api/discount-code-validate`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          shop: shop.myshopifyDomain,
          discountCodes: validationCodes,
        }),
      });

      if (!response.ok) {
        console.error(
          "Discount banner validation failed",
          await response.text(),
        );
        void logEvent(
          shop.myshopifyDomain,
          "error",
          "discount_validation_error",
          "Discount validation request failed.",
          {
            appliedCodes,
            extensionTarget,
            checkoutToken,
            customerEmail,
            customerName,
            customerId,
            checkoutData,
          },
        );
        //setBannerMessage(VALIDATION_ERROR_MESSAGE);
        setValidatedCodesKey(validationCodesKey);
        return;
      }

      const json = await response.json();
      const invalidCodes = Array.isArray(json?.invalidCodes)
        ? json.invalidCodes
        : [];
      void logEvent(
        shop.myshopifyDomain,
        "info",
        "discount_code_validated",
        "Discount code validation completed.",
        {
          appliedCodes,
          invalidCodes: invalidCodes.map((item) => ({
            code: item?.code || null,
            reason: item?.reason || null,
          })),
          extensionTarget,
          checkoutToken,
          customerEmail,
          customerName,
          customerId,
          checkoutData,
        },
      );
      const blockedCode = invalidCodes.find(
        (item) => item?.reason === "blocked" || item?.reason === "unavailable",
      );
      const removableCodes = invalidCodes
        .filter(
          (item) =>
            item?.code &&
            (item?.reason === "blocked" || item?.reason === "unavailable"),
        )
        .map((item) => String(item.code));

      if (blockedCode?.message) {
        void logEvent(
          shop.myshopifyDomain,
          "warning",
          "blocked_discount_detected",
          blockedCode.message,
          {
            code: blockedCode.code,
            appliedCodes,
            extensionTarget,
            checkoutToken,
            customerEmail,
            customerName,
            customerId,
            checkoutData,
          },
        );
      }

      setBannerMessage(blockedCode?.message || "");
      setValidatedCodesKey(validationCodesKey);

      if (isPrimaryInstance && removableCodes.length) {
        await removeInvalidDiscountCodes(removableCodes, blockedCode?.message);
      }
    } catch (error) {
      console.error("Discount banner extension error", error);
      void logEvent(
        shop.myshopifyDomain,
        "error",
        "discount_extension_error",
        error instanceof Error
          ? error.message
          : "Unknown discount extension error.",
        {
          appliedCodes,
          extensionTarget,
          checkoutToken,
          customerEmail,
          customerName,
          customerId,
          checkoutData,
        },
      );
      // setBannerMessage(VALIDATION_ERROR_MESSAGE);
      setValidatedCodesKey(validationCodesKey);
    } finally {
      setIsValidating(false);
    }
  }

  async function removeInvalidDiscountCodes(codes, fallbackMessage) {
    setIsRemovingDiscount(true);

    try {
      for (const code of codes) {
        const result = await applyDiscountCodeChange({
          type: "removeDiscountCode",
          code,
        });

        if (result.type === "error") {
          // const message =
          //   result.message || fallbackMessage || VALIDATION_ERROR_MESSAGE;

          const message = result.message || fallbackMessage || "";

          setBannerMessage(message);
          void logEvent(
            shop.myshopifyDomain,
            "error",
            "blocked_discount_remove_error",
            message,
            {
              code,
              appliedCodes,
              extensionTarget,
              checkoutToken,
              customerEmail,
              customerName,
              customerId,
              checkoutData,
            },
          );
          continue;
        }

        void logEvent(
          shop.myshopifyDomain,
          "info",
          "blocked_discount_auto_removed",
          "Blocked discount code was automatically removed from checkout.",
          {
            code,
            appliedCodes,
            extensionTarget,
            checkoutToken,
            customerEmail,
            customerName,
            customerId,
            checkoutData,
          },
        );
      }
    } finally {
      setIsRemovingDiscount(false);
    }
  }

  async function validateGiftCards() {
    console.log("[gift-card-checkout] applied gift cards", {
      extensionTarget,
      appliedGiftCards,
      appliedGiftCardCodes,
    });

    if (!appliedGiftCardCodes.length) {
      setGiftCardBannerMessage("");
      setValidatedGiftCardsKey("");
      return;
    }

    const validationGiftCards = [...appliedGiftCardCodes];
    const validationGiftCardsKey = appliedGiftCardsKey;
    setValidatedGiftCardsKey("");

    try {
      setIsGiftCardValidating(true);
      const backendUrl = String(BACKEND_URL_FROM_ENV || "")
        .trim()
        .replace(/\/$/, "");

      if (!backendUrl || !shop.myshopifyDomain) {
        setValidatedGiftCardsKey(validationGiftCardsKey);
        return;
      }

      const response = await fetch(`${backendUrl}/api/gift-card-validate`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          shop: shop.myshopifyDomain,
          giftCards: validationGiftCards,
        }),
      });

      if (!response.ok) {
        console.error("Gift card validation failed", await response.text());
        void logEvent(
          shop.myshopifyDomain,
          "error",
          "gift_card_validation_error",
          "Gift card validation request failed.",
          {
            appliedGiftCards: appliedGiftCardCodes,
            extensionTarget,
            checkoutToken,
            customerEmail,
            customerName,
            customerId,
            checkoutData,
          },
        );
        setValidatedGiftCardsKey(validationGiftCardsKey);
        return;
      }

      const json = await response.json();
      console.log("[gift-card-checkout] validation response", json);
      const invalidGiftCards = Array.isArray(json?.invalidGiftCards)
        ? json.invalidGiftCards
        : [];

      void logEvent(
        shop.myshopifyDomain,
        "info",
        "gift_card_validated",
        "Gift card validation completed.",
        {
          appliedGiftCards: appliedGiftCardCodes,
          invalidGiftCards: invalidGiftCards.map((item) => ({
            code: item?.code || null,
            reason: item?.reason || null,
          })),
          extensionTarget,
          checkoutToken,
          customerEmail,
          customerName,
          customerId,
          checkoutData,
        },
      );

      const blockedGiftCard = invalidGiftCards.find(
        (item) => item?.reason === "blocked" || item?.reason === "unavailable",
      );
      const removableGiftCards = invalidGiftCards
        .filter(
          (item) =>
            item?.code &&
            (item?.reason === "blocked" || item?.reason === "unavailable"),
        )
        .map((item) => String(item.code));

      if (blockedGiftCard?.message) {
        void logEvent(
          shop.myshopifyDomain,
          "warning",
          "blocked_gift_card_detected",
          blockedGiftCard.message,
          {
            code: blockedGiftCard.code,
            appliedGiftCards: appliedGiftCardCodes,
            extensionTarget,
            checkoutToken,
            customerEmail,
            customerName,
            customerId,
            checkoutData,
          },
        );
      }

      setGiftCardBannerMessage(blockedGiftCard?.message || "");
      setValidatedGiftCardsKey(validationGiftCardsKey);

      if (removableGiftCards.length) {
        await removeInvalidGiftCards(removableGiftCards, blockedGiftCard?.message);
      }
    } catch (error) {
      console.error("Gift card extension error", error);
      void logEvent(
        shop.myshopifyDomain,
        "error",
        "gift_card_extension_error",
        error instanceof Error ? error.message : "Unknown gift card error.",
        {
          appliedGiftCards: appliedGiftCardCodes,
          extensionTarget,
          checkoutToken,
          customerEmail,
          customerName,
          customerId,
          checkoutData,
        },
      );
      setValidatedGiftCardsKey(validationGiftCardsKey);
    } finally {
      setIsGiftCardValidating(false);
    }
  }

  async function removeInvalidGiftCards(codes, fallbackMessage) {
    if (typeof applyGiftCardChange !== "function") {
      const message =
        fallbackMessage ||
        "This gift card isn't allowed for this checkout. Please remove it.";

      setGiftCardBannerMessage(message);
      void logEvent(
        shop.myshopifyDomain,
        "error",
        "gift_card_remove_api_unavailable",
        "Gift card remove API is unavailable on this checkout target.",
        {
          codes,
          appliedGiftCards: appliedGiftCardCodes,
          extensionTarget,
          checkoutToken,
          customerEmail,
          customerName,
          customerId,
          checkoutData,
        },
      );
      return;
    }

    setIsRemovingGiftCard(true);

    try {
      for (const code of codes) {
        const lockKey = `${INSTANCE_KEY_PREFIX}:remove-gift-card:${String(
          code,
        ).trim().toUpperCase()}`;

        if (globalThis[lockKey]) continue;

        globalThis[lockKey] = true;

        let result;
        try {
          result = await applyGiftCardChange({
            type: "removeGiftCard",
            code,
          });
        } finally {
          delete globalThis[lockKey];
        }

        if (result.type === "error") {
          const message = result.message || fallbackMessage || "";

          setGiftCardBannerMessage(message);
          void logEvent(
            shop.myshopifyDomain,
            "error",
            "blocked_gift_card_remove_error",
            message,
            {
              code,
              appliedGiftCards: appliedGiftCardCodes,
              extensionTarget,
              checkoutToken,
              customerEmail,
              customerName,
              customerId,
              checkoutData,
            },
          );
          continue;
        }

        void logEvent(
          shop.myshopifyDomain,
          "info",
          "blocked_gift_card_auto_removed",
          "Blocked gift card was automatically removed from checkout.",
          {
            code,
            appliedGiftCards: appliedGiftCardCodes,
            extensionTarget,
            checkoutToken,
            customerEmail,
            customerName,
            customerId,
            checkoutData,
          },
        );
      }
    } finally {
      setIsRemovingGiftCard(false);
    }
  }

  if (
    !isPrimaryInstance ||
    (!conflictMessage &&
      !bannerMessage &&
      !giftCardBannerMessage &&
      !isResolvingConflict &&
      currentCodesValidated &&
      currentGiftCardsValidated)
  ) {
    return null;
  }

  const visibleMessage =
    conflictMessage ||
    giftCardBannerMessage ||
    bannerMessage ||
    (isResolvingConflict
      ? DISCOUNT_GIFT_CARD_CONFLICT_MESSAGE
      : isRemovingDiscount
      ? REMOVING_DISCOUNT_MESSAGE
      : isRemovingGiftCard
        ? REMOVING_GIFT_CARD_MESSAGE
        : isGiftCardValidating || !currentGiftCardsValidated
          ? GIFT_CARD_VALIDATION_PENDING_MESSAGE
          : VALIDATION_PENDING_MESSAGE);
  const bannerTone =
    conflictMessage || bannerMessage || giftCardBannerMessage
      ? "critical"
      : "warning";

  return <s-banner tone={bannerTone}>{visibleMessage}</s-banner>;
}
