import React, { createContext, useCallback, useContext, useMemo } from 'react';
import { IdExtractor } from 'src/contexts/types';
import { parseHref } from 'src/application/utils/urlsParser';

interface ShopifyUrlContextType {
  getTrimmedPathName: () => string | null;
  getPlpOrPdpId: (extractor: IdExtractor) => string | null;
  isOnPdpPage: () => boolean;
  isOnPlpPage: () => boolean;
  isReady: boolean;
}

const ShopifyUrlContext = createContext<ShopifyUrlContextType | undefined>(undefined);

export const ShopifyUrlProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const isReady = true; // No external dependencies, so always ready

  const getTrimmedPathName = useCallback((): string | null => {
    let { pathname } = window.location;
    // strip out the proxy path so local dev still works
    pathname = pathname.replace('/proxy', '');
    // remove trailing hash if it exists
    pathname = pathname.replace(/#.*$/, '');
    // remove trailing /, ie. some URLs can end with '/' like /collections/cast-iron/
    pathname = pathname.replace(/\/$/, '');

    if (pathname === undefined || pathname === null || pathname.length === 0) {
      return null;
    }

    return pathname;
  }, []);

  const getPlpOrPdpId = useCallback(
    (extractor: IdExtractor): string | null => {
      if (extractor === 'shopify-product-variant-id') {
        const parsedHref = parseHref(window.location.href);
        const variantId = parsedHref?.urlSearchParams?.get('variant');
        if (!variantId) {
          return getPlpOrPdpId('shopify-product-id');
        }
        return variantId;
      }

      const pathSegment = extractor === 'shopify-product-id' ? 'products' : 'collections';
      const tokens = getTrimmedPathName()?.split('/');
      const idIndex = tokens?.findIndex(token => token === pathSegment);
      if (idIndex !== undefined && idIndex >= 0 && tokens) {
        return decodeURIComponent(tokens[idIndex + 1]);
      }
      return null;
    },
    [getTrimmedPathName],
  );

  const isOnPdpPage = useCallback((): boolean => {
    return getTrimmedPathName()?.includes('/products') ?? false;
  }, [getTrimmedPathName]);

  const isOnPlpPage = useCallback((): boolean => {
    return (
      (getTrimmedPathName()?.includes('/collections') &&
        !getTrimmedPathName()?.includes('/products')) ??
      false
    );
  }, [getTrimmedPathName]);

  const value = useMemo(
    () => ({
      getTrimmedPathName,
      getPlpOrPdpId,
      isOnPdpPage,
      isOnPlpPage,
      isReady,
    }),
    [getTrimmedPathName, getPlpOrPdpId, isOnPdpPage, isOnPlpPage, isReady],
  );

  return <ShopifyUrlContext.Provider value={value}>{children}</ShopifyUrlContext.Provider>;
};

export const useShopifyUrl = () => {
  const context = useContext(ShopifyUrlContext);
  if (!context) {
    throw new Error('useShopifyUrl must be used within a ShopifyUrlProvider');
  }
  return context;
};
