import { Component, Prop, h, Event, Method, State, Element, Watch } from '@stencil/core';
import { __ } from '@wordpress/i18n';
import { FormSubmitController } from '../../../functions/form-data';
let id = 0;
export class ScChoice {
  constructor() {
    this.inputId = `choice-${++id}`;
    this.labelId = `choice-label-${id}`;
    /** Does the choice have focus */
    this.hasFocus = false;
    /** Does the choice have focus */
    this.isStacked = false;
    /** The size. */
    this.size = 'medium';
    /** The choice name attribute */
    this.type = 'radio';
    /** Is the choice disabled */
    this.disabled = false;
    /** Draws the choice in a checked state. */
    this.checked = false;
    /** Is this required */
    this.required = false;
    /** This will be true when the control is in an invalid state. Validity is determined by the `required` prop. */
    this.invalid = false;
    /** Show the label */
    this.showLabel = true;
    /** Show the price */
    this.showPrice = true;
    /** Show the radio/checkbox control */
    this.showControl = true;
  }
  /** Simulates a click on the choice. */
  async triggerClick() {
    this.input.click();
  }
  /** Checks for validity and shows the browser's validation message if the control is invalid. */
  async reportValidity() {
    this.invalid = !this.input.checkValidity();
    if (this.required) {
      const choices = this.getAllChoices();
      if (!choices.some(c => c.checked)) {
        this.input.setCustomValidity(this.type === 'radio' ? __('Please choose one.', 'surecart') : __('Please choose at least one.', 'surecart'));
        this.invalid = !this.input.checkValidity();
      }
      else {
        this.input.setCustomValidity('');
        this.invalid = !this.input.checkValidity();
      }
    }
    return this.input.reportValidity();
  }
  handleCheckedChange() {
    this.input.setCustomValidity('');
    if (this.type === 'radio' && this.checked) {
      this.getSiblingChoices().map(choice => (choice.checked = false));
    }
    this.input.checked = this.checked;
  }
  handleClick() {
    if (this.type === 'checkbox') {
      this.checked = !this.checked;
    }
    else {
      this.checked = true;
    }
    // we only want to emit this when an action is actually taken
    this.scChange.emit(this.input.checked);
  }
  handleBlur() {
    this.hasFocus = false;
    this.scBlur.emit();
  }
  handleFocus() {
    this.hasFocus = true;
    this.scFocus.emit();
  }
  /** Sets a custom validation message. If `message` is not empty, the field will be considered invalid. */
  async setCustomValidity(message) {
    this.input.setCustomValidity(message);
    this.invalid = !this.input.checkValidity();
  }
  getAllChoices() {
    const choiceGroup = this.el.closest('sc-choices') || this.el.parentElement;
    // Radios must be part of a radio group
    if (!choiceGroup) {
      return [];
    }
    return [...choiceGroup.querySelectorAll('sc-choice')].filter((choice) => choice.name === this.name);
  }
  getSiblingChoices() {
    return this.getAllChoices().filter(choice => choice !== this.el);
  }
  handleKeyDown(event) {
    if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(event.key)) {
      const choices = this.getAllChoices().filter(choice => !choice.disabled);
      const incr = ['ArrowUp', 'ArrowLeft'].includes(event.key) ? -1 : 1;
      let index = choices.indexOf(this.el) + incr;
      if (index < 0)
        index = choices.length - 1;
      if (index > choices.length - 1)
        index = 0;
      this.getAllChoices().map(choice => (choice.checked = false));
      choices[index].focus();
      choices[index].checked = true;
      event.preventDefault();
    }
  }
  // Prevent clicks on the label from briefly blurring the input
  handleMouseDown(event) {
    event.preventDefault();
    this.input.focus();
  }
  componentDidLoad() {
    this.handleResize();
    this.formController = new FormSubmitController(this.el, {
      value: (control) => (control.checked ? control.value : undefined),
    }).addFormData();
  }
  disconnectedCallback() {
    var _a;
    (_a = this.formController) === null || _a === void 0 ? void 0 : _a.removeFormData();
  }
  handleResize() {
    if (!(window === null || window === void 0 ? void 0 : window.ResizeObserver)) {
      return;
    }
    const resizeObserver = new window.ResizeObserver(entries => {
      for (let entry of entries) {
        if (entry.contentBoxSize) {
          const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;
          setTimeout(() => (this.isStacked = (contentBoxSize === null || contentBoxSize === void 0 ? void 0 : contentBoxSize.inlineSize) < 250), 0);
        }
      }
    });
    resizeObserver.observe(this.el);
  }
  handleSlotChange() {
    this.hasPrice = !!this.el.querySelector('[slot="price"]');
    this.hasPer = !!this.el.querySelector('[slot="per"]');
    this.hasDescription = !!this.el.querySelector('[slot="description"]');
    this.hasDefaultSlot = !!this.el.querySelector('[slot="default"]');
  }
  render() {
    return (h("label", { part: "base", class: {
        'choice': true,
        'choice--checked': this.checked,
        'choice--disabled': this.disabled,
        'choice--focused': this.hasFocus,
        'choice--layout-columns': !this.isStacked,
        [`choice--size-${this.size}`]: true,
      }, htmlFor: this.inputId, onKeyDown: e => this.handleKeyDown(e), onMouseDown: e => this.handleMouseDown(e) },
      h("span", { part: "control", class: {
          choice__control: true,
          choice__checkbox: this.type === 'checkbox',
          choice__radio: this.type === 'radio',
        }, hidden: !this.showControl },
        h("span", { part: "checked-icon", class: "choice__icon" }, this.type === 'checkbox' ? (h("svg", { viewBox: "0 0 16 16" },
          h("g", { stroke: "none", "stroke-width": "1", fill: "none", "fill-rule": "evenodd", "stroke-linecap": "round" },
            h("g", { stroke: "currentColor", "stroke-width": "2" },
              h("g", { transform: "translate(3.428571, 3.428571)" },
                h("path", { d: "M0,5.71428571 L3.42857143,9.14285714" }),
                h("path", { d: "M9.14285714,0 L3.42857143,9.14285714" })))))) : (h("svg", { viewBox: "0 0 16 16" },
          h("g", { stroke: "none", "stroke-width": "1", fill: "none", "fill-rule": "evenodd" },
            h("g", { fill: "currentColor" },
              h("circle", { cx: "8", cy: "8", r: "3.42857143" })))))),
        h("input", { id: this.inputId, ref: el => (this.input = el), type: this.type, name: this.name, value: this.value, checked: this.checked, disabled: this.disabled, "aria-checked": this.checked ? 'true' : 'false', "aria-disabled": this.disabled ? 'true' : 'false', "aria-labelledby": this.labelId, 
          // required={this.required}
          onClick: () => this.handleClick(), onBlur: () => this.handleBlur(), onFocus: () => this.handleFocus() })),
      h("span", { part: "label", id: this.labelId, class: "choice__label" },
        h("span", { class: "choice__label-text", hidden: !this.showLabel },
          h("span", { class: "choice__title", part: "title" },
            h("slot", { onSlotchange: () => this.handleSlotChange() })),
          h("span", { class: "choice__description description", part: "description", hidden: !this.hasDescription },
            h("slot", { name: "description", onSlotchange: () => this.handleSlotChange() }))),
        h("span", { class: "choice__price", hidden: !this.showPrice || (!this.hasPrice && !this.hasPer) },
          h("span", { class: "choice__title" },
            h("slot", { name: "price", onSlotchange: () => this.handleSlotChange() })),
          ' ',
          h("span", { class: "choice__description" },
            h("slot", { name: "per", onSlotchange: () => this.handleSlotChange() }))))));
  }
  static get is() { return "sc-choice"; }
  static get encapsulation() { return "shadow"; }
  static get originalStyleUrls() { return {
    "$": ["sc-choice.scss"]
  }; }
  static get styleUrls() { return {
    "$": ["sc-choice.css"]
  }; }
  static get properties() { return {
    "name": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "The choice name attribute"
      },
      "attribute": "name",
      "reflect": false
    },
    "size": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "'small' | 'medium' | 'large'",
        "resolved": "\"large\" | \"medium\" | \"small\"",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "The size."
      },
      "attribute": "size",
      "reflect": false,
      "defaultValue": "'medium'"
    },
    "value": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "The choice value"
      },
      "attribute": "value",
      "reflect": true
    },
    "type": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "'radio' | 'checkbox'",
        "resolved": "\"checkbox\" | \"radio\"",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "The choice name attribute"
      },
      "attribute": "type",
      "reflect": false,
      "defaultValue": "'radio'"
    },
    "disabled": {
      "type": "boolean",
      "mutable": true,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Is the choice disabled"
      },
      "attribute": "disabled",
      "reflect": true,
      "defaultValue": "false"
    },
    "checked": {
      "type": "boolean",
      "mutable": true,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Draws the choice in a checked state."
      },
      "attribute": "checked",
      "reflect": true,
      "defaultValue": "false"
    },
    "required": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Is this required"
      },
      "attribute": "required",
      "reflect": true,
      "defaultValue": "false"
    },
    "invalid": {
      "type": "boolean",
      "mutable": true,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "This will be true when the control is in an invalid state. Validity is determined by the `required` prop."
      },
      "attribute": "invalid",
      "reflect": true,
      "defaultValue": "false"
    },
    "showLabel": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Show the label"
      },
      "attribute": "show-label",
      "reflect": false,
      "defaultValue": "true"
    },
    "showPrice": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Show the price"
      },
      "attribute": "show-price",
      "reflect": false,
      "defaultValue": "true"
    },
    "showControl": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Show the radio/checkbox control"
      },
      "attribute": "show-control",
      "reflect": false,
      "defaultValue": "true"
    }
  }; }
  static get states() { return {
    "hasFocus": {},
    "isStacked": {},
    "hasDefaultSlot": {},
    "hasPrice": {},
    "hasPer": {},
    "hasDescription": {}
  }; }
  static get events() { return [{
      "method": "scBlur",
      "name": "scBlur",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "Emitted when the control loses focus."
      },
      "complexType": {
        "original": "void",
        "resolved": "void",
        "references": {}
      }
    }, {
      "method": "scChange",
      "name": "scChange",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "Emitted when the control's checked state changes."
      },
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      }
    }, {
      "method": "scFocus",
      "name": "scFocus",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "Emitted when the control gains focus."
      },
      "complexType": {
        "original": "void",
        "resolved": "void",
        "references": {}
      }
    }]; }
  static get methods() { return {
    "triggerClick": {
      "complexType": {
        "signature": "() => Promise<void>",
        "parameters": [],
        "references": {
          "Promise": {
            "location": "global"
          }
        },
        "return": "Promise<void>"
      },
      "docs": {
        "text": "Simulates a click on the choice.",
        "tags": []
      }
    },
    "reportValidity": {
      "complexType": {
        "signature": "() => Promise<boolean>",
        "parameters": [],
        "references": {
          "Promise": {
            "location": "global"
          }
        },
        "return": "Promise<boolean>"
      },
      "docs": {
        "text": "Checks for validity and shows the browser's validation message if the control is invalid.",
        "tags": []
      }
    },
    "setCustomValidity": {
      "complexType": {
        "signature": "(message: string) => Promise<void>",
        "parameters": [{
            "tags": [],
            "text": ""
          }],
        "references": {
          "Promise": {
            "location": "global"
          }
        },
        "return": "Promise<void>"
      },
      "docs": {
        "text": "Sets a custom validation message. If `message` is not empty, the field will be considered invalid.",
        "tags": []
      }
    }
  }; }
  static get elementRef() { return "el"; }
  static get watchers() { return [{
      "propName": "checked",
      "methodName": "handleCheckedChange"
    }]; }
}
