<script setup lang="ts">
import { type RobotGroup, type RobotInfo, seizeRobotByIds } from '@api/robot';
import type { RobotAddModalRef } from '@common/modal/robot-add-modal.vue';
import type { RobotGroupRenameModalRef } from '@common/modal/robot-group-rename-modal.vue';
import type { RobotRegisterModalRef } from '@common/modal/robot-register-modal.vue';
import type { EditorService } from '@core/editor.service';
import { Modal } from 'ant-design-vue';
import { watch } from 'vue';
import { reactive } from 'vue';
import { computed, inject, type InjectionKey, ref, type ShallowRef, shallowRef } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';

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

type Events = {
  (e: 'change', id: string): void;
};
const emit = defineEmits<Events>();

const { t } = useI18n();
const router = useRouter();

//#region 接口
const seizeRobots = async () => {
  const res = await seizeRobotByIds([...selected.keys()]);
  editor.value.updateRobots(res, { canControl: true });
};
//#endregion

const keyword = ref<string>('');

//#region 机器人列表
const groups = computed<RobotGroup[]>(() => editor.value.robotGroups.value ?? []);
const robots = computed<RobotInfo[]>(() => editor.value.robots.filter(({ label }) => label.includes(keyword.value)));
const getGroupRobots = (ids: RobotGroup['robots']) =>
  ids?.map((id) => editor.value.getRobotById(id)).filter((robot) => robot?.label.includes(keyword.value));

const selected = reactive<Set<RobotInfo['id']>>(new Set());
watch(
  () => props.editable,
  () => selected.clear(),
);

const isAllSelected = computed<boolean>(() => selected.size > 0 && robots.value.every(({ id }) => selected.has(id)));
const selectAll = (checked: boolean) => {
  if (checked) {
    robots.value.forEach(({ id }) => selected.add(id));
  } else {
    selected.clear();
  }
};

const checkGroupSelected = (ids: RobotGroup['robots']) => !!ids?.length && ids.every((id) => selected.has(id));
const selectGroup = (ids: RobotGroup['robots'], checked: boolean) => {
  if (checked) {
    ids?.forEach((id) => selected.add(id));
  } else {
    ids?.forEach((id) => selected.delete(id));
  }
};

const selectRobot = (id: RobotInfo['id'], checked: boolean) => {
  if (checked) {
    selected.add(id);
  } else {
    selected.delete(id);
  }
};
//#endregion

//#region 机器人组操作
const refAddRobot = shallowRef<RobotAddModalRef>();
const refRegisterRobot = shallowRef<RobotRegisterModalRef>();
const refRenameGroup = shallowRef<RobotGroupRenameModalRef>();

const toDeleteGroup = (id: RobotGroup['id']) =>
  Modal.confirm({
    class: 'confirm',
    title: t('您确定要删除该机器人组吗？'),
    centered: true,
    cancelText: t('返回'),
    okText: t('删除'),
    onOk: () => editor.value.deleteRobotGroup(id),
  });

const toEditGroup = (id: RobotGroup['id']) =>
  Modal.confirm({
    class: 'confirm',
    title: t('您确定要编辑该机器人组吗？'),
    content: t('请确保当前场景已经保存，否则将导致当前场景数据丢失。'),
    centered: true,
    cancelText: t('取消'),
    okText: t('编辑'),
    onOk: () => router.push({ name: '组编辑', params: { sid: props.sid, id } }),
  });
//#endregion

//#region 机器人操作
const toRemoveRobot = (id: RobotInfo['id']) =>
  Modal.confirm({
    class: 'confirm',
    title: t('您确定要从场景中移除该机器人吗？'),
    centered: true,
    cancelText: t('返回'),
    okText: t('移除'),
    onOk: () => {
      editor.value.removeRobots([id]);
      selected.delete(id);
    },
  });

const toRemoveRobots = () =>
  Modal.confirm({
    class: 'confirm',
    title: t('您确定要从场景中移除已选机器人吗？'),
    centered: true,
    cancelText: t('返回'),
    okText: t('移除'),
    onOk: () => {
      editor.value.removeRobots([...selected.keys()]);
      selected.clear();
    },
  });
//#endregion
</script>

<template>
  <RobotAddModal ref="refAddRobot" :token="token" />
  <RobotRegisterModal ref="refRegisterRobot" :token="token" />
  <RobotGroupRenameModal ref="refRenameGroup" :token="token" />

  <a-flex class="full" vertical>
    <a-input class="search mb-16" :placeholder="$t('请输入搜索关键字')" v-model:value="keyword">
      <template #suffix>
        <i class="icon search size-16" />
      </template>
    </a-input>

    <a-flex v-if="editable" class="mb-8" style="height: 32px" justify="space-between" align="center">
      <a-checkbox :checked="isAllSelected" @change="selectAll($event.target.checked)">{{ $t('全选') }}</a-checkbox>
      <a-space align="center">
        <a-button
          class="icon-btn panel-btn"
          :title="$t('抢占控制权')"
          size="small"
          @click="seizeRobots"
          :disabled="!selected.size"
        >
          <i class="mask control" />
        </a-button>
        <a-button
          class="icon-btn panel-btn"
          :title="$t('移除机器人')"
          size="small"
          @click="toRemoveRobots"
          :disabled="!selected.size"
        >
          <i class="mask trash_fill" />
        </a-button>
      </a-space>
    </a-flex>

    <a-collapse style="flex: auto; overflow-y: auto" expand-icon-position="end" ghost>
      <template #expandIcon="v">
        <i class="icon dropdown" :class="{ active: v?.isActive }" />
      </template>

      <a-collapse-panel v-for="{ id, label, robots } in groups" :key="id">
        <template v-if="editable" #extra>
          <a-dropdown placement="bottomRight">
            <a-button class="icon-btn" size="small" @click.stop>
              <i class="icon dot" />
            </a-button>
            <template #overlay>
              <a-menu>
                <a-menu-item>
                  <a-space align="center" :size="4" @click="refAddRobot?.open(id)">
                    <i class="icon plus size-20" />
                    <span>{{ $t('添加机器人') }}</span>
                  </a-space>
                </a-menu-item>
                <a-menu-item>
                  <a-space align="center" :size="4" @click="refRegisterRobot?.open(id)">
                    <i class="icon register size-20" />
                    <span>{{ $t('注册机器人') }}</span>
                  </a-space>
                </a-menu-item>
                <a-menu-item @click="refRenameGroup?.open(id, label)">
                  <a-space align="center" :size="4">
                    <i class="icon pen size-20" />
                    <span>{{ $t('修改组名称') }}</span>
                  </a-space>
                </a-menu-item>
                <a-menu-item @click="toDeleteGroup(id)">
                  <a-space align="center" :size="4">
                    <i class="icon trash size-20" />
                    <span>{{ $t('删除组') }}</span>
                  </a-space>
                </a-menu-item>
              </a-menu>
            </template>
          </a-dropdown>
        </template>

        <template #header>
          <a-flex justify="space-between" align="center">
            <a-space align="center" :size="8">
              <a-checkbox
                v-if="editable"
                :checked="checkGroupSelected(robots)"
                @change="selectGroup(robots, $event.target.checked)"
                @click.stop
              />
              <span>{{ label }}</span>
            </a-space>
            <a-button v-if="!editable" class="open-group-btn icon-btn" size="small" @click.stop="toEditGroup(id)">
              <i class="icon edit_group" />
            </a-button>
          </a-flex>
        </template>

        <a-list rowKey="id" :data-source="getGroupRobots(robots)">
          <template #renderItem="{ item }">
            <a-list-item
              :class="{ 'ph-16': !editable, 'pl-12': editable, 'pr-8': editable, selected: item.id === current }"
              style="height: 36px"
              @click="emit('change', item.id)"
            >
              <template v-if="editable" #actions>
                <a-button
                  class="icon-btn panel-btn"
                  :title="$t('移除机器人')"
                  size="small"
                  @click.stop="toRemoveRobot(item.id)"
                >
                  <i class="icon trash_fill" />
                </a-button>
              </template>
              <a-space align="center" :size="8">
                <a-checkbox
                  v-if="editable"
                  :checked="selected.has(item.id)"
                  @change="selectRobot(item.id, $event.target.checked)"
                  @click.stop
                />
                <a-typography-text type="secondary">{{ item.label }}</a-typography-text>
              </a-space>
            </a-list-item>
          </template>
        </a-list>
      </a-collapse-panel>
    </a-collapse>

    <a-button class="mt-8" v-if="editable" type="dashed" size="large" block @click="editor.createRobotGroup()">
      <i class="mask plus size-20 primary" />
      <span>{{ $t('添加机器人组') }}</span>
    </a-button>
  </a-flex>
</template>

<style scoped lang="scss">
.open-group-btn {
  margin-right: -8px;
  visibility: hidden;

  .ant-collapse-header:hover & {
    visibility: visible;
  }
}
</style>
