<script setup lang="ts">
import { toRefs, ref, computed } from 'vue'
import {
  LabelControl,
  Tooltip,
} from './index'
import {
  purifyHtml,
} from '@/helper'
import { useSettingsStore } from '@/stores/settings-store'
import { storeToRefs } from 'pinia'

const props = defineProps({
  params: {
    type: Object,
    required: true,
  },
})
const { params } = toRefs(props)
const settingsStore = useSettingsStore()
const {
  showPopup,
  componentUpgrade,
} = storeToRefs(settingsStore)

const arg = params.value
const value = ref<string>(arg['default'] ?? '#000000')
const disable = ref<boolean>(arg['disabled'] ?? false)
const showPicker = ref<boolean>(false)
const emit = defineEmits(['input', 'fieldData', 'previewRef'])
const inputValues = ref<any>([])
const previewRef = ref<any>([])

// Set for default value.
if (value.value !== '' && !disable.value) {
  inputValues.value[arg['id']] = value.value
  emit('fieldData', inputValues.value)
}

// Validate hex color
const isValidHex = (hex: string): boolean => {
  return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(hex)
}

const isPro = computed(() => {
  return typeof arg['pro'] !== 'undefined' && arg['pro'] !== null
})

// Normalize hex color value
const normalizeHex = (hex: string): string => {
  if (!hex) return '#000000'
  if (!hex.startsWith('#')) {
    hex = '#' + hex
  }
  return hex.toUpperCase()
}

// Committed color preview (shown on the swatch toggle button)
const colorPreview = computed(() => {
  return isValidHex(value.value) ? value.value : '#000000'
})

// Pending color — updated live in the picker, committed only on Confirm
const pendingColor = ref<string>(colorPreview.value)

const emitValueChange = () => {
  if (isPro.value) {
    if (typeof arg['pro_on_active'] !== 'undefined' && arg['pro_on_active'] !== null) {
      if (arg['pro_on_active'] && value.value !== '') {
        showPopup.value = true
      }
    } else {
      showPopup.value = true
    }

    componentUpgrade.value = arg['pro']
    value.value = arg['default'] ?? '#000000'
  } else {
    value.value = normalizeHex(value.value)
    inputValues.value[arg['id']] = value.value
    emit('fieldData', inputValues.value)

    previewRef.value[arg['id']] = inputValues.value
    emit('previewRef', previewRef.value)
  }
}

const togglePicker = () => {
  if (isPro.value) {
    showPopup.value = true
    componentUpgrade.value = arg['pro']
    return
  }
  // Reset pending to current committed value each time picker opens
  pendingColor.value = colorPreview.value
  showPicker.value = !showPicker.value
}

const handleClick = () => {
  if (isPro.value) {
    showPopup.value = true
    componentUpgrade.value = arg['pro']
  }
}

// Updates live preview only — does not commit
const handleColorInput = (event: Event) => {
  const target = event.target as HTMLInputElement
  pendingColor.value = target.value
}

// Commits pendingColor as the new value and closes picker
const confirmColor = () => {
  value.value = pendingColor.value
  emitValueChange()
  showPicker.value = false
}

// Discards pending changes and closes picker
const cancelColor = () => {
  pendingColor.value = colorPreview.value
  showPicker.value = false
}

const handleTextInput = () => {
  emitValueChange()
}

// Preset colors
const presetColors = [
  '#000000', '#FFFFFF', '#FF0000', '#00FF00', '#0000FF',
  '#FFFF00', '#FF00FF', '#00FFFF', '#FFA500', '#800080',
  '#FFC0CB', '#A52A2A', '#808080', '#008000', '#000080',
]

// Only updates pending — user still needs to click Confirm
const selectPresetColor = (color: string) => {
  pendingColor.value = color
}
</script>

<template>
  <div>
    <div class="stwlite-tw-flex stwlite-tw-items-center stwlite-tw-mb-2 stwlite-tw-gap-2">
      <LabelControl
        :params="arg"
      />
    </div>
    <div class="stwlite-tw-flex stwlite-tw-items-center stwlite-tw-mb-2 stwlite-tw-gap-2">
      <div class="stwlite-tw-relative stwlite-tw-flex stwlite-tw-items-center stwlite-tw-gap-2 stwlite-tw-max-w-xs stwlite-tw-w-full">
        <!-- Text input for hex value -->
        <input
          :id="arg['id']"
          v-model="value"
          :name="arg['id']"
          :disabled="disable"
          :placeholder="arg['placeholder'] || '#000000'"
          type="text"
          @input="handleTextInput"
          @click="handleClick"
          maxlength="7"
          :class="[
            'stwlite-tw-flex-1 stwlite-tw-px-3 stwlite-tw-py-2 stwlite-tw-border stwlite-tw-border-gray-300 stwlite-tw-rounded-md stwlite-tw-shadow-sm stwlite-tw-placeholder-gray-400 focus:stwlite-tw-outline-none focus:stwlite-tw-ring-2 focus:stwlite-tw-ring-blue-500 focus:stwlite-tw-border-blue-500 stwlite-tw-font-mono stwlite-tw-text-sm',
            disable ? 'stwlite-tw-bg-gray-100 stwlite-tw-text-gray-500 stwlite-tw-cursor-not-allowed' : 'stwlite-tw-bg-white stwlite-tw-text-gray-900'
          ]"
        />

        <!-- Color swatch toggle button -->
        <button
          type="button"
          @click="togglePicker"
          :disabled="disable"
          :style="{ backgroundColor: colorPreview }"
          :class="[
            'stwlite-tw-w-10 stwlite-tw-h-10 stwlite-tw-rounded-md stwlite-tw-border-2 stwlite-tw-border-solid stwlite-tw-transition-all stwlite-tw-duration-200 stwlite-tw-flex-shrink-0',
            showPicker ? 'stwlite-tw-border-blue-500 stwlite-tw-ring-2 stwlite-tw-ring-blue-200' : 'stwlite-tw-border-gray-300 hover:stwlite-tw-border-blue-400',
            disable ? 'stwlite-tw-cursor-not-allowed stwlite-tw-opacity-50' : 'stwlite-tw-cursor-pointer'
          ]"
          title="Pick color"
        >
          <span class="stwlite-tw-sr-only">Pick color</span>
        </button>

        <!-- Color picker dropdown -->
        <div
          v-if="showPicker && !disable"
          class="stwlite-tw-absolute stwlite-tw-top-12 stwlite-tw-left-0 stwlite-tw-z-50 stwlite-tw-bg-white stwlite-tw-border stwlite-tw-border-gray-300 stwlite-tw-rounded-lg stwlite-tw-shadow-lg stwlite-tw-p-4 stwlite-tw-w-64"
        >
          <!-- Live preview + native color input -->
          <div class="stwlite-tw-flex stwlite-tw-items-center stwlite-tw-gap-3 stwlite-tw-mb-4">
            <div
              :style="{ backgroundColor: pendingColor }"
              class="stwlite-tw-w-12 stwlite-tw-h-12 stwlite-tw-rounded-md stwlite-tw-border stwlite-tw-border-gray-300 stwlite-tw-flex-shrink-0"
            />
            <div class="stwlite-tw-flex stwlite-tw-flex-col stwlite-tw-gap-1 stwlite-tw-flex-1">
              <label class="stwlite-tw-text-xs stwlite-tw-text-gray-500">Custom color</label>
              <input
                type="color"
                :value="pendingColor"
                @input="handleColorInput"
                class="stwlite-tw-w-full stwlite-tw-h-8 stwlite-tw-rounded stwlite-tw-border stwlite-tw-border-gray-300 stwlite-tw-cursor-pointer"
                title="Open color picker"
              />
            </div>
          </div>

          <!-- Preset colors -->
          <div class="stwlite-tw-mb-4">
            <p class="stwlite-tw-text-xs stwlite-tw-font-medium stwlite-tw-text-gray-500 stwlite-tw-mb-2">Presets</p>
            <div class="stwlite-tw-grid stwlite-tw-grid-cols-5 stwlite-tw-gap-2">
              <button
                v-for="color in presetColors"
                :key="color"
                type="button"
                @click="selectPresetColor(color)"
                :style="{ backgroundColor: color }"
                :class="[
                  'stwlite-tw-w-9 stwlite-tw-h-9 stwlite-tw-rounded-md stwlite-tw-border-2 stwlite-tw-transition-all stwlite-tw-duration-200',
                  color === pendingColor ? 'stwlite-tw-border-blue-500 stwlite-tw-ring-2 stwlite-tw-ring-blue-200' : 'stwlite-tw-border-gray-300 hover:stwlite-tw-border-blue-400'
                ]"
                :title="color"
              >
                <span class="stwlite-tw-sr-only">{{ color }}</span>
              </button>
            </div>
          </div>

          <!-- Confirm / Cancel actions -->
          <div class="stwlite-tw-flex stwlite-tw-gap-2">
            <button
              type="button"
              @click="confirmColor"
              class="stwlite-tw-flex-1 stwlite-tw-px-3 stwlite-tw-py-2 stwlite-tw-text-sm stwlite-tw-font-medium stwlite-tw-bg-blue-600 hover:stwlite-tw-bg-blue-700 stwlite-tw-text-white stwlite-tw-rounded-md stwlite-tw-transition-colors stwlite-tw-duration-200"
            >
              Confirm
            </button>
            <button
              type="button"
              @click="cancelColor"
              class="stwlite-tw-flex-1 stwlite-tw-px-3 stwlite-tw-py-2 stwlite-tw-text-sm stwlite-tw-bg-gray-100 hover:stwlite-tw-bg-gray-200 stwlite-tw-text-gray-700 stwlite-tw-rounded-md stwlite-tw-transition-colors stwlite-tw-duration-200"
            >
              Cancel
            </button>
          </div>
        </div>
      </div>
      <Tooltip :params="arg" />
    </div>
    <p v-if="arg['description'] !== 'undefined' && arg['description']" class="stwlite-tw-text-sm stwlite-tw-text-gray-600 stwlite-tw-mt-2" v-html="purifyHtml(arg?.['description'] ?? '')" />
  </div>
</template>

<style scoped lang="scss">
/* Custom styling for native color picker */
input[type="color"] {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background-color: transparent;
  cursor: pointer;

  &::-webkit-color-swatch-wrapper {
    padding: 0;
  }

  &::-webkit-color-swatch {
    border: none;
    border-radius: 0.375rem;
  }

  &::-moz-color-swatch {
    border: none;
    border-radius: 0.375rem;
  }
}
input[type="text"] {
  padding-right: 0.75rem;
  padding-left: 0.75rem;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  background-color: rgb(255 255 255 / 1);
  border-color: rgb(209 213 219 / 1);
  border-width: 1px;
  border-radius: 0.375rem;
}
</style>
