/**
 * This file is part of the SplendidBear Websites' projects.
 *
 * Copyright (c) 2026 @ www.splendidbear.org
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

import React, { Fragment, useCallback, useEffect, useMemo, useState } from 'react';
import { func, node, string } from 'prop-types';

const CAPTCHA_STORAGE_KEY = 'mineseeker_captcha_verified';
const CAPTCHA_TOKEN_KEY = 'mineseeker_captcha_token';
const RECAPTCHA_ACTION = 'mineseeker_play';

const CaptchaOverlay = ({ siteKey, onVerified, children }) => {
  const [verified, setVerified] = useState(false);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(false);

  const handleToken = useCallback(token => {
    const wrapper = document.getElementById('mine-wrapper');
    if (wrapper) {
      wrapper.dataset.captchaToken = token;
    }
    sessionStorage.setItem(CAPTCHA_TOKEN_KEY, token);
    sessionStorage.setItem(CAPTCHA_STORAGE_KEY, Date.now().toString());
    setVerified(true);
    onVerified?.();
  }, [onVerified]);

  const buttonClasses = useMemo(() => [
    'captcha-button',
    error && 'captcha-button--error',
    loading && 'captcha-button--loading',
  ].filter(Boolean).join(' '), [error, loading]);

  useEffect(() => {
    const storedToken = sessionStorage.getItem(CAPTCHA_TOKEN_KEY);
    const storedTime = sessionStorage.getItem(CAPTCHA_STORAGE_KEY);

    if (storedToken && storedTime) {
      const elapsed = (Date.now() - parseInt(storedTime)) / 1000;
      if (110 > elapsed) {
        const wrapper = document.getElementById('mine-wrapper');
        if (wrapper) {
          wrapper.dataset.captchaToken = storedToken;
        }
        setVerified(true);
        onVerified?.();
        return;
      }
    }

    if (window.grecaptcha) {
      window.grecaptcha.ready(() => {
        window.grecaptcha
          .execute(siteKey, { action: RECAPTCHA_ACTION })
          .then(token => {
            handleToken(token);
          })
          .catch(() => {
            setError(true);
          });
      });
    }
  }, [siteKey, onVerified, handleToken]);


  const handleClick = () => {
    setLoading(true);
    setError(false);

    window.grecaptcha.ready(() => {
      window.grecaptcha
        .execute(siteKey, { action: RECAPTCHA_ACTION })
        .then(token => {
          handleToken(token);
          setLoading(false);
        })
        .catch(() => {
          setLoading(false);
          setError(true);
          setTimeout(() => setError(false), 2000);
        });
    });
  };

  if (verified) {
    return <Fragment>{children}</Fragment>;
  }

  return (
    <div className="captcha-overlay">
      <div className="captcha-content">
        <div className="captcha-icon">
          <i className="fa fa-shield-halved" />
        </div>
        <h1 className="captcha-title">Ready to Play?</h1>
        <p className="captcha-description">
          Click below to verify you&apos;re human and start playing.
        </p>
        <button
          className={buttonClasses}
          onClick={handleClick}
          disabled={loading}
        >
          <i className={`fa ${loading ? 'fa-spinner fa-spin' : error ? 'fa-exclamation-circle' : 'fa-play'}`} />
          {loading ? 'Verifying...' : error ? 'Try Again' : 'Start Playing'}
        </button>
      </div>
    </div>
  );
};

export default CaptchaOverlay;

CaptchaOverlay.propTypes = {
  siteKey:    string.isRequired,
  onVerified: func,
  children:   node,
};
