/**
 * FurryPlace Plugin - Login Modal Captcha
 *
 * This plugin adds a captcha widget to the login modal and disables
 * all login buttons until the captcha is completed.
 */

(function() {
  'use strict';

  // Get configuration
  const config = window.FURRYPLACE_CAPTCHA_CONFIG?.login || { enabled: false };

  if (!config.enabled || !config.siteKey) {
    console.log('[Login Captcha] Captcha not enabled for login modal');
    return;
  }

  let hcaptchaLoaded = false;
  let currentToken = null;
  let widgetId = null;

  // Load hCaptcha script
  function loadHCaptchaScript() {
    return new Promise((resolve, reject) => {
      if (window.hcaptcha) {
        hcaptchaLoaded = true;
        resolve();
        return;
      }

      const script = document.createElement('script');
      script.src = 'https://js.hcaptcha.com/1/api.js?render=explicit';
      script.async = true;
      script.defer = true;
      script.onload = () => {
        console.log('[Login Captcha] hCaptcha script loaded');
        hcaptchaLoaded = true;
        resolve();
      };
      script.onerror = () => {
        console.error('[Login Captcha] Failed to load hCaptcha script');
        reject(new Error('Failed to load hCaptcha script'));
      };
      document.head.appendChild(script);
    });
  }

  // Wait for hCaptcha API to be ready
  function waitForHCaptcha() {
    return new Promise((resolve) => {
      const check = () => {
        if (window.hcaptcha && window.hcaptcha.render) {
          resolve();
        } else {
          setTimeout(check, 100);
        }
      };
      check();
    });
  }

  // Find login buttons in modal
  function findLoginButtons(modal) {
    const buttons = [];

    // Find all links with /auth/ in href (OAuth buttons)
    const authLinks = modal.querySelectorAll('a[href*="/auth/"]');

    for (const el of authLinks) {
      const href = el.href || '';

      // Only include actual OAuth provider links
      if (
        href.includes('/auth/google') ||
        href.includes('/auth/twitch') ||
        href.includes('/auth/discord') ||
        href.includes('/auth/github')
      ) {
        buttons.push(el);
      }
    }

    // Also check for explicit login/register buttons (not just links)
    const loginButtons = modal.querySelectorAll('button[type="submit"], button.btn-primary');
    for (const btn of loginButtons) {
      const text = btn.textContent.toLowerCase();
      if (text.includes('login') || text.includes('sign in') || text.includes('register')) {
        buttons.push(btn);
      }
    }

    return buttons;
  }

  // Disable all login buttons
  function disableLoginButtons(buttons) {
    for (const btn of buttons) {
      btn.disabled = true;
      btn.style.opacity = '0.5';
      btn.style.cursor = 'not-allowed';
      btn.dataset.captchaDisabled = 'true';

      // Store original click handler and prevent clicks
      btn.addEventListener('click', preventClick, { capture: true });
    }
  }

  // Enable all login buttons and update URLs with captcha token
  function enableLoginButtons(buttons, token = null) {
    for (const btn of buttons) {
      btn.disabled = false;
      btn.style.opacity = '1';
      btn.style.cursor = 'pointer';
      delete btn.dataset.captchaDisabled;

      // Update URL with captcha token if provided
      if (token && btn.href) {
        const url = new URL(btn.href, window.location.origin);
        url.searchParams.set('token', token);
        btn.href = url.toString();
      }

      // Remove click prevention
      btn.removeEventListener('click', preventClick, { capture: true });
    }
  }

  // Prevent click event
  function preventClick(e) {
    if (e.target.dataset.captchaDisabled === 'true') {
      e.preventDefault();
      e.stopPropagation();
      e.stopImmediatePropagation();
      alert('Please complete the captcha verification first');
      return false;
    }
  }

  // Create captcha widget container
  function createCaptchaContainer() {
    const container = document.createElement('div');
    container.className = 'login-captcha-container';
    container.style.cssText = `
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 0.5rem;
      width: 100%;
    `;

    const label = document.createElement('p');
    label.textContent = 'Please verify you are human to continue:';
    label.style.cssText = `
      margin: 0 0 0.5rem 0;
      font-size: 0.875rem;
      color: #000000;
      text-align: center;
    `;
    container.appendChild(label);

    const widgetContainer = document.createElement('div');
    widgetContainer.className = 'hcaptcha-widget';
    container.appendChild(widgetContainer);

    return { container, widgetContainer };
  }

  // Inject captcha into login modal
  async function injectCaptchaIntoModal(modal) {
    // Check if already injected
    if (modal.querySelector('.login-captcha-container')) {
      console.log('[Login Captcha] Captcha already injected in this modal');
      return;
    }

    console.log('[Login Captcha] Injecting captcha into login modal');

    // Find login buttons
    const buttons = findLoginButtons(modal);
    if (buttons.length === 0) {
      console.log('[Login Captcha] No login buttons found in modal');
      return;
    }

    console.log('[Login Captcha] Found', buttons.length, 'login button(s)');

    // Disable buttons initially
    disableLoginButtons(buttons);

    // Create captcha container
    const { container, widgetContainer } = createCaptchaContainer();

    // Find a good place to insert the captcha
    // Look for the container that holds the buttons
    let buttonsContainer = null;

    // Try to find the parent container of the buttons (usually has flex classes)
    for (const btn of buttons) {
      let parent = btn.parentElement;
      while (parent && parent !== modal) {
        if (parent.classList.contains('flex') || parent.classList.contains('gap-2')) {
          buttonsContainer = parent;
          break;
        }
        parent = parent.parentElement;
      }
      if (buttonsContainer) break;
    }

    // Insert captcha inside the buttons container after the last button
    if (buttonsContainer) {
      // Find the last OAuth button
      const lastButton = buttons[buttons.length - 1];

      // Remove any empty divs that might be placeholders
      const emptyDivs = buttonsContainer.querySelectorAll('div.mt-2.flex.flex-col.items-center.gap-1');
      emptyDivs.forEach(div => {
        if (div.children.length === 0 || (div.children.length <= 2 && div.textContent.trim() === '')) {
          div.remove();
        }
      });

      // Insert after the last button
      if (lastButton.nextSibling) {
        buttonsContainer.insertBefore(container, lastButton.nextSibling);
      } else {
        buttonsContainer.appendChild(container);
      }
    } else {
      // Fallback: try to insert inside the form after buttons
      const form = modal.querySelector('form');
      if (form) {
        // Find last button and insert after it
        const lastButton = buttons[buttons.length - 1];
        if (lastButton.parentElement) {
          if (lastButton.nextSibling) {
            lastButton.parentElement.insertBefore(container, lastButton.nextSibling);
          } else {
            lastButton.parentElement.appendChild(container);
          }
        } else {
          form.appendChild(container);
        }
      } else {
        // Last resort: append to modal body
        const body = modal.querySelector('.modal-box') || modal;
        body.appendChild(container);
      }
    }

    // Wait for hCaptcha to be ready
    await waitForHCaptcha();

    // Render hCaptcha widget
    try {
      widgetId = window.hcaptcha.render(widgetContainer, {
        sitekey: config.siteKey,
        theme: config.theme || 'dark',
        size: config.size || 'normal',
        callback: function(token) {
          currentToken = token;
          console.log('[Login Captcha] Captcha verified, token:', token.substring(0, 20) + '...');

          // Update button URLs with the token
          enableLoginButtons(buttons, token);

          // Store token for backend requests
          sessionStorage.setItem('login_captcha_token', token);

          // Trigger custom event
          window.dispatchEvent(new CustomEvent('furryplace:captcha:verified', {
            detail: { token, verificationPoint: 'login' }
          }));
        },
        'error-callback': function() {
          console.error('[Login Captcha] Captcha error');
          currentToken = null;
          disableLoginButtons(buttons);
          sessionStorage.removeItem('login_captcha_token');
        },
        'expired-callback': function() {
          console.warn('[Login Captcha] Captcha expired');
          currentToken = null;
          disableLoginButtons(buttons);
          sessionStorage.removeItem('login_captcha_token');
        }
      });

      console.log('[Login Captcha] hCaptcha widget rendered');
    } catch (error) {
      console.error('[Login Captcha] Failed to render hCaptcha:', error);
      // On error, enable buttons so user isn't stuck
      enableLoginButtons(buttons);
    }
  }

  // Watch for login modals appearing
  function watchForLoginModals() {
    // Create a mutation observer to watch for modals
    const observer = new MutationObserver((mutations) => {
      for (const mutation of mutations) {
        // Check added nodes
        for (const node of mutation.addedNodes) {
          if (node.nodeType === 1) { // Element node
            // Check if it's a dialog/modal
            if (node.tagName === 'DIALOG' || node.classList?.contains('modal')) {
              checkAndInjectCaptcha(node);
            }

            // Check children for dialogs
            const dialogs = node.querySelectorAll?.('dialog, .modal') || [];
            for (const dialog of dialogs) {
              checkAndInjectCaptcha(dialog);
            }
          }
        }

        // Check for 'open' attribute changes on dialogs
        if (mutation.type === 'attributes' && mutation.attributeName === 'open') {
          const target = mutation.target;
          if (target.tagName === 'DIALOG' && target.open) {
            checkAndInjectCaptcha(target);
          }
        }
      }
    });

    observer.observe(document.body, {
      childList: true,
      subtree: true,
      attributes: true,
      attributeFilter: ['open']
    });

    console.log('[Login Captcha] Watching for login modals');
  }

  // Check if modal is a login modal and inject captcha
  async function checkAndInjectCaptcha(modal) {
    // Wait a bit for modal content to be fully rendered
    await new Promise(resolve => setTimeout(resolve, 100));

    console.log('[Login Captcha] Checking modal for login buttons...', modal);

    // Check if modal contains login-related content
    const buttons = findLoginButtons(modal);
    console.log('[Login Captcha] Found buttons:', buttons);

    if (buttons.length > 0) {
      injectCaptchaIntoModal(modal);
    } else {
      console.log('[Login Captcha] No login buttons found in this modal');
    }
  }

  // Initialize plugin
  async function init() {
    console.log('[Login Captcha] Initializing login modal captcha plugin...');

    try {
      // Load hCaptcha script
      await loadHCaptchaScript();

      // Start watching for modals
      if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', watchForLoginModals);
      } else {
        watchForLoginModals();
      }

      // Also check existing modals
      const existingModals = document.querySelectorAll('dialog, .modal');
      for (const modal of existingModals) {
        if (modal.open || modal.classList.contains('modal-open')) {
          checkAndInjectCaptcha(modal);
        }
      }

      // Register SDK captcha callback for programmatic requests
      if (window.FurryPlaceSDK) {
        window.FurryPlaceSDK.registerCaptchaCallback('login', async () => {
          // Return stored token if available
          const storedToken = sessionStorage.getItem('login_captcha_token');
          if (storedToken) {
            return storedToken;
          }

          // Otherwise return current token from widget
          return currentToken;
        });

        // Also register for Google OAuth
        window.FurryPlaceSDK.registerCaptchaCallback('googleOAuth', async () => {
          const storedToken = sessionStorage.getItem('login_captcha_token');
          if (storedToken) {
            return storedToken;
          }
          return currentToken;
        });

        // Also register for register
        window.FurryPlaceSDK.registerCaptchaCallback('register', async () => {
          const storedToken = sessionStorage.getItem('login_captcha_token');
          if (storedToken) {
            return storedToken;
          }
          return currentToken;
        });

        console.log('[Login Captcha] Registered SDK captcha callbacks');
      }

      // Intercept fetch requests to inject captcha token
      const originalFetch = window.fetch;
      window.fetch = async function(url, options) {
        const urlString = typeof url === 'string' ? url : url.toString();

        // Check if this is a login or auth request
        if (urlString.includes('/login') || urlString.includes('/auth/')) {
          const token = sessionStorage.getItem('login_captcha_token');
          if (token && options) {
            // Add token to request body if it's a POST
            if (options.method === 'POST' && options.body) {
              try {
                const bodyData = typeof options.body === 'string' ? JSON.parse(options.body) : options.body;
                bodyData.captchaToken = token;
                options.body = JSON.stringify(bodyData);
              } catch (e) {
                console.warn('[Login Captcha] Could not inject captcha token into request body');
              }
            }
          }
        }

        return originalFetch.call(this, url, options);
      };

      // Intercept links to /auth/google to add token as query param
      document.addEventListener('click', function(e) {
        let target = e.target;
        while (target && target !== document) {
          if (target.tagName === 'A' && target.href && target.href.includes('/auth/google')) {
            const token = sessionStorage.getItem('login_captcha_token');
            if (token) {
              e.preventDefault();
              const url = new URL(target.href);
              url.searchParams.set('token', token);
              window.location.href = url.toString();
            }
            return;
          }
          target = target.parentElement;
        }
      }, true);

      console.log('[Login Captcha] Plugin initialized');
    } catch (error) {
      console.error('[Login Captcha] Failed to initialize:', error);
    }
  }

  // Wait for SDK if needed, then init
  if (window.FurryPlaceSDK) {
    init();
  } else {
    const waitForSDK = () => {
      if (window.FurryPlaceSDK) {
        init();
      } else {
        setTimeout(waitForSDK, 100);
      }
    };
    waitForSDK();
  }
})();
