// Styles
import './VColorPickerPreview.sass'

// Components
import { VBtn } from '@/components/VBtn'
import { VSlider } from '@/components/VSlider'

// Composables
import { makeComponentProps } from '@/composables/component'
import { IconValue } from '@/composables/icons'
import { useLocale } from '@/composables/locale'

// Utilities
import { onUnmounted, toRef } from 'vue'
import { nullColor } from './util'
import {
  defineComponent,
  HSVtoCSS,
  parseColor,
  propsFactory,
  RGBtoHSV,
  SUPPORTS_EYE_DROPPER,
  useRender,
} from '@/util'

// Types
import type { PropType } from 'vue'
import type { HSV } from '@/util'

export const makeVColorPickerPreviewProps = propsFactory({
  color: {
    type: Object as PropType<HSV | null>,
  },
  disabled: Boolean,
  readonly: Boolean,
  hideAlpha: Boolean,
  hideEyeDropper: Boolean,
  eyeDropperIcon: {
    type: IconValue,
    default: '$eyeDropper',
  },

  ...makeComponentProps(),
}, 'VColorPickerPreview')

export const VColorPickerPreview = defineComponent({
  name: 'VColorPickerPreview',

  props: makeVColorPickerPreviewProps(),

  emits: {
    'update:color': (color: HSV) => true,
  },

  setup (props, { emit }) {
    const { t } = useLocale()

    const abortController = new AbortController()

    const isInteractive = toRef(() => !props.disabled && !props.readonly)

    onUnmounted(() => abortController.abort())

    async function openEyeDropper () {
      if (!SUPPORTS_EYE_DROPPER || !isInteractive.value) return

      const eyeDropper = new window.EyeDropper()
      try {
        const result = await eyeDropper.open({ signal: abortController.signal })
        const colorHexValue = RGBtoHSV(parseColor(result.sRGBHex))
        emit('update:color', { ...(props.color ?? nullColor), ...colorHexValue })
      } catch (e) {}
    }

    useRender(() => (
      <div
        class={[
          'v-color-picker-preview',
          {
            'v-color-picker-preview--hide-alpha': props.hideAlpha,
          },
          props.class,
        ]}
        style={ props.style }
      >
        { SUPPORTS_EYE_DROPPER && !props.hideEyeDropper && (
          <div class="v-color-picker-preview__eye-dropper" key="eyeDropper">
            <VBtn
              aria-label={ t('$vuetify.colorPicker.ariaLabel.eyedropper') }
              density="comfortable"
              disabled={ props.disabled }
              readonly={ props.readonly }
              icon={ props.eyeDropperIcon }
              variant="plain"
              onClick={ openEyeDropper }
            />
          </div>
        )}

        <div class="v-color-picker-preview__dot">
          <div style={{ background: HSVtoCSS(props.color ?? nullColor) }} />
        </div>

        <div class="v-color-picker-preview__sliders">
          <VSlider
            class="v-color-picker-preview__track v-color-picker-preview__hue"
            aria-label={ t('$vuetify.colorPicker.ariaLabel.hueSlider') }
            modelValue={ props.color?.h }
            onUpdate:modelValue={ h => emit('update:color', { ...(props.color ?? nullColor), h }) }
            step={ 1 }
            min={ 0 }
            max={ 360 }
            disabled={ props.disabled }
            readonly={ props.readonly }
            thumbSize={ 14 }
            trackSize={ 8 }
            trackFillColor="white"
            hideDetails
          />

          { !props.hideAlpha && (
            <VSlider
              class="v-color-picker-preview__track v-color-picker-preview__alpha"
              aria-label={ t('$vuetify.colorPicker.ariaLabel.alphaSlider') }
              modelValue={ props.color?.a ?? 1 }
              onUpdate:modelValue={ a => emit('update:color', { ...(props.color ?? nullColor), a }) }
              step={ 0.01 }
              min={ 0 }
              max={ 1 }
              disabled={ props.disabled }
              readonly={ props.readonly }
              thumbSize={ 14 }
              trackSize={ 8 }
              trackFillColor="white"
              hideDetails
            />
          )}
        </div>
      </div>
    ))

    return {}
  },
})

export type VColorPickerPreview = InstanceType<typeof VColorPickerPreview>
