<script setup lang="ts">
import { computed, ref, watch } from "vue";

const props = defineProps<{
  onAddText: () => void;
  onAddCircle: () => void;
  onAddRectangle: () => void;
  onClear: () => void;
  onImportImage: (file: File) => Promise<void>;
  onFillChange: (fill: string) => void;
  onStrokeChange: (stroke: string) => void;
  activeFill: string | null;
  activeStroke: string | null;
  canStyleSelection: boolean;
  zoom: number;
  minZoom: number;
  maxZoom: number;
  onZoomChange: (zoom: number) => void;
  onZoomIn: () => void;
  onZoomOut: () => void;
  onZoomReset: () => void;
}>();

const emit = defineEmits<{
  (e: "request-image"): void;
}>();

const fileInput = ref<HTMLInputElement | null>(null);
const fillValue = ref(props.activeFill ?? "#111827");
const strokeValue = ref(props.activeStroke ?? "#3b82f6");
const zoomSliderValue = ref(Math.round(props.zoom * 100));

watch(
  () => props.activeFill,
  (next) => {
    fillValue.value = next ?? "#111827";
  }
);

watch(
  () => props.activeStroke,
  (next) => {
    strokeValue.value = next ?? "#3b82f6";
  }
);

watch(
  () => props.zoom,
  (next) => {
    zoomSliderValue.value = Math.round(next * 100);
  }
);

const openFilePicker = () => {
  if (!fileInput.value) {
    return;
  }
  fileInput.value.value = "";
  fileInput.value.click();
};

const handleFileChange = async (event: Event) => {
  const input = event.target as HTMLInputElement;
  const files = input.files;
  if (!files || !files.length) {
    return;
  }
  const [file] = files;
  if (!file) {
    return;
  }
  await props.onImportImage(file);
};

const stylingDisabled = computed(() => !props.canStyleSelection);

const handleFillChange = (event: Event) => {
  const input = event.target as HTMLInputElement;
  const value = input.value;
  fillValue.value = value;
  props.onFillChange(value);
};

const handleStrokeChange = (event: Event) => {
  const input = event.target as HTMLInputElement;
  const value = input.value;
  strokeValue.value = value;
  props.onStrokeChange(value);
};

const handleZoomInput = (event: Event) => {
  const input = event.target as HTMLInputElement;
  const value = Number(input.value);
  if (Number.isNaN(value)) {
    return;
  }
  zoomSliderValue.value = value;
  props.onZoomChange(value / 100);
};

const zoomLabel = computed(() => `${Math.round(props.zoom * 100)}%`);
</script>

<template>
  <div class="flex flex-wrap items-center gap-2 border-b border-slate-800/60 bg-slate-900/50 px-4 py-3">
    <!-- Add Elements Group -->
    <div class="flex items-center gap-1 border-r border-slate-700/50 pr-3">
      <button
        type="button"
        class="flex h-9 w-9 items-center justify-center rounded-lg text-lg font-bold text-slate-300 transition hover:bg-slate-800"
        title="Add Text"
        @click="props.onAddText"
      >
        T
      </button>
      <button
        type="button"
        class="flex h-9 w-9 items-center justify-center rounded-lg text-xl font-bold text-slate-300 transition hover:bg-slate-800"
        title="Add Circle"
        @click="props.onAddCircle"
      >
        ●
      </button>
      <button
        type="button"
        class="flex h-9 w-9 items-center justify-center rounded-lg text-xl font-bold text-slate-300 transition hover:bg-slate-800"
        title="Add Rectangle"
        @click="props.onAddRectangle"
      >
        ▭
      </button>
      <button
        type="button"
        class="flex h-9 w-9 items-center justify-center rounded-lg text-xl font-bold text-slate-300 transition hover:bg-slate-800"
        title="Upload Image"
        @click="openFilePicker"
      >
        🖼
      </button>
    </div>

    <!-- Color Pickers Group -->
    <div class="flex items-center gap-2 border-r border-slate-700/50 pr-3">
      <label class="flex items-center gap-1.5" title="Fill Color">
        <span class="text-xs text-slate-400">Fill</span>
        <input
          type="color"
          class="h-8 w-12 cursor-pointer rounded border border-slate-700/70 bg-slate-800/80 p-0.5"
          :disabled="stylingDisabled"
          :value="fillValue"
          @input="handleFillChange"
        />
      </label>
      <label class="flex items-center gap-1.5" title="Stroke Color">
        <span class="text-xs text-slate-400">Stroke</span>
        <input
          type="color"
          class="h-8 w-12 cursor-pointer rounded border border-slate-700/70 bg-slate-800/80 p-0.5"
          :disabled="stylingDisabled"
          :value="strokeValue"
          @input="handleStrokeChange"
        />
      </label>
    </div>

    <!-- Zoom Controls -->
    <div class="flex items-center gap-2 border-r border-slate-700/50 pr-3">
      <button
        type="button"
        class="flex h-8 w-8 items-center justify-center rounded border border-slate-700/60 bg-slate-800/80 text-sm font-bold text-slate-100 transition hover:bg-slate-700"
        title="Zoom Out"
        @click="props.onZoomOut"
      >
        –
      </button>
      <span class="min-w-12 text-center text-xs font-medium text-slate-300">
        {{ zoomLabel }}
      </span>
      <button
        type="button"
        class="flex h-8 w-8 items-center justify-center rounded border border-slate-700/60 bg-slate-800/80 text-sm font-bold text-slate-100 transition hover:bg-slate-700"
        title="Zoom In"
        @click="props.onZoomIn"
      >
        +
      </button>
      <button
        type="button"
        class="rounded border border-slate-700/60 bg-slate-800/80 px-2 py-1 text-xs font-medium text-slate-200 transition hover:bg-slate-700"
        title="Reset Zoom"
        @click="props.onZoomReset"
      >
        Reset
      </button>
    </div>

    <!-- Clear Button -->
    <button
      type="button"
      class="ml-auto rounded border border-red-500/40 px-3 py-1.5 text-xs font-medium text-red-300 transition hover:bg-red-500/10"
      @click="props.onClear"
    >
      Clear Canvas
    </button>

    <!-- Hidden File Input -->
    <input
      ref="fileInput"
      type="file"
      accept="image/png,image/jpeg,image/webp,image/svg+xml"
      class="hidden"
      @change="handleFileChange"
    />
  </div>
</template>

