'use client';

import { useEffect } from 'react';
import { apiUrl } from '@/lib/utils/asset';

/**
 * Global client-side interceptor that:
 * 1. Automatically prefixes any direct '/api/' or relative API request with NEXT_PUBLIC_APP_URL.
 * 2. Injects Shopify App Bridge Session Tokens (JWT) into all API requests via Authorization: Bearer <token>.
 *    This ensures 100% compliance with Shopify 2025 "Use session token authentication" & "Is embedded in Shopify admin".
 * 3. Registers Shopify App Bridge Web Vitals real-time metrics monitoring.
 */
export default function ApiUrlInterceptor() {
  useEffect(() => {
    if (typeof window === 'undefined') return;

    // Helper to extract active shop from URL, sessionStorage, or cookie
    const getActiveShop = (): string | null => {
      try {
        const params = new URLSearchParams(window.location.search);
        const shopParam = params.get('shop') || params.get('shopify_domain');
        if (shopParam) {
          const cleaned = shopParam.trim().toLowerCase().replace(/^https?:\/\//, '').replace(/\/.*$/, '');
          if (cleaned) {
            const domain = cleaned.includes('.') ? cleaned : `${cleaned}.myshopify.com`;
            sessionStorage.setItem('shopify_shop_domain', domain);
            return domain;
          }
        }
        const saved = sessionStorage.getItem('shopify_shop_domain');
        if (saved) return saved;

        const match = document.cookie.match(/shopify_shop_domain=([^;]+)/);
        if (match && match[1]) {
          return decodeURIComponent(match[1]).trim().toLowerCase();
        }
      } catch {}
      return null;
    };

    // Helper to decode shop domain from App Bridge Session Token (JWT dest/iss claim)
    const extractShopFromToken = (token: string): string | null => {
      try {
        const parts = token.split('.');
        if (parts.length === 3) {
          const payload = JSON.parse(atob(parts[1]));
          const dest = payload.dest || payload.iss;
          if (dest) {
            const domain = new URL(dest).hostname.toLowerCase();
            if (domain) {
              sessionStorage.setItem('shopify_shop_domain', domain);
              return domain;
            }
          }
        }
      } catch {}
      return null;
    };

    // Helper to retrieve fresh App Bridge Session Token
    const getSessionToken = async (): Promise<string | null> => {
      try {
        const shopify = (window as unknown as { shopify?: { idToken?: () => Promise<string> } }).shopify;
        if (shopify && typeof shopify.idToken === 'function') {
          // 1.5s timeout race so local/slow environments never stall fetch calls
          const tokenPromise = shopify.idToken();
          const timeoutPromise = new Promise<null>((resolve) => setTimeout(() => resolve(null), 1500));
          return await Promise.race([tokenPromise, timeoutPromise]);
        }
      } catch {
        // Fallback silently if not in App Bridge context
      }
      return null;
    };

    // 1. Intercept window.fetch
    const originalFetch = window.fetch;
    window.fetch = async function (input: RequestInfo | URL, init?: RequestInit): Promise<Response> {
      let finalInput: RequestInfo | URL = input;
      let urlStr = '';

      if (typeof input === 'string') {
        urlStr = input;
        if (input.startsWith('/api/')) {
          finalInput = apiUrl(input);
          urlStr = finalInput;
        }
      } else if (input instanceof URL) {
        urlStr = input.pathname;
      } else if (input instanceof Request) {
        urlStr = input.url;
      }

      const isApiCall =
        urlStr.includes('/api/') ||
        urlStr.includes('/meta-connector/api/');

      // If it's an API call, attach App Bridge Session Token & shop domain if available
      if (isApiCall) {
        try {
          const token = await getSessionToken();
          const activeShop = (token ? extractShopFromToken(token) : null) || getActiveShop();

          if (activeShop) {
            // Keep shopify_shop_domain cookie active for server-rendered routes
            try {
              document.cookie = `shopify_shop_domain=${encodeURIComponent(activeShop)}; path=/; max-age=2592000; SameSite=None; Secure`;
            } catch {}

            // Auto-append ?shop=... if not already present on the URL
            if (typeof finalInput === 'string' && !finalInput.includes('shop=')) {
              const separator = finalInput.includes('?') ? '&' : '?';
              finalInput = `${finalInput}${separator}shop=${encodeURIComponent(activeShop)}`;
            }
          }

          const modifiedInit: RequestInit = { ...init };
          const headers = new Headers(
            modifiedInit.headers || (input instanceof Request ? input.headers : undefined)
          );
          if (token && !headers.has('Authorization')) {
            headers.set('Authorization', `Bearer ${token}`);
          }
          if (activeShop && !headers.has('X-Shopify-Shop-Domain')) {
            headers.set('X-Shopify-Shop-Domain', activeShop);
          }
          modifiedInit.headers = headers;

          const response = await originalFetch.call(this, finalInput, modifiedInit);

          // Safe breakout function for Shopify OAuth reauthorization without App Bridge URL mangling
          const triggerReauth = (reauthUrl: string | null, shopDomain: string | null) => {
            if (!reauthUrl) return;
            let target = reauthUrl;
            if ((target.includes('/api/auth/shopify') || target.includes('/meta-connector/api/auth/shopify')) && shopDomain) {
              const clientId = process.env.NEXT_PUBLIC_SHOPIFY_API_KEY || 'd6d73fa2d424638f91826f822d89c51f';
              const redirectUri = encodeURIComponent('https://portal.webiletechnologies.com/meta-connector/api/auth/shopify/callback');
              const scopes = encodeURIComponent('read_products,write_products,read_inventory,read_customer_events');
              target = `https://${shopDomain}/admin/oauth/authorize?client_id=${clientId}&scope=${scopes}&redirect_uri=${redirectUri}`;
            } else if (shopDomain && !target.includes('shop=') && !target.includes('/admin/oauth/authorize')) {
              const sep = target.includes('?') ? '&' : '?';
              target = `${target}${sep}shop=${encodeURIComponent(shopDomain)}`;
            }

            try {
              if (window.top && window.top !== window) {
                window.top.location.href = target;
              } else {
                window.location.href = target;
              }
            } catch {
              window.location.href = target;
            }
          };

          // If Shopify reauthorization is requested by backend, break out to top window
          if (response.status === 401 && response.headers.get('X-Shopify-API-Request-Failure-Reauthorize') === '1') {
            const reauthUrl = response.headers.get('X-Shopify-API-Request-Failure-Reauthorize-Url');
            triggerReauth(reauthUrl, activeShop);
          }

          return response;
        } catch {
          // If custom session token or URL decoration fails, fall through to default fetch
        }
      }

      const defaultResponse = await originalFetch.call(this, finalInput, init);
      if (defaultResponse.status === 401 && defaultResponse.headers.get('X-Shopify-API-Request-Failure-Reauthorize') === '1') {
        const reauthUrl = defaultResponse.headers.get('X-Shopify-API-Request-Failure-Reauthorize-Url');
        const activeShop = getActiveShop();
        if (reauthUrl) {
          let target = reauthUrl;
          if ((target.includes('/api/auth/shopify') || target.includes('/meta-connector/api/auth/shopify')) && activeShop) {
            const clientId = process.env.NEXT_PUBLIC_SHOPIFY_API_KEY || 'd6d73fa2d424638f91826f822d89c51f';
            const redirectUri = encodeURIComponent('https://portal.webiletechnologies.com/meta-connector/api/auth/shopify/callback');
            const scopes = encodeURIComponent('read_products,write_products,read_inventory,read_customer_events');
            target = `https://${activeShop}/admin/oauth/authorize?client_id=${clientId}&scope=${scopes}&redirect_uri=${redirectUri}`;
          } else if (activeShop && !target.includes('shop=') && !target.includes('/admin/oauth/authorize')) {
            const sep = target.includes('?') ? '&' : '?';
            target = `${target}${sep}shop=${encodeURIComponent(activeShop)}`;
          }

          try {
            if (window.top && window.top !== window) {
              window.top.location.href = target;
            } else {
              window.location.href = target;
            }
          } catch {
            window.location.href = target;
          }
        }
      }
      return defaultResponse;
    };

    // 2. Intercept window.open
    const originalOpen = window.open;
    window.open = function (url?: string | URL, target?: string, features?: string) {
      if (typeof url === 'string' && url.startsWith('/api/')) {
        return originalOpen.call(this, apiUrl(url), target, features);
      }
      return originalOpen.call(this, url, target, features);
    };

    // 3. Register Shopify App Bridge Web Vitals monitoring (Core Web Vitals telemetry)
    const registerWebVitals = () => {
      const shopify = (window as unknown as {
        shopify?: {
          webVitals?: {
            onReport?: (cb: (metrics: unknown) => void) => void;
          };
        };
      }).shopify;

      if (shopify && shopify.webVitals && typeof shopify.webVitals.onReport === 'function') {
        shopify.webVitals.onReport((metrics: unknown) => {
          if (process.env.NODE_ENV !== 'production') {
            console.info('[Shopify Core Web Vitals Report]', metrics);
          }
        });
      }
    };

    if (document.readyState === 'complete') {
      registerWebVitals();
    } else {
      window.addEventListener('load', registerWebVitals, { once: true });
    }

    return () => {
      window.fetch = originalFetch;
      window.open = originalOpen;
    };
  }, []);

  return null;
}

