"use client";

import { useEffect, useRef, useState } from "react";

declare global {
  interface Window {
    Alma?: {
      Widgets: {
        initialize: (merchantId: string, domain: unknown) => AlmaWidgetsInstance;
        PaymentPlans: unknown;
        Modal: unknown;
      };
      ApiMode: {
        TEST: unknown;
        LIVE: unknown;
      };
    };
  }
}

interface AlmaWidgetsInstance {
  add: (widget: unknown, options: AlmaWidgetOptions) => void;
}

interface AlmaPlan {
  installmentsCount: number;
  minAmount: number;
  maxAmount: number;
  deferredDays?: number;
}

interface AlmaWidgetOptions {
  container: string;
  purchaseAmount: number;
  locale?: string;
  hideIfNotEligible?: boolean;
  transitionDelay?: number;
  monochrome?: boolean;
  hideBorder?: boolean;
  plans?: AlmaPlan[];
  customerBillingCountry?: string;
  clickableSelector?: string;
}

interface AlmaWidgetProps {
  /** Amount in euros (not cents) */
  amount: number;
  /** Widget type: 'badge' shows inline plans, 'modal' shows only a modal trigger */
  type?: "badge" | "modal";
  /** CSS selector for the element that triggers the modal (modal type only) */
  clickableSelector?: string;
  /** Whether to hide the widget if no plan is eligible */
  hideIfNotEligible?: boolean;
  /** Custom CSS classes for the container */
  className?: string;
}

interface AlmaRemoteConfig {
  merchant_id: string;
  enabled: boolean;
  plans: AlmaPlan[];
  min_amount: number;
  max_amount: number;
}

const WIDGET_CSS = "https://cdn.jsdelivr.net/npm/@alma/widgets/dist/widgets.min.css";
const WIDGET_JS = "https://cdn.jsdelivr.net/npm/@alma/widgets/dist/widgets.umd.js";

let configCache: AlmaRemoteConfig | null = null;
let configLoading: Promise<AlmaRemoteConfig | null> | null = null;

async function fetchAlmaConfig(): Promise<AlmaRemoteConfig | null> {
  if (configCache) return configCache;
  if (configLoading) return configLoading;

  configLoading = fetch(
    `${process.env.NEXT_PUBLIC_SUPABASE_URL}/functions/v1/alma-config`,
    {
      headers: {
        Authorization: `Bearer ${process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY}`,
      },
    }
  )
    .then((r) => r.json())
    .then((d) => {
      configCache = d.merchant_id ? (d as AlmaRemoteConfig) : null;
      return configCache;
    })
    .catch(() => null);

  return configLoading;
}

function loadScript(src: string): Promise<void> {
  return new Promise((resolve, reject) => {
    if (document.querySelector(`script[src="${src}"]`)) {
      resolve();
      return;
    }
    const script = document.createElement("script");
    script.src = src;
    script.async = true;
    script.onload = () => resolve();
    script.onerror = reject;
    document.head.appendChild(script);
  });
}

function loadStylesheet(href: string) {
  if (document.querySelector(`link[href="${href}"]`)) return;
  const link = document.createElement("link");
  link.rel = "stylesheet";
  link.href = href;
  document.head.appendChild(link);
}

export function AlmaWidget({
  amount,
  type = "badge",
  clickableSelector,
  hideIfNotEligible = true,
  className = "",
}: AlmaWidgetProps) {
  const containerRef = useRef<HTMLDivElement>(null);
  const widgetsRef = useRef<AlmaWidgetsInstance | null>(null);
  const [ready, setReady] = useState(false);
  const [almaConfig, setAlmaConfig] = useState<AlmaRemoteConfig | null>(null);
  const containerId = useRef(`alma-widget-${Math.random().toString(36).slice(2)}`);

  // Load Alma assets and initialise the controller once
  useEffect(() => {
    let cancelled = false;

    async function init() {
      loadStylesheet(WIDGET_CSS);
      await loadScript(WIDGET_JS);
      const cfg = await fetchAlmaConfig();
      if (!cfg || !cfg.enabled || cancelled || !window.Alma) return;

      widgetsRef.current = window.Alma.Widgets.initialize(
        cfg.merchant_id,
        window.Alma.ApiMode.LIVE
      );
      setAlmaConfig(cfg);
      setReady(true);
    }

    init();
    return () => { cancelled = true; };
  }, []);

  // Re-render widget whenever amount or readiness changes
  useEffect(() => {
    if (!ready || !widgetsRef.current || !window.Alma || !almaConfig) return;
    const amountCents = Math.round(amount * 100);

    if (type === "badge") {
      widgetsRef.current.add(window.Alma.Widgets.PaymentPlans, {
        container: `#${containerId.current}`,
        purchaseAmount: amountCents,
        locale: "fr-FR",
        hideIfNotEligible,
        transitionDelay: 5500,
        monochrome: false,
        hideBorder: false,
        customerBillingCountry: "fr",
        plans: almaConfig.plans,
      });
    } else {
      widgetsRef.current.add(window.Alma.Widgets.Modal, {
        container: `#${containerId.current}`,
        purchaseAmount: amountCents,
        locale: "fr-FR",
        clickableSelector: clickableSelector ?? `#${containerId.current}`,
        customerBillingCountry: "fr",
        plans: almaConfig.plans,
      });
    }
  }, [ready, amount, type, clickableSelector, hideIfNotEligible, almaConfig]);

  return (
    <div
      id={containerId.current}
      ref={containerRef}
      className={className}
    />
  );
}
