'use client';

import { useEffect, useState } from 'react';
import settings from '@theme/settings';
import { isKnownVariant } from './registry';
import type { CheckoutVariantId, CheckoutVariantOptions } from './types';

export interface ResolvedCheckoutConfig {
  variantId: CheckoutVariantId;
  options: CheckoutVariantOptions;
}

interface RawCheckoutConfig {
  variant?: string;
  options?: Record<string, unknown>;
}

const FALLBACK_VARIANT: CheckoutVariantId = 'multi-step';

const coerceOptions = (
  raw: Record<string, unknown> | undefined
): CheckoutVariantOptions => {
  if (!raw) return {};
  const cast = raw as Partial<CheckoutVariantOptions>;
  const out: CheckoutVariantOptions = {};
  if (typeof cast.enableEditMode === 'boolean') out.enableEditMode = cast.enableEditMode;
  if (typeof cast.autoAdvance === 'boolean') out.autoAdvance = cast.autoAdvance;
  if (typeof cast.stickyMobileCta === 'boolean') out.stickyMobileCta = cast.stickyMobileCta;
  if (typeof cast.showOrderReview === 'boolean') out.showOrderReview = cast.showOrderReview;
  if (typeof cast.showTrustBadges === 'boolean') out.showTrustBadges = cast.showTrustBadges;
  if (typeof cast.gtmEnabled === 'boolean') out.gtmEnabled = cast.gtmEnabled;
  if (typeof cast.compactMode === 'boolean') out.compactMode = cast.compactMode;
  return out;
};

const readBaseFromSettings = (): ResolvedCheckoutConfig => {
  const fromSettings = (settings as { checkout?: RawCheckoutConfig })?.checkout;
  const variantId = isKnownVariant(fromSettings?.variant)
    ? fromSettings.variant
    : FALLBACK_VARIANT;
  return {
    variantId,
    options: coerceOptions(fromSettings?.options)
  };
};

const mergeOverride = (
  base: ResolvedCheckoutConfig,
  override: RawCheckoutConfig | undefined
): ResolvedCheckoutConfig => {
  if (!override) return base;
  return {
    variantId: isKnownVariant(override.variant) ? override.variant : base.variantId,
    options: { ...base.options, ...coerceOptions(override.options) }
  };
};

/**
 * Resolves checkout config from two layers (each optional):
 *
 *   1. settings.js (sync, always available — baseline / fallback)
 *   2. /api/theme-settings (backend theme-config widget — persistent override)
 *
 * Layer 2 falls back silently if backend is unreachable or no config is saved.
 * The editor is OPTIONAL — when no theme-config is saved, the storefront keeps
 * using its built-in settings.js.
 */
export const useResolvedCheckoutConfig = (): ResolvedCheckoutConfig => {
  const [config, setConfig] = useState<ResolvedCheckoutConfig>(readBaseFromSettings);

  useEffect(() => {
    let cancelled = false;
    fetch('/api/theme-settings', { cache: 'no-store' })
      .then((res) => (res.ok ? res.json() : null))
      .then((data: { checkout?: RawCheckoutConfig } | null) => {
        if (cancelled) return;
        if (!data?.checkout) return;
        setConfig(() => mergeOverride(readBaseFromSettings(), data.checkout));
      })
      .catch(() => {
        // Silent: backend not reachable or widget missing — keep settings.js baseline
      });
    return () => {
      cancelled = true;
    };
  }, []);

  return config;
};
