<template>
  <transition name="fade">
    <div
      class="control-panl"
      :class="{ full, pc: os.isPc && !os.isTablet, 'strengthen-right': full }"
      v-if="!hide"
    >
      <div class="control-layer">
        <div
          class="panl pub-panl start"
          v-if="!(os.isPc && !os.isTablet)"
          @click="useEmitLeave()"
        >
          <div class="include-icon" style="text-align: center">
            <ui-icon type="close"></ui-icon>
          </div>
        </div>

        <div :class="{ ['scroll-view']: !(os.isPc && !os.isTablet) }">
          <div
            class="panl"
            v-for="(groupItem, i) in group"
            :class="{ apart: groupItem.apart }"
          >
            <p v-if="groupItem.label">{{ groupItem.label }}</p>
            <VCtrl
              v-for="ctrl in groupItem.ctrls"
              :activeCtrls="modelValue"
              :ctrl="ctrl"
              @click="(ctrl) => clickHandler(ctrl)"
            />
          </div>
        </div>

        <div
          class="panl pub-panl end"
          :class="{ active: !disabledMap.tool, 'fun-ctrl': true }"
          v-if="!os.isPc"
          @click="disabledMap.tool = !disabledMap.tool"
        >
          <div class="include-icon nav-ctrl">
            <ui-icon type="list"></ui-icon>
            <span>{{ count }}</span>
          </div>
        </div>
      </div>
    </div>
  </transition>
</template>

<script lang="ts" setup>
import { ref, watchEffect, onActivated, onDeactivated, onUnmounted } from "vue";
import { Group, Ctrl } from "./index";
import { os } from "@/utils";
import { disabledMap, boxWidthStack, useEmitLeave, controlFullStack } from "@/hook";
import VCtrl from "./ctrl.vue";

const props = defineProps<{
  group: Group;
  show: boolean;
  modelValue: Array<Ctrl>;
  full?: boolean;
  count?: number;
}>();

const updateHide = (show = props.show) => {
  if (show) {
    setTimeout(() => (hide.value = false));
  } else {
    setTimeout(() => (hide.value = true));
  }
};

const hide = ref(true);

watchEffect(() => updateHide());
onActivated(updateHide);
onDeactivated(() => updateHide(false));

const emit = defineEmits<{
  (e: "update:modelValue", data: any, oldData: Array<Ctrl>): void;
  (e: "select", data: Ctrl): void;
}>();

const clickHandler = (ctrl: Ctrl) => {
  if (ctrl.inClick) {
    return emit("select", ctrl);
  }

  const newRuns = [...props.modelValue];
  const index = newRuns.indexOf(ctrl);
  if (~index) {
    newRuns.splice(index, 1);
  } else if (ctrl.makeup) {
    newRuns.push(ctrl);
  } else {
    const makeupRuns = newRuns.filter((item) => item.makeup);
    const ctrlGroups = props.group.find((group) => group.ctrls.includes(ctrl));
    const anewRuns = newRuns.filter((item) => {
      const currentGroups = props.group.find((group) => group.ctrls.includes(item));
      return currentGroups !== ctrlGroups && (currentGroups.makeup || ctrlGroups.makeup);
    });
    newRuns.length = 0;
    newRuns.push(...Array.from(new Set([...makeupRuns, ...anewRuns])), ctrl);
  }
  emit("update:modelValue", newRuns, props.modelValue);
};

watchEffect(() => {
  if (!props.show) {
    emit(
      "update:modelValue",
      props.group.reduce((t, c) => [...t, ...c.ctrls.filter((ctrl) => ctrl.def)], []),
      []
    );
  }
});

watchEffect(() => {
  if (props.modelValue.some((item) => "show" in item && !item.show)) {
    emit(
      "update:modelValue",
      props.modelValue.filter((item) => !("show" in item && !item.show)),
      []
    );
  }
});

if (!os.isPc) {
  let inset = false;
  let boxWidth = ref("calc(100% - 60px)");
  const sysWidth = boxWidthStack.current.value;

  watchEffect(() => {
    if (props.show) {
      boxWidth.value = sysWidth.value.includes("calc")
        ? "calc(100% - 60px)"
        : sysWidth.value;
      if (!inset) {
        boxWidthStack.push(boxWidth);
        inset = true;
      }
    } else if (inset) {
      boxWidthStack.pop();
      inset = false;
    }
  });
} else {
  let isShow;
  watchEffect(() => {
    if (isShow === props.show) {
      return;
    }
    if (props.show) {
      controlFullStack.push(ref(props.full));
    } else if (controlFullStack.length.value > 1) {
      controlFullStack.pop();
    }
    isShow = props.show;
  });

  onUnmounted(() => {
    if (isShow || isShow !== props.show) {
      controlFullStack.pop();
    }
  });
}
</script>

<style lang="sass" scoped>
@import './style.scss'
</style>

<style lang="scss">
.control-panl .icon .tip {
  width: 68px;
  word-break: break-all;
  white-space: normal;
  text-align: center;
  padding: 10px 4px;
}
</style>
