<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { hexToHSL, hslToHex } from '../../services/themeService'

const props = defineProps<{
  modelValue: string
  label?: string
}>()

const emit = defineEmits<{
  'update:modelValue': [value: string]
}>()

const isOpen = ref(false)
const hexInput = ref(props.modelValue)

const hsl = computed(() => {
  try {
    return hexToHSL(props.modelValue)
  } catch {
    return { h: 0, s: 50, l: 50 }
  }
})

const hue = ref(hsl.value.h)
const saturation = ref(hsl.value.s)
const lightness = ref(hsl.value.l)

watch(() => props.modelValue, (newVal) => {
  hexInput.value = newVal
  const newHsl = hexToHSL(newVal)
  hue.value = newHsl.h
  saturation.value = newHsl.s
  lightness.value = newHsl.l
})

function updateFromHSL() {
  const hex = hslToHex(hue.value, saturation.value, lightness.value)
  hexInput.value = hex
  emit('update:modelValue', hex)
}

function updateFromHex() {
  if (/^#[0-9A-Fa-f]{6}$/.test(hexInput.value)) {
    emit('update:modelValue', hexInput.value)
    const newHsl = hexToHSL(hexInput.value)
    hue.value = newHsl.h
    saturation.value = newHsl.s
    lightness.value = newHsl.l
  }
}

// Close picker on outside click
function handleClickOutside(e: MouseEvent) {
  const target = e.target as HTMLElement
  if (!target.closest('.color-picker')) {
    isOpen.value = false
  }
}

// Register click outside listener
watch(isOpen, (open) => {
  if (open) {
    setTimeout(() => document.addEventListener('click', handleClickOutside), 0)
  } else {
    document.removeEventListener('click', handleClickOutside)
  }
})
</script>

<template>
  <div class="color-picker" @click.stop>
    <div class="color-preview" @click="isOpen = !isOpen">
      <div class="color-swatch" :style="{ background: modelValue }"></div>
      <span class="color-value">{{ modelValue }}</span>
    </div>

    <div v-if="isOpen" class="color-dropdown" @click.stop>
      <div class="color-sliders">
        <div class="slider-group">
          <label>Hue</label>
          <input
            type="range"
            v-model.number="hue"
            min="0"
            max="360"
            class="hue-slider"
            @input="updateFromHSL"
          />
          <span>{{ hue }}°</span>
        </div>

        <div class="slider-group">
          <label>Saturation</label>
          <input
            type="range"
            v-model.number="saturation"
            min="0"
            max="100"
            class="saturation-slider"
            :style="{
              '--sat-left': hslToHex(hue, 0, lightness),
              '--sat-right': hslToHex(hue, 100, lightness)
            }"
            @input="updateFromHSL"
          />
          <span>{{ saturation }}%</span>
        </div>

        <div class="slider-group">
          <label>Lightness</label>
          <input
            type="range"
            v-model.number="lightness"
            min="0"
            max="100"
            class="lightness-slider"
            :style="{
              '--light-mid': hslToHex(hue, saturation, 50)
            }"
            @input="updateFromHSL"
          />
          <span>{{ lightness }}%</span>
        </div>
      </div>

      <div class="hex-input-group">
        <label>Hex</label>
        <input
          type="text"
          v-model="hexInput"
          @blur="updateFromHex"
          @keyup.enter="updateFromHex"
          maxlength="7"
        />
      </div>

      <div class="large-preview" :style="{ background: modelValue }"></div>
    </div>
  </div>
</template>

<style scoped>
.color-picker {
  position: relative;
}

.color-preview {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.375rem 0.5rem;
  background: var(--bg-primary);
  border: 1px solid var(--border-color);
  border-radius: 6px;
  cursor: pointer;
  transition: border-color 0.15s;
}

.color-preview:hover {
  border-color: var(--accent);
}

.color-swatch {
  width: 24px;
  height: 24px;
  border-radius: 4px;
  border: 1px solid rgba(255, 255, 255, 0.1);
}

.color-value {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--text-secondary);
  text-transform: uppercase;
}

.color-dropdown {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  width: 240px;
  padding: 1rem;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  z-index: 100;
}

.color-sliders {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.slider-group {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.slider-group label {
  width: 70px;
  font-size: 0.75rem;
  color: var(--text-secondary);
}

.slider-group input[type="range"] {
  flex: 1;
  height: 8px;
  border-radius: 4px;
  appearance: none;
  cursor: pointer;
}

.slider-group span {
  width: 40px;
  font-size: 0.7rem;
  color: var(--text-muted);
  text-align: right;
}

.hue-slider {
  background: linear-gradient(
    to right,
    #ff0000, #ffff00, #00ff00, #00ffff, #0000ff, #ff00ff, #ff0000
  );
}

.saturation-slider {
  background: linear-gradient(to right, var(--sat-left), var(--sat-right));
}

.lightness-slider {
  background: linear-gradient(to right, #000000, var(--light-mid), #ffffff);
}

input[type="range"]::-webkit-slider-thumb {
  appearance: none;
  width: 14px;
  height: 14px;
  background: white;
  border-radius: 50%;
  border: 2px solid var(--bg-primary);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
  cursor: pointer;
}

.hex-input-group {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}

.hex-input-group label {
  font-size: 0.75rem;
  color: var(--text-secondary);
}

.hex-input-group input {
  flex: 1;
  padding: 0.375rem 0.5rem;
  background: var(--bg-primary);
  border: 1px solid var(--border-color);
  border-radius: 4px;
  color: var(--text-primary);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  text-transform: uppercase;
}

.large-preview {
  height: 40px;
  border-radius: 6px;
  border: 1px solid rgba(255, 255, 255, 0.1);
}

/* Mobile responsive */
@media (max-width: 600px) {
  .color-preview {
    padding: 0.25rem 0.375rem;
  }

  .color-swatch {
    width: 20px;
    height: 20px;
  }

  .color-value {
    font-size: 0.7rem;
  }

  .color-dropdown {
    width: 220px;
    padding: 0.75rem;
    left: 50%;
    transform: translateX(-50%);
  }

  .slider-group label {
    width: 55px;
    font-size: 0.7rem;
  }

  .slider-group span {
    width: 35px;
    font-size: 0.65rem;
  }

  .large-preview {
    height: 32px;
  }
}
</style>
