<template>
  <teleport to="body">
    <transition name="add-group-fade" appear>
      <div
        v-if="open"
        class="add-group-backdrop"
        @click.self="closeDialog"
      >
        <div class="add-group-dialog" role="dialog" aria-modal="true" :aria-label="titleText">
          <div class="add-group-title">{{ titleText }}</div>
          <div class="add-group-icons" role="listbox" aria-label="选择分组图标">
            <button
              v-for="icon in iconOptions"
              :key="icon.id"
              class="add-group-icon"
              :class="{ selected: selectedIcon === icon.id }"
              type="button"
              :title="icon.label"
              :aria-pressed="selectedIcon === icon.id"
              @click="selectIcon(icon)"
            >
              <Icon class="add-group-icon-svg" :icon="icon.icon" aria-hidden="true" />
            </button>
          </div>
          <div class="add-group-field">
            <label for="add-group-name">名称</label>
            <input
              id="add-group-name"
              ref="inputRef"
              v-model="name"
              type="text"
              maxlength="12"
              placeholder="常用"
              @keydown.enter.prevent="submit"
            />
          </div>
          <div class="add-group-actions">
            <button class="btn btn-primary" type="button" :disabled="!canSubmit" @click="submit">
              {{ submitText }}
            </button>
            <button class="btn btn-secondary" type="button" @click="closeDialog">
              取消
            </button>
          </div>
        </div>
      </div>
    </transition>
  </teleport>
</template>

<script setup lang="ts">
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import { Icon } from '@iconify/vue';
import { groupIcons } from '@/config/groupIcons';

const props = defineProps<{
  open: boolean;
  title?: string;
  submitText?: string;
  initialName?: string;
  initialIconId?: string;
}>();

const emit = defineEmits<{
  (event: 'update:open', value: boolean): void;
  (event: 'submit', payload: { name: string; iconId: string }): void;
}>();

const iconOptions = groupIcons;

const inputRef = ref<HTMLInputElement | null>(null);
const name = ref('');
const selectedIcon = ref(iconOptions[0]?.id ?? '');

const canSubmit = computed(() => name.value.trim().length > 0);
const titleText = computed(() => props.title ?? '添加分组');
const submitText = computed(() => props.submitText ?? '保存');

const resetForm = () => {
  const fallbackIcon = iconOptions[0];
  const providedIcon = props.initialIconId?.trim();
  const initialIcon = providedIcon || fallbackIcon?.id || '';
  const providedName = props.initialName?.trim();
  const initialLabel =
    providedName ||
    iconOptions.find(icon => icon.id === initialIcon)?.label ||
    fallbackIcon?.label ||
    '';
  selectedIcon.value = initialIcon;
  name.value = initialLabel;
};

const selectIcon = (icon: (typeof iconOptions)[number]) => {
  selectedIcon.value = icon.id;
  name.value = icon.label;
};

const closeDialog = () => {
  emit('update:open', false);
};

const submit = () => {
  if (!canSubmit.value) return;
  emit('submit', { name: name.value.trim(), iconId: selectedIcon.value });
};

const handleKeydown = (event: KeyboardEvent) => {
  if (!props.open) return;
  if (event.key === 'Escape') {
    event.preventDefault();
    closeDialog();
  }
};

onMounted(() => {
  window.addEventListener('keydown', handleKeydown);
});

onBeforeUnmount(() => {
  window.removeEventListener('keydown', handleKeydown);
});

watch(
  () => props.open,
  value => {
    if (value) {
      resetForm();
      nextTick(() => inputRef.value?.focus());
    }
  }
);
</script>

<style lang="scss" scoped>
@import '@/styles/tokens.scss';

.add-group-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: $z-index-modal;
}

.add-group-dialog {
  width: min(500px, 92vw);
  padding: 18px 20px 20px;
  border-radius: $border-radius-large;
  background: rgba(18, 18, 18, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: $shadow-lg;
  position: relative;
  overflow: hidden;
  backdrop-filter: blur($backdrop-filter-blur) saturate($backdrop-filter-saturation);
}

.add-group-dialog::before {
  content: '';
  position: absolute;
  inset: auto auto -120px -120px;
  width: 280px;
  height: 280px;
  background: radial-gradient(circle, rgba(255, 149, 0, 0.4), transparent 70%);
  pointer-events: none;
}

.add-group-title {
  font-size: 16px;
  font-weight: 600;
  color: $color-text-primary;
  margin-bottom: 12px;
}

.add-group-icons {
  display: grid;
  grid-template-columns: repeat(8, minmax(0, 1fr));
  gap: 10px;
  padding: 12px;
  border-radius: $border-radius-medium;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  margin-bottom: 14px;
}

.add-group-icon {
  width: 32px;
  height: 32px;
  border-radius: 9px;
  border: 1px solid transparent;
  background: rgba(255, 255, 255, 0.02);
  color: $color-text-secondary;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background-color $motion-duration-sm $motion-easing-standard,
    color $motion-duration-sm $motion-easing-standard,
    border-color $motion-duration-sm $motion-easing-standard,
    box-shadow $motion-duration-sm $motion-easing-standard,
    transform $motion-duration-sm $motion-easing-standard;
}

.add-group-icon-svg {
  width: 18px;
  height: 18px;
}

.add-group-icon:hover {
  background: rgba(255, 255, 255, 0.1);
  color: $color-text-primary;
  transform: translateY(-1px);
}

.add-group-icon.selected {
  border-color: rgba(255, 149, 0, 0.5);
  background: rgba(255, 149, 0, 0.18);
  color: $color-text-primary;
  box-shadow: 0 0 0 1px rgba(255, 149, 0, 0.35);
}

.add-group-field {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 16px;
}

.add-group-field label {
  font-size: 13px;
  color: $color-text-secondary;
  min-width: 36px;
}

.add-group-field input {
  flex: 1;
  height: 34px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.08);
  color: $color-text-primary;
  padding: 0 14px;
  font-size: 13px;
  outline: none;
  transition: border-color $motion-duration-sm $motion-easing-standard,
    box-shadow $motion-duration-sm $motion-easing-standard;
}

.add-group-field input:focus {
  border-color: rgba(255, 149, 0, 0.5);
  box-shadow: 0 0 0 2px rgba(255, 149, 0, 0.2);
}

.add-group-actions {
  display: flex;
  gap: 10px;
}

.btn {
  padding: 6px 16px;
  border-radius: 999px;
  border: none;
  font-size: 13px;
  cursor: pointer;
  transition: transform $motion-duration-sm $motion-easing-standard,
    box-shadow $motion-duration-sm $motion-easing-standard,
    background-color $motion-duration-sm $motion-easing-standard,
    color $motion-duration-sm $motion-easing-standard;
}

.btn-primary {
  background: $color-accent;
  color: #1a1206;
  box-shadow: 0 6px 16px rgba(255, 149, 0, 0.25);
}

.btn-primary:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  box-shadow: none;
}

.btn-primary:not(:disabled):hover {
  transform: translateY(-1px);
  box-shadow: 0 8px 18px rgba(255, 149, 0, 0.35);
}

.btn-secondary {
  background: rgba(255, 255, 255, 0.1);
  color: $color-text-primary;
}

.btn-secondary:hover {
  background: rgba(255, 255, 255, 0.16);
}

.add-group-fade-enter-active,
.add-group-fade-leave-active {
  transition: opacity 220ms ease;
}

.add-group-fade-enter-from,
.add-group-fade-leave-to {
  opacity: 0;
}

.add-group-fade-enter-active .add-group-dialog,
.add-group-fade-leave-active .add-group-dialog {
  transition: transform 240ms ease, opacity 240ms ease;
}

.add-group-fade-enter-from .add-group-dialog,
.add-group-fade-leave-to .add-group-dialog {
  transform: translateY(6px) scale(0.98);
  opacity: 0;
}

@media (max-width: 520px) {
  .add-group-icons {
    grid-template-columns: repeat(6, minmax(0, 1fr));
  }
}
</style>
