import FieldStyles from "../styles/FieldStyles.wrn"

import ComponentBaseStyles from "../styles/ComponentBaseStyles.wrn"

component TogglePassword {
  outputs {
    input(payload: { name?: string; value: string | number | boolean | null | object; visible: boolean })
    change(payload: { name?: string; value: string | number | boolean | null | object; visible: boolean })
    toggle(payload: { visible: boolean })
  }

  props {
    size: string = "default"
    color: string = "primary"
    label: string = "Password"
    name: string = "password"
    value: string = ""
    placeholder: string = "Enter your password"
    autocomplete: string = "current-password"
    minlength: string = ""
    maxlength: string = ""
    pattern: string = "(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9]).{8,}"
    fields: unknown[] = []
    visible: boolean = false
    toggleable: boolean = true
    toggleMode: string = "button"
    checkboxLabel: string = "Show password"
    showLabel: string = "Show password"
    hideLabel: string = "Hide password"
    disabled: boolean = false
    readonly: boolean = false
    required: boolean = false
    invalid: boolean = false
    helpText: string = ""
    validationMessage: string = ""
    class: string = ""
}

  state revealed = visible

  functions {
    shared function toggleVisibility() {
      if (disabled || readonly || !toggleable) {
        return
      }
      revealed = !revealed
    }

    shared function fieldId(field, index) {
      return field.id || field.name || name + "-" + index
    }

    shared function fieldName(field, index) {
      return field.name || name + "-" + index
    }
  }

  view {
    <fieldset
      class="wire-component wire-component--color-{color} wire-component--size-{size} wire-next--toggle-password {invalid ? 'wire-next--invalid' : ''} {disabled ? 'wire-next--disabled' : ''} {class}"
      data-wrn-toggle-password
      data-visible="{revealed ? 'true' : 'false'}"
    >
      {#if fields.length}
        <div class="wire-next__password-fields">
          {#each fields as field, index}
            <div class="wire-next__password-field">
              <label for="{fieldId(field, index)}">{field.label || label}</label>
              <div class="wire-next__password-control">
                <input
                  id="{fieldId(field, index)}"
                  type="{revealed ? 'text' : 'password'}"
                  name="{fieldName(field, index)}"
                  value="{field.value || ''}"
                  placeholder="{field.placeholder || placeholder}"
                  autocomplete="{field.autocomplete || autocomplete}"
                  minlength="{field.minlength || minlength}"
                  maxlength="{field.maxlength || maxlength}"
                  pattern="{field.pattern || pattern}"
                  disabled="{disabled || field.disabled}"
                  readonly="{readonly || field.readonly}"
                  required="{required || field.required}"
                  aria-invalid="{invalid ? 'true' : 'false'}"
                  @input="output.input({ name: event.target.name, value: event.target.value, visible: revealed })"
                  @change="output.change({ name: event.target.name, value: event.target.value, visible: revealed })"
                />
                {#if toggleable && toggleMode === "button"}
                  <button
                    type="button"
                    class="wire-next__password-toggle"
                    aria-label="{revealed ? hideLabel : showLabel}"
                    title="{revealed ? hideLabel : showLabel}"
                    aria-pressed="{revealed ? 'true' : 'false'}"
                    disabled="{disabled || readonly}"
                    @click="toggleVisibility(); output.toggle({ visible: revealed })"
                  >
                    <span class="wire-next__password-icon wire-next__password-icon--show" aria-hidden="true"></span>
                  </button>
                {/if}
              </div>
            </div>
          {/each}
        </div>
      {:else}
        <label for="{name}-password">{label}</label>
        <div class="wire-next__password-control">
          <input
            {...attrs}
            id="{name}-password"
            type="{revealed ? 'text' : 'password'}"
            name="{name}"
            value="{value}"
            placeholder="{placeholder}"
            autocomplete="{autocomplete}"
            minlength="{minlength}"
            maxlength="{maxlength}"
            pattern="{pattern}"
            disabled="{disabled}"
            readonly="{readonly}"
            required="{required}"
            aria-invalid="{invalid ? 'true' : 'false'}"
            aria-describedby="{validationMessage ? name + '-validation' : helpText ? name + '-help' : ''}"
            @input="output.input({ value: event.target.value, visible: revealed })"
            @change="output.change({ value: event.target.value, visible: revealed })"
          />
          {#if toggleable && toggleMode === "button"}
            <button
              type="button"
              class="wire-next__password-toggle"
              aria-label="{revealed ? hideLabel : showLabel}"
              title="{revealed ? hideLabel : showLabel}"
              aria-pressed="{revealed ? 'true' : 'false'}"
              disabled="{disabled || readonly}"
              @click="toggleVisibility(); output.toggle({ visible: revealed })"
            >
              <span class="wire-next__password-icon wire-next__password-icon--show" aria-hidden="true"></span>
            </button>
          {/if}
        </div>
      {/if}
      {#if toggleable && toggleMode === "checkbox"}
        <label class="wire-next__password-checkbox">
          <input
            type="checkbox"
            checked="{revealed}"
            disabled="{disabled || readonly}"
            @change="revealed = event.target.checked; output.toggle({ visible: revealed })"
          />
          <span>{checkboxLabel}</span>
        </label>
      {/if}
      {#if helpText && !validationMessage}<small id="{name}-help">{helpText}</small>{/if}
      <small
        id="{name}-validation"
        class="wire-next__validation"
        data-error="{name}"
      >{validationMessage}</small>
    </fieldset>
    <FieldStyles hidden />
    <ComponentBaseStyles hidden />
  }

  style {
    .wire-next--toggle-password {
      display: grid;
      width: 100%;
      min-width: 0;
      max-width: none;
      box-sizing: border-box;
      gap: 0.45rem;
      padding: 0;
      border: 0;
    }

    .wire-next--toggle-password > label {
      color: var(--wire-color-text);
      font-size: 0.75rem;
      font-weight: 600;
    }

    .wire-next__password-fields {
      display: grid;
      gap: 1rem;
    }

    .wire-next__password-field {
      display: grid;
      gap: 0.45rem;
    }

    .wire-next__password-field > label {
      color: var(--wire-color-text);
      font-size: 0.82em;
      font-weight: 750;
    }

    .wire-next__password-control {
      position: relative;
      display: flex;
      min-width: 0;
      align-items: center;
      width: 100%;
    }

    .wire-next__password-control > input {
      width: 100%;
      min-width: 0;
      min-height: 2.75em;
      padding: 0.65em 3em 0.65em 0.8em;
      border: 1px solid var(--wire-color-border);
      border-radius: var(--wire-radius-sm);
      outline: 0;
      color: var(--wire-color-text);
      background: var(--wire-color-bg);
      font: inherit;
      font-size: 0.8125rem;
      transition:
        border-color var(--wire-motion-base) var(--wire-ease-standard),
        box-shadow var(--wire-motion-base) var(--wire-ease-standard);
    }

    .wire-next__password-control > input:focus-visible {
      border-color: var(--wire-component-color);
      box-shadow: 0 0 0 3px color-mix(in srgb, var(--wire-component-color) 18%, transparent);
    }

    .wire-next__password-toggle {
      position: absolute;
      top: 50%;
      right: 0.45em;
      display: grid;
      width: 2em;
      height: 2em;
      padding: 0;
      place-items: center;
      border: 0;
      border-radius: calc(var(--wire-radius-sm) * 0.72);
      color: var(--wire-color-muted);
      background: transparent;
      cursor: pointer;
      transform: translateY(-50%);
    }

    .wire-next__password-toggle:hover,
    .wire-next__password-toggle:focus-visible {
      color: var(--wire-component-color);
      background: color-mix(in srgb, var(--wire-component-color) 10%, transparent);
      outline: 0;
    }

    .wire-next__password-icon {
      display: block;
      width: 1.05em;
      height: 1.05em;
      background: currentColor;
      mask-position: center;
      mask-repeat: no-repeat;
      mask-size: contain;
    }

    .wire-next__password-icon--show {
      mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.06 12.35a1 1 0 0 1 0-.7C3.7 7.6 7.64 5 12 5c4.36 0 8.3 2.6 9.94 6.65a1 1 0 0 1 0 .7C20.3 16.4 16.36 19 12 19c-4.36 0-8.3-2.6-9.94-6.65Z'/%3E%3Ccircle cx='12' cy='12' r='3'/%3E%3C/svg%3E");
    }

    .wire-next__password-toggle[aria-pressed="true"]::after {
      position: absolute;
      width: 1.25em;
      height: 0.12em;
      border-radius: 999px;
      background: currentColor;
      content: "";
      transform: rotate(45deg);
      box-shadow: 0 0 0 1px var(--wire-color-bg);
    }

    .wire-next__password-checkbox {
      display: inline-flex;
      width: fit-content;
      align-items: center;
      gap: 0.55rem;
      color: var(--wire-color-muted);
      font-size: 0.78em;
      cursor: pointer;
    }

    .wire-next__password-checkbox > input {
      width: 1rem;
      height: 1rem;
      margin: 0;
      accent-color: var(--wire-component-color);
    }

    .wire-next--toggle-password > small {
      color: var(--wire-color-muted);
      font-size: 0.72em;
    }
  }
}
