<template>
  <PlannerSidebar title="Properties">
    <div
      class="bg-white-50 flex flex-col"
      v-if="selectedObject && applicableProperties"
    >
      <div
        class="grid grid-cols-2 px-2 py-2"
        v-for="prop of applicableProperties.properties"
      >
        <label :for="`${prop.key}-${selectedObject.id}`">{{
          prop.title
        }}</label>
        <input
          v-if="prop.type === 'string'"
          :id="`${prop.key}-${selectedObject.id}`"
          type="text"
          :value="selectedObject[prop.key as keyof typeof selectedObject]"
          @input="updateProp(prop, ($event.target as HTMLInputElement)?.value)"
        />
        <input
          v-else-if="prop.type === 'color'"
          :id="`${prop.key}-${selectedObject.id}`"
          type="color"
          :value="selectedObject[prop.key as keyof typeof selectedObject]"
          @change="updateProp(prop, ($event.target as HTMLInputElement)?.value)"
        />
        <input
          v-else-if="prop.type === 'number'"
          :id="`${prop.key}-${selectedObject.id}`"
          type="number"
          :value="selectedObject[prop.key as keyof typeof selectedObject]"
          @input="updateProp(prop, ($event.target as HTMLInputElement)?.value)"
        />
        <input
          v-else-if="prop.type === 'boolean'"
          :id="`${prop.key}-${selectedObject.id}`"
          type="checkbox"
          :checked="(selectedObject[prop.key as keyof typeof selectedObject] as boolean)"
          @input="
            updateProp(prop, ($event.target as HTMLInputElement)?.checked)
          "
        />
        <select
          v-else-if="prop.type === 'select'"
          :id="`${prop.key}-${selectedObject.id}`"
          :value="selectedObject[prop.key as keyof typeof selectedObject]"
          @input="updateProp(prop, ($event.target as HTMLInputElement)?.value)"
        >
          <option v-for="option of prop.options" :value="option.value">
            {{ option.title }}
          </option>
        </select>
      </div>
    </div>
  </PlannerSidebar>
</template>

<script setup lang="ts">
import PlannerSidebar from './PlannerSidebar.vue';
import { Layer } from '../../modules/house-planner/interfaces';
import {
  ObjectProperties,
  ObjectProperty,
} from './interfaces/properties.interfaces';
import { computed } from 'vue';

const props = defineProps<{
  layers: Layer[];
}>();

const emit = defineEmits<{
  (
    e: 'update',
    layerId: number,
    objectId: number,
    key: string,
    value: unknown
  ): void;
}>();

const commonProps: ObjectProperty[] = [
  { key: 'name', title: 'Name', type: 'string' },
  { key: 'visible', title: 'Visible', type: 'boolean', groupable: true },
];

const lineProps: ObjectProperty[] = [
  ...commonProps,
  { key: 'width', title: 'Line Width', type: 'number', groupable: true },
  { key: 'color', title: 'Color', type: 'color', groupable: true },
  {
    key: 'lineCap',
    title: 'Line Cap',
    type: 'select',
    groupable: true,
    options: [
      { value: undefined, title: '' },
      { value: 'butt', title: 'Butt' },
      { value: 'round', title: 'Round' },
      { value: 'square', title: 'Square' },
    ],
  },
  { key: 'closed', title: 'Closed', type: 'boolean', groupable: true },
];

const objectTypeProperties: ObjectProperties[] = [
  {
    type: 'line',
    properties: lineProps,
  },
  {
    type: 'curve',
    properties: lineProps,
  },
  {
    type: 'room',
    properties: lineProps,
  },
  {
    type: 'object',
    properties: commonProps,
  },
];

const currentLayer = computed(() =>
  props.layers.find((layer) => layer.active && layer.visible)
);

// TODO multi edit
const selectedObject = computed(
  () => currentLayer.value?.contents?.filter((obj) => obj.selected)[0]
);

const applicableProperties = computed(
  () =>
    selectedObject.value &&
    objectTypeProperties.find(
      (prop) => prop.type === selectedObject.value?.type
    )
);

const updateProp = (prop: ObjectProperty, value: unknown) => {
  if (!currentLayer.value || !selectedObject.value) return;
  if (prop.type === 'number') value = parseFloat(value as string);
  emit(
    'update',
    currentLayer.value!.id,
    selectedObject.value!.id,
    prop.key,
    value
  );
};
</script>
