<script lang="ts" setup>
  import '@simonwep/pickr/dist/themes/monolith.min.css';
  import ColorPicker from '@simonwep/pickr';
  import type { PropType } from 'vue';
  import { computed, onMounted, onUnmounted, ref, unref } from 'vue';

  type Format = Exclude<keyof ColorPicker.HSVaColor, 'clone'>;

  const props = defineProps({
    value: {
      type: String,
      default: '#377dff',
    },
    format: {
      type: String as PropType<ColorPicker.Representation>,
      default: 'HEXA' as ColorPicker.Representation,
    },
    config: {
      type: Object as PropType<ColorPicker.Options>,
    },
    defaultValue: {
      type: String,
      default: '',
    },
  });

  const emit = defineEmits(['update:value']);

  const prefixCls = 'thingskit';

  const colorPickerCls = 'color-picker';

  const picker = ref<Nullable<ColorPicker>>(null);

  const getFormat = computed<Format>(() => {
    return `to${props.format}`;
  });

  const getColor = () => {
    const value = unref(picker)?.getColor();
    return value && value[unref(getFormat)]().toString();
  };

  const onInit = () => {
    unref(picker)?.setColor(props.value);
  };

  const onSave = () => {
    const value = getColor();
    emit('update:value', value);
    unref(picker)?.hide();
  };

  const onClear = () => {
    emit('update:value', props.defaultValue);
    unref(picker)?.hide();
    unref(picker)?.setColor(props.defaultValue);
  };

  const getOption = computed<ColorPicker.Options>(() => {
    const { config = {} } = props;
    return {
      theme: 'monolith',
      components: {
        // Main components
        preview: true,
        opacity: true,
        hue: true,

        // Input / output Options
        interaction: {
          hex: true,
          rgba: true,
          input: true,
          clear: true,
          save: true,
        },
      },
      i18n: {
        'ui:dialog': 'color picker dialog',
        'btn:toggle': 'toggle color picker dialog',
        'btn:swatch': 'color swatch',
        'btn:last-color': '使用以前的颜色',
        'btn:save': '保存',
        'btn:cancel': '取消',
        'btn:clear': '清除',

        // 用于 aria-labels 的字符串
        'aria:btn:save': 'save and close',
        'aria:btn:cancel': 'cancel and close',
        'aria:btn:clear': 'clear and close',
        'aria:input': '颜色输入字段',
        'aria:palette': '颜色选择区域',
        'aria:hue': '色调选择滑块',
        'aria:opacity': '选择滑块',
      },
      ...config,

      el: `.${prefixCls}-${colorPickerCls}`,
    };
  });

  onMounted(() => {
    picker.value = ColorPicker.create(unref(getOption));
    unref(picker)?.on('init', onInit);
    unref(picker)?.on('save', onSave);
    unref(picker)?.on('clear', onClear);
  });

  onUnmounted(() => {
    unref(picker)?.off('init', onInit);
    unref(picker)?.off('save', onSave);
    unref(picker)?.off('clear', onClear);

    unref(picker)?.destroyAndRemove();
  });
</script>

<template>
  <div :class="`${prefixCls}-${colorPickerCls}`"></div>
</template>
