<template>
  <PlannerSidebar :title="$t('planner.panel.properties.title')">
    <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';
import { useI18n } from 'vue-i18n';

const { t } = useI18n();

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: t('planner.properties.name'), type: 'string' },
  {
    key: 'visible',
    title: t('planner.properties.visible'),
    type: 'boolean',
    groupable: true,
  },
];

const lineProps: ObjectProperty[] = [
  ...commonProps,
  {
    key: 'width',
    title: t('planner.properties.width'),
    type: 'number',
    groupable: true,
  },
  {
    key: 'color',
    title: t('planner.properties.color'),
    type: 'color',
    groupable: true,
  },
  {
    key: 'lineCap',
    title: t('planner.properties.lineCap'),
    type: 'select',
    groupable: true,
    options: [
      { value: undefined, title: '' },
      { value: 'butt', title: t('planner.properties.butt') },
      { value: 'round', title: t('planner.properties.round') },
      { value: 'square', title: t('planner.properties.square') },
    ],
  },
  {
    key: 'lineJoin',
    title: t('planner.properties.lineJoin'),
    type: 'select',
    groupable: true,
    options: [
      { value: undefined, title: '' },
      { value: 'miter', title: t('planner.properties.miter') },
      { value: 'bevel', title: t('planner.properties.bevel') },
      { value: 'round', title: t('planner.properties.round') },
    ],
  },
  {
    key: 'closed',
    title: t('planner.properties.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>
