
window.givikiWidget = {};

function showDonationWidget(donationData = null, donationSettings = null) {
  const iframe = document.getElementById("giveasia_donationWidget");
  iframe.width = "100%";
  iframe.height = "100%";
  iframe.style.cssText = "display: block !important; margin: 0 !important; padding: 0 !important; border: 0 !important; width: 100vw !important; height: 100vh !important; position: fixed !important; opacity: 1 !important; top: 0 !important; left: 0 !important; right: 0 !important; bottom: 0 !important; transform: translateZ(100px) !important; z-index: 9999999 !important;";

  if (!donationData) {
    const localData = localStorage.getItem('giveasia_donationWidgetData');
    donationData = localData ? JSON.parse(localData) : { donationStep: 'amount_select', charityId: '11002' };
  }

  if (!donationSettings) {
    donationSettings = { widgetUrl: `https://${window.location.hostname}${window.location.pathname}?donate` };
  }

  iframe.contentWindow.postMessage({
    event: 'showDonationWidget',
    state: donationData,
    settings: donationSettings,
  }, '*');

  localStorage.removeItem('giveasia_donationWidgetData');
  const reminderIframe = document.getElementById('giveasia_donationReminder');

  if (postMessage) {
    reminderIframe.contentWindow.postMessage({
      event: 'hideDonationReminder',
    }, '*');
  }

  setTimeout(() => {
    reminderIframe.width = "0";
    reminderIframe.height = "0";
    reminderIframe.style.cssText = "display: hidden !important; margin: 0 !important; padding: 0 !important; border: 0 !important; width: 0 !important; height: 0 !important; position: fixed !important; opacity: 0 !important; top: 0 !important; left: 0 !important; right: 0 !important; bottom: 0 !important; transform: translateZ(100px) !important; z-index: 9999999 !important;";
  }, 250);
}

window.showDonationWidget = showDonationWidget;

window.givikiWidget.open = (donationData) => {
  showDonationWidget(donationData);
};

window.givikiWidget.install = (options = { openButton: true, inlineDonateForm: false, triggerDonateForm: false }) => {
  const ALLOWED_QUERY_PARAMS = {
    donationWidget: ['show'],
    donationType: ['once', 'monthly'],
    donationStep: ['amount_select', 'upsell_to_recurring', 'personal_information', 'cover_platform_fees', 'payment'],
    oneTimeAmount: '',
    recurringAmount: '',
  };

  const MOBILE_SCREEN_WIDTH = 700;

  function filterAllowedQueryParams() {
    const queryParams = {};
    const queryString = window.location.search;
    if (queryString) {
      const searchParams = new URLSearchParams(queryString);
      for (const [key, value] of searchParams.entries()) {
        if (ALLOWED_QUERY_PARAMS.hasOwnProperty(key)) {
          if (key === 'oneTimeAmount' || key === 'recurringAmount') {
            queryParams[key] = value.replace(/\D/g, '');
          } else if (ALLOWED_QUERY_PARAMS[key].includes(value)) {
            queryParams[key] = value;
          }
        }
      }
    }
    return queryParams;
  }

  function handleQueryStringChange() {
    const settings = filterAllowedQueryParams();
    if (settings.donationWidget) {
      const state = { donationStep: 'amount_select', ...settings };
      if (settings.donationStep) {
        state.donationStep = settings.donationStep;
      }
      showDonationWidget(state);
    }
  }

  function isMobile() {
    const userAgent = navigator.userAgent.toLowerCase();
    const isMobile = /iphone|ipad|ipod|android|blackberry|windows phone/g.test(userAgent);

    return window.screen.width <= MOBILE_SCREEN_WIDTH || isMobile;
  }

  function initQueryParamsWatch() {
    // Check current query string
    handleQueryStringChange();
    // Listen for hash change
    window.addEventListener('popstate', handleQueryStringChange);
  }

  function createIframe(id, title, src, style) {
    const iframe = document.createElement("iframe");
    iframe.id = id;
    iframe.title = title;
    iframe.src = src;
    iframe.style.cssText = style;
    iframe.setAttribute('allowtransparency', 'true');
    iframe.setAttribute('allowpaymentrequest', 'true');
    iframe.setAttribute('allow', 'payment * clipboard-read; clipboard-write');
    return iframe;
  }

  function initInlineDonationForm(url = 'https://widget.give.asia/form') {
    let donateForm = document.getElementById('giveasia_inlineDonationForm');
    if (!donateForm) {
      const iframeStyle = "margin: 0 !important; padding: 0 !important; border: 0 !important; transform: translateZ(100px) !important; width: 320px !important; height: 600px !important;";
      const iframe = createIframe("giveasia_inlineDonationForm", "Inline Donation Form", url, iframeStyle);
      document.getElementById('giveasia_donateForm').append(iframe);
    }
  }

  function setViewport(options = {}) {
    const defaultContent = 'width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no';
    const content = options.viewportContent || defaultContent;
    const existingViewport = document.querySelector('meta[name="viewport"]');

    if (!existingViewport || existingViewport.content !== content) {
      if (!existingViewport) {
        const metaTag = document.createElement('meta');
        metaTag.name = 'viewport';
        metaTag.content = content;
        document.head.appendChild(metaTag);
      } else {
        existingViewport.content = content;
      }
    }
  }

  function initDonationWidget(url = 'https://widget.give.asia/modal') {
    if (isMobile()) {
      if (!document.querySelector('meta[name="viewport"]')) {
        const metaTag = document.createElement('meta');
        metaTag.name = 'viewport';
        metaTag.content = 'width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no';
        document.head.appendChild(metaTag);
      }
    }
    if (document.body) {
      const iframeStyle = "display: none !important; margin: 0 !important; padding: 0 !important; border: 0 !important; width: 0 !important; height: 0 !important; position: fixed !important; opacity: 0 !important; top: 0 !important; left: 0 !important; right: 0 !important; bottom: 0 !important; transform: translateZ(100px) !important; z-index: 9999999 !important;";
      const iframe = createIframe("giveasia_donationWidget", "Donation Widget", url, iframeStyle);
      document.body.appendChild(iframe);
    } else {
      console.error("Document body is not available.");
    }
  }

  function initDonationReminder(url = 'https://widget.give.asia/reminder') {
    const iframeStyle = "display: none !important; margin: 0 !important; padding: 0 !important; border: 0 !important; width: 0 !important; height: 0 !important; position: fixed !important; opacity: 0 !important; left: 0 !important; bottom: 0 !important; transform: translateZ(100px) !important; z-index: 9999998 !important;";
    const iframe = createIframe("giveasia_donationReminder", "Donation Reminder", url, iframeStyle);
    iframe.allowTransparency = true;
    document.body.appendChild(iframe);
  }

  function addDonateButtonStyles() {
    const styleContent = `
      #giveasia_donateButton {
        display: inline-flex !important;
        align-items: center !important;
        justify-content: center !important;
        box-sizing: border-box !important;
        appearance: none !important;
        user-select: none !important;
        white-space: nowrap !important;
        font-weight: normal !important;
        font-family: Arial, Helvetica, sans-serif !important;
        overflow: hidden !important;
        -webkit-tap-highlight-color: transparent !important;
        outline: none !important;
        width: 110px !important;
        height: 40px !important;
        font-size: 15px !important;
        border-radius: 9999px !important;
        transition: transform 0.3s, color 0.3s, opacity 0.3s !important;
        background-color: #f31260 !important;
        color: white !important;
        position: fixed !important;
        z-index: 9999 !important;
        bottom: 20px !important;
        right: 20px !important;
        padding: 20px !important;
        border: none !important;
        cursor: pointer !important;
        gap: 0.5rem !important;
      }
  
      #giveasia_donateButton:hover {
        opacity: 0.8;
      }
  
      #giveasia_donateButton svg {
        max-width: 32px;
        animation: pulse 1.5s cubic-bezier(0.4, 0, 0.6, 1) infinite;
      }
  
      @keyframes pulse {
        0%, 100% {
          transform: scale(1);
        }
        70% {
          transform: scale(1.2);
        }
      }
    `;
  
    const styleElement = document.createElement('style');
    styleElement.type = 'text/css';
    styleElement.appendChild(document.createTextNode(styleContent));
    document.head.appendChild(styleElement);
  }

  // TODO: refactor to support different button styles
  function initDonateButton() {
    let button = document.getElementById('giveasia_donateButton');
    if (!button) {
      button = document.createElement("button");
      button.innerHTML = '<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" class="pulse" aria-hidden="true" focusable="false" tabindex="-1" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M256 448a32 32 0 0 1-18-5.57c-78.59-53.35-112.62-89.93-131.39-112.8-40-48.75-59.15-98.8-58.61-153C48.63 114.52 98.46 64 159.08 64c44.08 0 74.61 24.83 92.39 45.51a6 6 0 0 0 9.06 0C278.31 88.81 308.84 64 352.92 64c60.62 0 110.45 50.52 111.08 112.64.54 54.21-18.63 104.26-58.61 153-18.77 22.87-52.8 59.45-131.39 112.8a32 32 0 0 1-18 5.56z"></path></svg> Donate';
      button.id = 'giveasia_donateButton';
      button.type = 'button';

      document.body.appendChild(button);

      button.addEventListener("click", function () {
        showDonationWidget();
      });
    }
  }

  function initTriggerForm(url = 'https://widget.give.asia/form-trigger') {
    // find by id
    // replace with iframe
    let triggerForm = document.getElementById('giveasia_triggerDonationForm');
    if (!triggerForm) {
      const iframeStyle = "margin: 0 !important; padding: 0 !important; border: 0 !important; width: 320px !important; height: 440px !important; transform: translateZ(100px) !important;";
      const iframe = createIframe("giveasia_triggerDonationForm", "Trigger Donation Form", url, iframeStyle);
      document.getElementById('giveasia_triggerForm').append(iframe);
    }
  }
  
  function initDonationTrigger() {
    if (options.triggerDonateForm) {
      initTriggerForm(`https://widget.give.asia/form-trigger?charityId=${11002}`);
      return;
    }
    if (options.openButton) {
      initDonateButton();
      return;
    }
  }

  function hideIframe(iframeId, timeoutTime = 0, postMessage = null) {
    const iframe = document.getElementById(iframeId);

    if (postMessage) {
      iframe.contentWindow.postMessage({
        event: postMessage,
      }, '*');
    }

    setTimeout(() => {
      iframe.width = "0";
      iframe.height = "0";
      iframe.style.cssText = "display: hidden !important; margin: 0 !important; padding: 0 !important; border: 0 !important; width: 0 !important; height: 0 !important; position: fixed !important; opacity: 0 !important; top: 0 !important; left: 0 !important; right: 0 !important; bottom: 0 !important; transform: translateZ(100px) !important; z-index: 9999999 !important;";
    }, timeoutTime);
  }

  function showDonationReminderIframe() {
    const iframe = document.getElementById("giveasia_donationReminder");
    iframe.height = "130";
    iframe.style.cssText = "border-radius: 0.375rem !important; display: block !important; margin: 0 !important; padding: 0 !important; border: 0 !important; width: 100% !important; max-width: 400px !important; height: 130px !important; position: fixed !important; opacity: 1 !important; left: 0 !important; bottom: 0 !important; transform: translateZ(100px) !important; z-index: 9999998 !important;";

    iframe.contentWindow.postMessage({
      event: 'showDonationReminder',
    }, '*');
  }

  function preserveScrollTopPosition() {
    const scrollY = window.scrollY;
    setTimeout(() => {
      window.scrollTo(0, scrollY);
    }, 300);
  }

  function updateIframeHeight(height) {
    const iframe = document.getElementById('giveasia_triggerDonationForm');
    const style = `margin: 0 !important; padding: 0 !important; border: 0 !important; width: 320px !important; height: ${height}px !important; transform: translateZ(100px) !important;`;
    iframe.style.cssText = style;
  }

  function handleIframeCommunication(message) {
    switch (message.data.event) {
      case 'closeCompleteDonation':
        // rm data from localStorage
        // hide widget iframe
        localStorage.removeItem('giveasia_donationWidgetData');
        hideIframe("giveasia_donationWidget");
        break;
      case 'closeIncompleteDonation':
        // add data to localStorage
        localStorage.setItem('giveasia_donationWidgetData', JSON.stringify(message.data.data));
        // show donation reminder iframe
        hideIframe("giveasia_donationWidget");
        showDonationReminderIframe();
        break;
      case 'closeReminder':
        // rm from localStorage
        // close reminder iframe
        localStorage.removeItem('giveasia_donationWidgetData');
        hideIframe("giveasia_donationReminder", 250, 'hideDonationReminder');
        break;
      case 'continueDonation':
        // get data from localStorage
        // send data to iframe
        // show donate widget (from iframe postMessage)
        hideIframe("giveasia_donationReminder", 250, 'hideDonationReminder');
        const donationData = JSON.parse(localStorage.getItem('giveasia_donationWidgetData'));
        showDonationWidget(donationData);
        break;
      case 'widgetLoaded':
        console.log('widget loaded');
        // add donation button
        initDonationTrigger();
        initQueryParamsWatch();
        break;
      case 'inputFocus':
        preserveScrollTopPosition();
        break;
      case 'triggerDonationModal':
        hideIframe("giveasia_donationReminder", 250, 'hideDonationReminder');
        const donationState = message.data.data;
        showDonationWidget(donationState);
        break;
      case 'updateIframeHeight':
        updateIframeHeight(message.data.data.height);
        break;
    }
  }

  function handleIframe() {
    localStorage.removeItem('giveasia_donationWidgetData');
    addDonateButtonStyles();
    setViewport();
    if (options.inlineDonateForm) {
      const widgetUrl = `https://${window.location.hostname}${window.location.pathname}`;
      const widgetIframeId = 'giveasia_inlineDonationForm';
      initInlineDonationForm(`https://widget.give.asia/form?charityId=${11002}&widgetUrl=${widgetUrl}&iframeId=${widgetIframeId}`);
    } else {
      initDonationWidget(`https://widget.give.asia/modal?charityId=${11002}`);
    }
    initDonationReminder(`https://widget.give.asia/reminder`);
    window.addEventListener('message', handleIframeCommunication);
  }

  window.addEventListener('load', handleIframe);
};