import { injectStyle, observeChildren } from '@descope-ui/common/components-helpers';
import { draggableMixin, createStyleMixin, componentNameValidationMixin } from '../../mixins';
import { createBaseInputClass } from '../../baseClasses/createBaseInputClass';
import { compose } from '../../helpers';
import { getComponentName } from '../../helpers/componentHelpers';

export const componentName = getComponentName('hcaptcha');

const observedAttributes = ['enabled', 'site-key'];

const BaseInputClass = createBaseInputClass({ componentName, baseSelector: ':host > div' });
class RawHcaptcha extends BaseInputClass {
  static get observedAttributes() {
    return observedAttributes.concat(BaseInputClass.observedAttributes || []);
  }

  attributeChangedCallback(attrName, oldValue, newValue) {
    super.attributeChangedCallback?.(attrName, oldValue, newValue);
    if (oldValue !== newValue) {
      if (attrName === 'enabled') {
        this.toggleCaptchaEles(newValue === 'true');
      }
    }
  }

  constructor() {
    super();

    this.attachShadow({ mode: 'open' }).innerHTML = `
    <div class="badge">
      <span id="hcaptcha"></span>
      <input id="hcaptcha-input" type="hidden" name="hcaptcha" required />
      <img src="https://imgs.descope.com/connectors/templates/hcaptcha/hcaptcha-big.png" alt="hcaptcha"/>
    </div>
    <slot></slot>
	`;

    injectStyle(
      `
      :host {
        display: inline-flex;
      }
      :host > div:not(.hidden) {
        display: flex;
      }
      :host #hcaptcha-input {
        display: none;
      }
      :host #hcaptcha .hcaptcha-logo {
        height: 100%;
      }
      :host #hcaptcha {
				width: 100%;
        height: 100%;
			}
      :host img {
        max-width: 100%;
        max-height: 100%;
        object-fit: contain;
      }
      .hidden {
        display: none;
      }
        `,
      this
    );

    this.captchaEle = this.shadowRoot.querySelector('#hcaptcha');
    this.mockCaptchaEle = this.shadowRoot.querySelector('img');
    this.badge = this.shadowRoot.querySelector('.badge');
    this.inputElement = this.shadowRoot.querySelector('input');
  }

  init() {
    super.init?.();

    observeChildren(this, this.updatePreview.bind(this));
    // avoid any possible conflicts with the inner input elements
    this.inputElement.getValidity = null;
    this.inputElement.checkValidity = null;
  }

  toggleCaptchaEles(enabled) {
    if (enabled) {
      this.captchaEle.style.display = '';
      this.mockCaptchaEle.style.display = 'none';
    } else {
      this.captchaEle.style.display = 'none';
      this.mockCaptchaEle.style.display = '';
    }
  }

  updatePreview() {
    this.toggleCaptchaEles(this.enabled);
  }

  getValidity() {
    if (!this.inputElement.value) {
      return { valueMissing: true };
    }

    return {};
  }

  checkValidity() {
    return !!this.inputElement.value;
  }

  get siteKey() {
    return this.getAttribute('site-key');
  }

  get enabled() {
    return this.getAttribute('enabled') === 'true';
  }
}

export const HcaptchaClass = compose(
  createStyleMixin({
    mappings: {
      hostWidth: [{ selector: () => ':host', property: 'width' }],
      hostDirection: { property: 'direction' },
      verticalPadding: [{ property: 'padding-top' }, { property: 'padding-bottom' }],
      horizontalPadding: [{ property: 'padding-left' }, { property: 'padding-right' }],
      maxHeight: [
        { selector: '>img', property: 'height' },
        { selector: '>#hcaptcha', property: 'height' },
      ],
      maxWidth: [
        { selector: '>img', property: 'max-width' },
        { selector: '>hcaptcha', property: 'max-width' },
      ],
    },
  }),
  draggableMixin,
  componentNameValidationMixin
)(RawHcaptcha);
