<script setup lang="ts">
import { MAP_POINT_TYPES, MapAreaType, type MapPen, type MapPointInfo, MapPointType, type Rect } from '@api/map';
import type { RobotInfo } from '@api/robot';
import type { PointBindModalRef } from '@common/modal/point-bind-modal.vue';
import type { RobotBindModalRef } from '@common/modal/robot-bind-modal.vue';
import type { EditorService } from '@core/editor.service';
import sTheme from '@core/theme.service';
import { isNil } from 'lodash-es';
import { ref, shallowRef } from 'vue';
import { computed, inject, type InjectionKey, type ShallowRef } from 'vue';

type Props = {
  token: InjectionKey<ShallowRef<EditorService>>;
  id?: string;
};
const props = defineProps<Props>();
const editor = inject(props.token)!;

const pen = computed<MapPen | null>(() => {
  const v = editor.value.current.value;
  if (v?.id !== props.id) return null;
  return v!;
});
const point = computed<MapPointInfo | null>(() => {
  const v = pen.value?.point;
  if (!v?.type) return null;
  return v;
});
const rect = computed<Partial<Rect>>(() => {
  if (isNil(point.value)) return {};
  const { x, y, width, height } = editor.value.getPointRect(pen.value!) ?? {};
  return { x, y, width, height };
});

const refBindRobot = shallowRef<RobotBindModalRef>();
const robotKeyword = ref<string>('');
const robots = computed<RobotInfo[]>(
  () =>
    <RobotInfo[]>(
      point.value?.robots
        ?.map((v) => editor.value.getRobotById(v))
        .filter((v) => v?.label?.includes(robotKeyword.value))
    ) ?? [],
);

const refBindPoint = shallowRef<PointBindModalRef>();
const pointKeyword = ref<string>('');
const actions = computed<MapPen[]>(
  () =>
    <MapPen[]>(
      point.value?.actions
        ?.map((v) => editor.value.getPenById(v))
        .filter((v) => v?.point?.type === MapPointType.动作点 && v?.label?.includes(pointKeyword.value))
    ),
);

const coArea1 = computed<MapPen[]>(() => editor.value.getBoundAreas(props.id, 'point', MapAreaType.库区));
const coArea2 = computed<MapPen[]>(() => editor.value.getBoundAreas(props.id, 'point', MapAreaType.互斥区));
</script>

<template>
  <RobotBindModal ref="refBindRobot" :token="token" />
  <PointBindModal ref="refBindPoint" :token="token" />

  <a-card class="full" :title="$t('属性')" :bordered="false">
    <a-flex v-if="id && pen && point" :gap="24" vertical>
      <a-row :gutter="[8, 8]">
        <a-col :span="12">
          <a-select :value="point.type" @change="editor.changePointType(id, <number>$event)">
            <a-select-option v-for="[l, v] in MAP_POINT_TYPES" :key="v">{{ $t(l) }}</a-select-option>
          </a-select>
        </a-col>
        <a-col :span="12">
          <a-input
            :maxlength="10"
            :value="pen.label"
            @change="editor.updatePen(id, { label: $event.target.value }, false)"
          >
            <template #suffix><EditOutlined /></template>
          </a-input>
        </a-col>
      </a-row>

      <a-row :gutter="[8, 8]">
        <a-col :span="24">
          <a-typography-text>{{ $t('描述') }}:</a-typography-text>
        </a-col>
        <a-col :span="24">
          <a-textarea
            class="prop"
            :placeholder="$t('请输入描述内容')"
            :maxlength="100"
            :autoSize="{ minRows: 3, maxRows: 3 }"
            :value="pen?.desc"
            @change="editor.updatePen(id, { desc: $event.target.value }, false)"
          />
        </a-col>
      </a-row>

      <a-row align="middle" :gutter="16">
        <a-col flex="auto">
          <a-typography-text>{{ $t('坐标') }}:</a-typography-text>
        </a-col>
        <a-col flex="none">
          <a-space :size="8">
            <a-typography-text code>X:</a-typography-text>
            <a-input-number
              style="width: 80px"
              :placeholder="$t('请输入')"
              :precision="0"
              :controls="false"
              :value="rect?.x?.toFixed()"
              @change="editor.updatePen(id, { x: +$event - (rect.width ?? 0) / 2 })"
            />
          </a-space>
        </a-col>
        <a-col flex="none">
          <a-space :size="8">
            <a-typography-text code>Y:</a-typography-text>
            <a-input-number
              style="width: 80px"
              :placeholder="$t('请输入')"
              :precision="0"
              :controls="false"
              :value="rect?.y?.toFixed()"
              @change="editor.updatePen(id, { y: +$event - (rect.height ?? 0) / 2 })"
            />
          </a-space>
        </a-col>
      </a-row>

      <a-collapse expand-icon-position="end" :bordered="false">
        <template #expandIcon="v">
          <i class="icon dropdown" :class="{ active: v?.isActive }" />
        </template>

        <a-collapse-panel
          v-if="[MapPointType.充电点, MapPointType.停靠点].includes(point.type)"
          :header="$t('绑定机器人')"
        >
          <template #extra>
            <a-button class="icon-btn" size="small" @click.stop="refBindRobot?.open(pen)">
              <i class="mask plus" />
            </a-button>
          </template>
          <a-input class="search mv-8" :placeholder="$t('请输入搜索关键字')" v-model:value="robotKeyword">
            <template #suffix>
              <i class="icon search size-16" />
            </template>
          </a-input>
          <a-list rowKey="id" :data-source="robots">
            <template #renderItem="{ item }">
              <a-list-item class="ph-16" style="height: 36px">
                <a-typography-text>{{ item.label }}</a-typography-text>
              </a-list-item>
            </template>
          </a-list>
        </a-collapse-panel>

        <a-collapse-panel v-if="MapPointType.等待点 === point.type" :header="$t('绑定动作点')">
          <template #extra>
            <a-button class="icon-btn" size="small" @click.stop="refBindPoint?.open(pen, MapPointType.动作点)">
              <i class="mask plus" />
            </a-button>
          </template>
          <a-input class="search mv-8" :placeholder="$t('请输入搜索关键字')" v-model:value="pointKeyword">
            <template #suffix>
              <i class="icon search size-16" />
            </template>
          </a-input>
          <a-list rowKey="id" :data-source="actions">
            <template #renderItem="{ item }">
              <a-list-item class="ph-16" style="height: 36px">
                <a-typography-text>{{ item.label }}</a-typography-text>
              </a-list-item>
            </template>
          </a-list>
        </a-collapse-panel>

        <a-collapse-panel v-if="MapPointType.动作点 === point.type" :header="$t('关联库区')">
          <a-list rowKey="id" :data-source="coArea1">
            <template #renderItem="{ item }">
              <a-list-item class="ph-16" style="height: 36px">
                <a-typography-text>{{ item.label }}</a-typography-text>
              </a-list-item>
            </template>
          </a-list>
        </a-collapse-panel>

        <a-collapse-panel
          v-if="
            [
              MapPointType.普通点,
              MapPointType.电梯点,
              MapPointType.自动门点,
              MapPointType.等待点,
              MapPointType.充电点,
              MapPointType.停靠点,
              MapPointType.动作点,
              MapPointType.临时避让点,
            ].includes(point.type)
          "
          :header="$t('关联互斥区')"
        >
          <a-list rowKey="id" :data-source="coArea2">
            <template #renderItem="{ item }">
              <a-list-item class="ph-16" style="height: 36px">
                <a-typography-text>{{ item.label }}</a-typography-text>
              </a-list-item>
            </template>
          </a-list>
        </a-collapse-panel>
      </a-collapse>
    </a-flex>
    <a-empty v-else :image="sTheme.empty" />
  </a-card>
</template>
