<script setup lang="ts">
import { computed, ref } from "vue";
import { useLabelsStore, type Label } from "../stores/labels";
import { NOTE_COLOR_KEYS, NOTE_COLOR_LABELS, NOTE_SWATCH_CLASSES, type NoteColor } from "../notes/colors";
import BaseModal from "./BaseModal.vue";
import Icon from "./Icon.vue";

const emit = defineEmits<{ (e: "close"): void }>();
const labels = useLabelsStore();
const newName = ref("");
const pickerFor = ref<string | null>(null);
const mergeFor = ref<string | null>(null);

const canMerge = computed(() => labels.items.length > 1);

async function add() {
  const name = newName.value.trim();
  if (!name) return;
  await labels.create(name);
  newName.value = "";
}

async function rename(id: string, value: string) {
  const name = value.trim();
  if (name) await labels.rename(id, name);
}

function labelDot(color: string): string {
  return NOTE_SWATCH_CLASSES[color as NoteColor] ?? NOTE_SWATCH_CLASSES.default;
}

function openColor(id: string) {
  mergeFor.value = null;
  pickerFor.value = pickerFor.value === id ? null : id;
}

async function pickColor(id: string, color: NoteColor) {
  pickerFor.value = null;
  await labels.setColor(id, color);
}

function openMerge(id: string) {
  pickerFor.value = null;
  mergeFor.value = mergeFor.value === id ? null : id;
}

function otherLabels(id: string): Label[] {
  return labels.items.filter((lb) => lb.id !== id);
}

async function doMerge(sourceId: string, targetId: string) {
  mergeFor.value = null;
  await labels.mergeInto(sourceId, targetId);
}
</script>

<template>
  <BaseModal panel-class="w-full max-w-sm shadow-xl" @close="emit('close')">
    <div class="flex items-center justify-between border-b border-neutral-100 px-4 py-3 dark:border-neutral-800">
        <h2 class="text-sm font-semibold">Manage labels</h2>
        <button type="button" class="icon-btn" aria-label="Close" @click="emit('close')"><Icon name="close" /></button>
      </div>
      <div class="flex flex-col gap-2 p-4">
        <form class="flex items-center gap-2" @submit.prevent="add">
          <Icon name="plus" />
          <input
            v-model="newName"
            type="text"
            placeholder="Create label"
            class="flex-1 rounded-md border border-neutral-300 bg-white px-2 py-1.5 text-sm outline-none focus-visible:ring-2 focus-visible:ring-brand dark:border-neutral-700 dark:bg-neutral-800"
          />
        </form>
        <ul class="flex flex-col gap-1 pt-1">
          <li v-for="lb in labels.items" :key="lb.id" class="relative flex items-center gap-1.5">
            <button
              type="button"
              class="h-4 w-4 shrink-0 rounded-full border border-black/10 transition hover:scale-110 focus:outline-none focus-visible:ring-2 focus-visible:ring-brand dark:border-white/15"
              :class="labelDot(lb.color)"
              :title="`Color: ${NOTE_COLOR_LABELS[(lb.color as NoteColor)] ?? lb.color}`"
              aria-label="Change label color"
              @click="openColor(lb.id)"
            />
            <input
              :value="lb.name"
              class="min-w-0 flex-1 rounded-md bg-transparent px-2 py-1.5 text-sm outline-none focus-visible:ring-2 focus-visible:ring-brand"
              @change="rename(lb.id, ($event.target as HTMLInputElement).value)"
            />
            <span
              class="shrink-0 tabular-nums text-xs text-neutral-400"
              :title="`${lb.count ?? 0} note${(lb.count ?? 0) === 1 ? '' : 's'}`"
              >{{ lb.count ?? 0 }}</span
            >
            <button
              v-if="canMerge"
              type="button"
              class="icon-btn"
              title="Merge into another label"
              aria-label="Merge into another label"
              @click="openMerge(lb.id)"
            >
              <Icon name="merge" />
            </button>
            <button
              type="button"
              class="icon-btn"
              title="Delete label"
              aria-label="Delete label"
              @click="labels.remove(lb.id)"
            >
              <Icon name="trash" />
            </button>
            <div
              v-if="pickerFor === lb.id"
              class="absolute left-0 top-full z-10 mt-1 flex max-w-[13rem] flex-wrap gap-1.5 rounded-lg border border-neutral-200 bg-white p-2 shadow-lg dark:border-neutral-700 dark:bg-neutral-800"
            >
              <button
                v-for="key in NOTE_COLOR_KEYS"
                :key="key"
                type="button"
                :title="NOTE_COLOR_LABELS[key]"
                :aria-label="NOTE_COLOR_LABELS[key]"
                class="h-6 w-6 rounded-full border border-black/10 transition hover:scale-110 focus:outline-none focus-visible:ring-2 focus-visible:ring-brand"
                :class="[NOTE_SWATCH_CLASSES[key], lb.color === key ? 'ring-2 ring-brand' : '']"
                @click="pickColor(lb.id, key)"
              />
            </div>
            <div
              v-if="mergeFor === lb.id"
              class="absolute right-0 top-full z-10 mt-1 w-52 rounded-lg border border-neutral-200 bg-white p-1 shadow-lg dark:border-neutral-700 dark:bg-neutral-800"
            >
              <p class="px-2 py-1 text-xs text-neutral-400">
                Merge “{{ lb.name }}” into… <span class="text-neutral-300 dark:text-neutral-500">(keeps notes)</span>
              </p>
              <ul class="max-h-44 overflow-y-auto">
                <li v-for="t in otherLabels(lb.id)" :key="t.id">
                  <button
                    type="button"
                    class="flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm hover:bg-neutral-100 dark:hover:bg-neutral-700"
                    @click="doMerge(lb.id, t.id)"
                  >
                    <span
                      class="h-2.5 w-2.5 shrink-0 rounded-full border border-black/10 dark:border-white/15"
                      :class="labelDot(t.color)"
                    ></span>
                    <span class="truncate">{{ t.name }}</span>
                  </button>
                </li>
              </ul>
            </div>
          </li>
        </ul>
        <p v-if="!labels.items.length" class="py-2 text-center text-xs text-neutral-400">
          No labels yet — create one above.
        </p>
      </div>
  </BaseModal>
</template>
