<template>
  <div
    class="transformer-box flex"
    :style="{
      left: `${transformShop.x - 4}px`,
      top: `${transformShop.y - 4}px`,
    }"
    @click="activeShop = transformShop"
  >
    <LabelItem
      :shop="transformShop"
      :show="hasHover"
      :style="{
        transform: `scale(${transformShop.scale})`,
        transformOrigin: transformOrigin,
      }"
    />
    <div
      ref="baffleRef"
      class="baffle"
      :class="{ hide: props.shop.id !== activeShop.id }"
      @mouseover="hasHover = true"
      @mouseout="hasHover = false"
    ></div>
    <div
      ref="cornerLTRef"
      class="corner left-top"
      :class="{ hide: props.shop.id !== activeShop.id }"
    ></div>
    <div
      ref="cornerRTRef"
      class="corner right-top"
      :class="{ hide: props.shop.id !== activeShop.id }"
    ></div>
    <div
      ref="cornerLBRef"
      class="corner left-bottom"
      :class="{ hide: props.shop.id !== activeShop.id }"
    ></div>
    <div
      ref="cornerRBRef"
      class="corner right-bottom"
      :class="{ hide: props.shop.id !== activeShop.id }"
    ></div>
  </div>
</template>

<script setup lang="ts">
  import { ref, onMounted, nextTick, computed, onBeforeUnmount, watch } from 'vue';
  import { MapWorkShopInfoItem } from '../../stores/useMapEditor';
  import LabelItem from './LabelItem.vue';
  import useMapEditor from '../../stores/useMapEditor';
  import { storeToRefs } from 'pinia';
  import { TransformType } from './type';
  import { cloneDeep } from 'lodash-es';

  const mapEditor = useMapEditor();
  const { mapWidth, mapHeight, showShops, addedShops, activeShop } = storeToRefs(mapEditor);

  const props = defineProps<{ shop: MapWorkShopInfoItem }>();

  const transformShop = computed(() => showShops.value.find((item) => item.id === props.shop.id)!);
  const hasHover = ref(false);

  let transform: TransformType = TransformType.STATIC;
  let parentEl: HTMLDivElement;

  const baffleRef = ref<HTMLDivElement>();
  const cornerLTRef = ref<HTMLDivElement>();
  const cornerRTRef = ref<HTMLDivElement>();
  const cornerLBRef = ref<HTMLDivElement>();
  const cornerRBRef = ref<HTMLDivElement>();

  const originPos = {
    x: 0,
    y: 0,
  };

  const originRect = {
    w: 0,
    h: 0,
  };

  const transformOrigin = ref('center');

  const resizeRect = () => {
    originRect.w = baffleRef.value?.clientWidth || 0;
    originRect.h = baffleRef.value?.clientHeight || 0;
  };

  const getNumByBound = (num: number, min: number, max: number): number => {
    let ret = num;
    if (num > max) {
      ret = max;
    } else if (num < min) {
      ret = min;
    }
    return ret;
  };

  const handleMouseDown = (e) => {
    // console.log(e);
    if (transformShop.value.id !== activeShop.value.id) {
      return;
    }

    if (e.target === baffleRef.value) {
      console.log('move start');
      transform = TransformType.MOVE;
      originPos.x = e.clientX;
      originPos.y = e.clientY;
    } else if (e.target === cornerLTRef.value) {
      transform = TransformType.SCALE;
      transformOrigin.value = 'right bottom';
    } else if (e.target === cornerRTRef.value) {
      transform = TransformType.SCALE;
      transformOrigin.value = 'left bottom';
    } else if (e.target === cornerLBRef.value) {
      transform = TransformType.SCALE;
      transformOrigin.value = 'right top';
    } else if (e.target === cornerRBRef.value) {
      transform = TransformType.SCALE;
      transformOrigin.value = 'left top';
    } else {
      activeShop.value = {} as MapWorkShopInfoItem;
    }
  };

  const handleMouseMove = (e) => {
    let dx = e.clientX - originPos.x;
    let dy = e.clientY - originPos.y;
    originPos.x = e.clientX;
    originPos.y = e.clientY;
    const shop = showShops.value.find((item) => item.id === props.shop.id)!;
    if (e.target === baffleRef.value && transform === TransformType.MOVE) {
      const el = document.getElementById('shopEditContainer') as HTMLDivElement;
      const style = window.getComputedStyle(el, null);
      const transformInfo =
        style.getPropertyValue('-webkit-transform') ||
        style.getPropertyValue('-moz-transform') ||
        style.getPropertyValue('-ms-transform') ||
        style.getPropertyValue('-o-transform') ||
        style.getPropertyValue('transform') ||
        'FAIL';
      const scale = Number(transformInfo.split('(')[1].split(',')[0]);
      dx /= scale;
      dy /= scale;

      shop.x = getNumByBound(shop.x + dx, 0, mapWidth.value - originRect.w);
      shop.y = getNumByBound(shop.y + dy, 0, mapHeight.value - originRect.h);
    } else if (transform === TransformType.SCALE) {
      return;
      console.log('0-0-00-');
      console.log(originRect.w, originRect.h);
      console.log(dx, dy);

      const newW =
        originRect.w + dx + shop.x > mapWidth.value ? mapWidth.value - shop.x : originRect.w + dx;
      const newH =
        originRect.h + dy + shop.y > mapHeight.value ? mapHeight.value - shop.y : originRect.h + dy;
      shop.scale = shop.scale * Math.min(newW / originRect.w, newH / originRect.h);
      console.log(newW, newH, shop.scale);

      nextTick(() => {
        resizeRect();
      });
    }
  };

  const handleMouseUp = () => {
    transform = TransformType.STATIC;
    originPos.x = 0;
    originPos.y = 0;
    addedShops.value = cloneDeep(showShops.value);
  };

  watch(
    activeShop,
    (val) => {
      if (val.id === props.shop.id) {
        bindListener();
      } else {
        unbindListener();
      }
    },
    {
      deep: true,
    },
  );

  onMounted(() => {
    parentEl = document.getElementById('drawContainer') as HTMLDivElement;
    resizeRect();
    bindListener();
  });

  const bindListener = () => {
    parentEl.addEventListener('mousedown', handleMouseDown);
    parentEl.addEventListener('mousemove', handleMouseMove);
    parentEl.addEventListener('mouseup', handleMouseUp);
  };

  const unbindListener = () => {
    parentEl.removeEventListener('mousedown', handleMouseDown);
    parentEl.removeEventListener('mousemove', handleMouseMove);
    parentEl.removeEventListener('mouseup', handleMouseUp);
  };

  onBeforeUnmount(() => {
    unbindListener();
  });
</script>

<style scoped lang="scss">
  .transformer-box {
    position: absolute;
    padding: 4px;
  }

  .baffle {
    position: absolute;
    width: 100%;
    height: 100%;
    border: 2px solid #4573bd;
    top: 0;
    left: 0;
    cursor: move;
    transform: none;
  }

  .corner {
    position: absolute;
    width: 12px;
    height: 12px;
    background-color: #ffffff;
    border: 2px solid #4573bd;
    cursor: crosshair;

    &.left-top {
      left: 0;
      top: 0;
      transform: translate(-50%, -50%);
    }

    &.right-top {
      right: 0;
      top: 0;
      transform: translate(50%, -50%);
    }

    &.left-bottom {
      left: 0;
      bottom: 0;
      transform: translate(-50%, 50%);
    }

    &.right-bottom {
      right: 0;
      bottom: 0;
      transform: translate(50%, 50%);
    }
  }

  .hide {
    opacity: 0;
  }
</style>
