<template>
  <PlannerSidebar title="Properties">
    <div
      class="bg-white-50 flex h-full flex-col overflow-auto"
      v-if="selectedObject && applicableProperties"
    >
      <PropertyFormItem
        v-for="prop of applicableProperties.properties"
        :id="selectedObject.id"
        :prop="prop"
        :value="selectedObject[prop.key as keyof typeof selectedObject]"
        @update="(newValue) => updateProp(prop, newValue)"
      />
    </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';
import PropertyFormItem from './PropertyFormItem.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: 'lineJoin',
    title: 'Line Join',
    type: 'select',
    groupable: true,
    options: [
      { value: undefined, title: '' },
      { value: 'miter', title: 'Miter' },
      { value: 'bevel', title: 'Bevel' },
      { value: 'round', title: 'Round' },
    ],
  },
  { 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>
