<script setup lang="ts">
import {Switch} from "@headlessui/vue";
import {twMerge, twJoin} from "tailwind-merge";

import type {Props} from "./types";

const props = withDefaults(defineProps<Props>(), {
  disabled: false,
  size: 'md',
  switchClass: '',
  color: 'blue',
  onIcon: null,
  onIconClass: null,
  offIcon: null,
  offIconClass: null,
  activeClass: '',
  inactiveClass: '',
  activeContainerClass: '',
  inactiveContainerClass: ''
})
const active = defineModel<boolean>({required: true})
const switchClass = computed(() => {
  return twMerge(twJoin(
    ui.base,
    ui.size[props.size],
    ui.rounded,
    ui.ring,
    props.disabled ? 'opacity-20' : '',
    // color.value && (active.value ? ui.value.active : ui.value.inactive).replaceAll('{color}', color.value)
    props.color && (active.value ? ui.active[props.color] : ui.inactive),
    active.value ? props.activeClass : props.inactiveClass
  ), props.switchClass)
})
const containerClass = computed(() => {
  return twMerge(twJoin(
    ui.container.base,
    ui.container.size[props.size],
    (active.value ? ui.container.active[props.size] : ui.container.inactive),
    active.value ? props.activeContainerClass : props.inactiveContainerClass
  ))
})
const onIconClassFormatted = computed(() => {
  return twMerge(twJoin(
    ui.icon.size[props.size],
    props.onIconClass
    // props.color && ui.icon.on
  ))
})
const offIconClassFormatted = computed(() => {
  return twMerge(twJoin(
    ui.icon.size[props.size],
    props.offIconClass
    // color && ui.value.icon.off.replaceAll('{color}', color.value)
  ))
})


const ui = {
  "base": "relative inline-flex flex-shrink-0 border-2 border-transparent disabled:cursor-not-allowed disabled:opacity-50 focus:outline-none transition ease-in-out",
  "rounded": "rounded-full",
  "ring": "focus-visible:ring-2 focus-visible:ring-blue-500 dark:focus-visible:ring-blue-400 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:focus-visible:ring-offset-gray-900",
  "active": {
    "blue": "bg-blue-700 dark:bg-blue-500",
    "green": "bg-green"
  },
  "inactive": "bg-gray-200 dark:bg-gray-200/20",
  "size": {
    "2xs": "h-3 w-5",
    "xs": "h-3.5 w-6",
    "sm": "h-4 w-7",
    "md": "h-5 w-9",
    "lg": "h-6 w-11",
    "xl": "h-7 w-[3.25rem]",
    "2xl": "h-8 w-[3.75rem]"
  },
  "container": {
    "base": "pointer-events-none relative inline-block rounded-full bg-white dark:bg-gray-900 shadow transform ring-0 transition ease-in-out duration-200",
    "active": {
      "2xs": "translate-x-2 rtl:-translate-x-2",
      "xs": "translate-x-2.5 rtl:-translate-x-2.5",
      "sm": "translate-x-3 rtl:-translate-x-3",
      "md": "translate-x-4 rtl:-translate-x-4",
      "lg": "translate-x-5 rtl:-translate-x-5",
      "xl": "translate-x-6 rtl:-translate-x-6",
      "2xl": "translate-x-7 rtl:-translate-x-7"
    },
    "inactive": "translate-x-0 rtl:-translate-x-0",
    "size": {
      "2xs": "h-2 w-2",
      "xs": "h-2.5 w-2.5",
      "sm": "h-3 w-3",
      "md": "h-4 w-4",
      "lg": "h-5 w-5",
      "xl": "h-6 w-6",
      "2xl": "h-7 w-7"
    }
  },
  "icon": {
    "base": "absolute inset-0 h-full w-full flex items-center justify-center transition-opacity",
    "active": "opacity-100 ease-in duration-200",
    "inactive": "opacity-0 ease-out duration-100",
    "size": {
      "2xs": "h-2 w-2",
      "xs": "h-2 w-2",
      "sm": "h-2 w-2",
      "md": "h-3 w-3",
      "lg": "h-4 w-4",
      "xl": "h-5 w-5",
      "2xl": "h-6 w-6"
    },
    // "on": "text-{color}-500 dark:text-{color}-400",
    // "off": "text-gray-400 dark:text-gray-500"
  },
}

</script>

<template>
  <Switch
    v-model="active"
    :disabled="disabled"
    :class="switchClass"
    aria-label="Switch"
    style="border-color: transparent"
  >
    <span :class="containerClass">
      <span
        v-if="onIcon"
        :class="[active ? ui.icon.active : ui.icon.inactive, ui.icon.base]"
        aria-hidden="true"
      >
        <component
          :is="onIcon"
          :class="onIconClassFormatted"
          filled
          :font-controlled="false"
        />
      </span>
      <span
        v-if="offIcon"
        :class="[active ? ui.icon.inactive : ui.icon.active, ui.icon.base]"
        aria-hidden="true"
      >
        <component
          :is="offIcon"
          :class="offIconClassFormatted"
          filled
          :font-controlled="false"
        />
      </span>
    </span>
  </Switch>
</template>

<style scoped>

</style>
