import React, { useEffect, useMemo, useState } from 'react';
import { createRoot } from 'react-dom/client';
import WizardModal from './wizard/WizardModal';
import './front.css';

const BUTTON_SIZE_VARS = {
  sm: {
    '--bp-btn-padding-y': '10px',
    '--bp-btn-padding-x': '14px',
    '--bp-btn-font-size': '14px',
  },
  md: {
    '--bp-btn-padding-y': '12px',
    '--bp-btn-padding-x': '18px',
    '--bp-btn-font-size': '15px',
  },
  lg: {
    '--bp-btn-padding-y': '14px',
    '--bp-btn-padding-x': '22px',
    '--bp-btn-font-size': '17px',
  },
};

const ICON_ALIAS_MAP = {
  calendar: 'calendar.svg',
  location: 'locations.svg',
  locations: 'locations.svg',
  category: 'categories.svg',
  categories: 'categories.svg',
  service: 'services.svg',
  services: 'services.svg',
  extras: 'service-extras.svg',
  agent: 'agents.svg',
  agents: 'agents.svg',
  payment: 'payment.svg',
};

function BookPointWidget({ label, mountEl, options }) {
  const [open, setOpen] = useState(() => shouldAutoOpenWizard());
  const hideButton = mountEl?.getAttribute('data-bp-fallback') === '1';

  const imagesBase = (window.pointlybooking_FRONT?.images || '').replace(/\/$/, '') + '/';
  const iconsBase = (window.pointlybooking_FRONT?.icons || '').replace(/\/$/, '') + '/';
  const brand = useMemo(() => ({
    imagesBase,
    iconsBase,
    helpPhone: '+1 234 567 89',
  }), [imagesBase, iconsBase]);
  const buttonLabel = options?.button?.text || label || 'Book Now';
  const buttonStyle = useMemo(() => buildButtonStyle(options), [options]);
  const buttonIcon = useMemo(() => renderButtonIcon(options?.button?.icon, brand), [options?.button?.icon, brand]);
  const buttonClass = options?.button?.fullWidth ? 'bp-book-btn bp-book-btn--full' : 'bp-book-btn';

  useEffect(() => attachOpenHandler(mountEl, setOpen), [mountEl]);

  return (
    <>
      {!hideButton && (
        <button
          className={buttonClass}
          type="button"
          style={buttonStyle}
          onClick={() => setOpen(true)}
        >
          {buttonIcon}
          <span className="bp-book-btn-label">{buttonLabel}</span>
        </button>
      )}

      <WizardModal
        open={open}
        onClose={() => setOpen(false)}
        brand={brand}
        widgetOptions={options}
      />
    </>
  );
}

function parseWidgetOptions(mountEl) {
  if (!mountEl) return {};
  const raw = mountEl.getAttribute('data-bp-options');
  if (!raw) return {};
  try {
    const decoded = JSON.parse(raw);
    return decoded && typeof decoded === 'object' ? decoded : {};
  } catch (e) {
    return {};
  }
}

function buildButtonStyle(options) {
  const button = options?.button;
  if (!button || typeof button !== 'object') return undefined;

  const style = {};
  if (isColor(button.color)) style['--bp-btn-bg'] = button.color;
  if (isColor(button.hoverColor)) style['--bp-btn-hover-bg'] = button.hoverColor;
  if (isColor(button.textColor)) style['--bp-btn-text'] = button.textColor;

  const radius = asNumber(button.radius);
  if (radius !== null && radius >= 0) {
    style['--bp-btn-radius'] = `${Math.min(80, Math.round(radius))}px`;
  }

  const size = String(button.size || '').toLowerCase();
  if (BUTTON_SIZE_VARS[size]) {
    Object.assign(style, BUTTON_SIZE_VARS[size]);
  }

  return Object.keys(style).length ? style : undefined;
}

function renderButtonIcon(rawIcon, brand) {
  if (rawIcon == null) return null;
  const icon = String(rawIcon).trim();
  if (!icon) return null;

  const lower = icon.toLowerCase();
  if (ICON_ALIAS_MAP[lower]) {
    const src = buildIconUrl(ICON_ALIAS_MAP[lower], brand?.iconsBase);
    return (
      <span className="bp-book-btn-icon" aria-hidden="true">
        <img src={src} alt="" loading="lazy" />
      </span>
    );
  }

  if (isImagePath(icon)) {
    const src = resolveImageSource(icon, brand);
    return (
      <span className="bp-book-btn-icon" aria-hidden="true">
        <img src={src} alt="" loading="lazy" />
      </span>
    );
  }

  return <span className="bp-book-btn-icon" aria-hidden="true">{icon}</span>;
}

function resolveImageSource(icon, brand) {
  if (/^(https?:)?\/\//i.test(icon) || icon.startsWith('/')) {
    return icon;
  }
  if (icon.toLowerCase().endsWith('.svg') && brand?.iconsBase) {
    return buildIconUrl(icon, brand.iconsBase);
  }
  if (brand?.imagesBase) {
    return buildIconUrl(icon, brand.imagesBase);
  }
  return icon;
}

function buildIconUrl(file, base) {
  const cleanBase = String(base || '');
  const cleanFile = String(file || '').replace(/^\/+/, '');
  const url = cleanBase ? `${cleanBase}${cleanFile}` : cleanFile;
  const iconsBuild = String(window.pointlybooking_FRONT?.iconsBuild || '').trim();
  const imagesBuild = String(window.pointlybooking_FRONT?.imagesBuild || '').trim();
  const build = cleanFile.toLowerCase().endsWith('.svg') ? iconsBuild : imagesBuild;
  if (!build) return url;
  const sep = url.includes('?') ? '&' : '?';
  return `${url}${sep}v=${encodeURIComponent(build)}`;
}

function isColor(value) {
  if (typeof value !== 'string') return false;
  const trimmed = value.trim();
  if (!trimmed) return false;
  if (/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/.test(trimmed)) return true;
  if (/^rgba?\(\s*[\d.\s,%]+\s*\)$/i.test(trimmed)) return true;
  if (/^hsla?\(\s*[\d.\s,%]+\s*\)$/i.test(trimmed)) return true;
  return false;
}

function asNumber(value) {
  const num = Number(value);
  return Number.isFinite(num) ? num : null;
}

function isImagePath(value) {
  return /\.(svg|png|jpe?g|gif|webp|avif)$/i.test(value) || /^(https?:)?\/\//i.test(value) || value.startsWith('/');
}

function attachOpenHandler(mountEl, setOpen) {
  if (!mountEl) return () => {};
  mountEl.__bpOpen = () => setOpen(true);
  return () => {
    if (mountEl.__bpOpen) delete mountEl.__bpOpen;
  };
}

function getBrand() {
  const imagesBase = (window.pointlybooking_FRONT?.images || '').replace(/\/$/, '') + '/';
  const iconsBase = (window.pointlybooking_FRONT?.icons || '').replace(/\/$/, '') + '/';
  return {
    imagesBase,
    iconsBase,
    helpPhone: '+1 234 567 89',
  };
}

function bootLegacy() {
  const mount = document.getElementById('bp-front-root');
  if (!mount) return;

  const root = createRoot(mount);
  const brand = getBrand();

  const open = () => {
    mount.style.display = 'block';
    root.render(
      <WizardModal
        open={true}
        onClose={() => {
          root.render(null);
          mount.style.display = 'none';
        }}
        brand={brand}
      />
    );
  };

  document.addEventListener('click', (e) => {
    const target = e.target;
    if (!(target instanceof Element)) return;
    if (target.closest('.bp-open-wizard')) {
      e.preventDefault();
      open();
    }
  });

  if (shouldAutoOpenWizard()) {
    open();
  }
}

function boot() {
  const widgets = document.querySelectorAll(".bp-front-root[data-bp-widget='wizard']");
  if (!widgets.length) {
    bootLegacy();
    return;
  }

  widgets.forEach((el) => {
    const root = createRoot(el);
    const options = parseWidgetOptions(el);
    const label = options?.button?.text || el.getAttribute('data-bp-label') || 'Book Now';
    root.render(
      <BookPointWidget
        label={label}
        mountEl={el}
        options={options}
      />
    );
  });

  document.addEventListener('click', (e) => {
    const target = e.target;
    if (!(target instanceof Element)) return;
    const trigger = target.closest('.bp-fallback-btn, [data-bp-open="wizard"]');
    if (!trigger) return;

    const candidate = trigger.nextElementSibling;
    const mount = candidate && candidate.classList.contains('bp-front-root')
      ? candidate
      : trigger.closest('.bp-front-root') || document.querySelector('.bp-front-root');

    if (mount && typeof mount.__bpOpen === 'function') {
      e.preventDefault();
      mount.__bpOpen();
    }
  });
}

function hasResumeTokenInUrl() {
  if (typeof window === 'undefined') return false;
  try {
    const url = new URL(window.location.href);
    return !!url.searchParams.get('pointlybooking_resume');
  } catch (e) {
    return false;
  }
}

function hasPaymentReturnInUrl() {
  if (typeof window === 'undefined') return false;
  try {
    const url = new URL(window.location.href);
    return !!url.searchParams.get('pointlybooking_payment');
  } catch (e) {
    return false;
  }
}

function shouldAutoOpenWizard() {
  return hasResumeTokenInUrl() || hasPaymentReturnInUrl();
}

if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', boot);
} else {
  boot();
}
