/**
 * EGroupware eTemplate2 - Switch widget
 *
 * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
 * @package etemplate
 * @subpackage api
 * @link https://www.egroupware.org
 * @author Hadi Nategh
 */

import {css, html} from "lit";
import {SlotMixin} from "@lion/core";
import {Et2InputWidget} from "../Et2InputWidget/Et2InputWidget";
import '../Et2Image/Et2Image';
import {SlSwitch} from "@shoelace-style/shoelace";
import shoelace from "../Styles/shoelace";

/**
 * Switch to turn on or off.  Like a checkbox, but different UI.
 *
 * Add "et2SlideSwitch" class to use an alternate UI with images.  Use CSS to set the images:
 *
 */
export class Et2Switch extends Et2InputWidget(SlotMixin(SlSwitch))
{
	static get styles()
	{
		return [
			...shoelace,
			...super.styles,
			css`
			  :host {
				/* Make it line up with the middle of surroundings */
				margin: auto 0px;
				vertical-align: -webkit-baseline-middle;
			  }

			  .switch {
				position: relative;
			  }

			  .toggle__label {
				position: absolute;
				left: 0px;
				border-radius: 50%;
				flex: 0 0 auto;
				display: inline-flex;
				align-items: center;
				justify-content: center;
				width: var(--width);
				height: var(--height);
				margin: 0px;
			  }

			  .switch__thumb {
				z-index: var(--sl-z-index-tooltip);
			  }

			  ::slotted(span.label) {
				width: var(--width);
				display: inline-flex;
				align-items: center;
				height: var(--height);
			  }

			  /* 
			  Use two images instead of normal switch by adding et2_image_switch class
			  see etemplate.css for the rest (slotted label)
			   */

			  :host(.et2SlideSwitch) .switch {
				min-width: 60px;
				--height: var(--sl-input-height-medium);
				border-color: var(--sl-input-border-color);
				border-width: var(--sl-input-border-width);
				border-radius: var(--sl-border-radius-medium);
				border-style: solid;
			  }

			  :host(.et2SlideSwitch) .switch__control {
				visibility: hidden;
			  }

			  :host(.et2SlideSwitch) .switch__label {
				width: 100%;
				height: 100%;
			  }

			  :host(.et2SlideSwitch) ::slotted(.label) {
				flex: 1 1 auto;
			  }
			`,
		];
	}

	static get properties()
	{
		return {
			...super.properties,
			/* label to show when the toggle switch is on */
			toggleOn: {type: String},
			/* label to show when the toggle switch is off */
			toggleOff: {type: String}
		}
	}

	get slots()
	{
		return {
			...super.slots,
			'': () =>
			{
				return this.labelTemplate();
			}
		}
	}

	constructor()
	{
		super();
		this.isSlComponent = true;
		this.toggleOn = '';
		this.toggleOff = '';
	}

	updated(changedProperties)
	{
		if(changedProperties.has("toggleOn") || changedProperties.has("toggleOff") || changedProperties.has("label"))
		{
			if(!this.toggleOn && !this.toggleOff && this._labelNode)
			{
				this._labelNode.childNodes.forEach(c => c.remove());
			}
			else
			{
				if(this._labelNode)
				{
					this._labelNode.querySelector('.on').textContent = this.toggleOn;
					this._labelNode.querySelector('.off').textContent = this.toggleOff;
				}
				this.shadowRoot.querySelector('.switch__label').classList.add('toggle__label');
			}
		}
	}

	set value(new_value : string | boolean)
	{
		this.requestUpdate("checked");
		if(this.toggleOn || this.toggleOf)
		{
			if(new_value)
			{
				this._labelNode?.classList.add('on');
			}
			else
			{
				this._labelNode?.classList.remove('on');
			}
		}
		this.checked = !!new_value;
		return;
	}

	get value ()
	{
		return this.checked;
	}

	private get _labelNode()
	{
		return this.querySelector(".label");
	}

	labelTemplate()
	{
		const labelClass = this.checked ? "label on" : "label";
		return html`
            <span class=${labelClass} aria-label="${this.label}">
				<span class="on">${this.toggleOn}</span>
				<span class="off">${this.toggleOff}</span>
			</span>
		`;
	}
}

customElements.define("et2-switch", Et2Switch);