import ItemObject from "@/modules/list/objects/item";
import { Dialog } from "@/modules/list/state";
import Item from "./item";
import { css } from "@linaria/core";
import {
  defineComponent,
  onMounted,
  reactive,
  nextTick,
  ref,
  computed,
  onUnmounted,
} from "vue";
import { object } from "vue-types";
import { useCtx } from "../../context";

export default defineComponent({
  props: {
    data: object<Dialog>().isRequired,
  },
  emits: ["move"],
  setup(props) {
    const ctx = useCtx();
    const { list } = ctx;
    const closeRef = ref();
    const state = reactive({
      width: props.data.width,
      height: props.data.height,
      x: props.data.x,
      y: props.data.y,
      scale: 0,
      itemData: {} as any,
      touchClient: null as any,
      dialogId: 0,
    });

    const pos = computed(() => {
      return {
        x: props.data.x,
        y: props.data.y,
      };
    });

    onMounted(() => {
      state.itemData = list.list.find((e) => {
        return e._id == props.data.dataId;
      });
      setTimeout(() => {
        nextTick(() => {
          state.scale = 1.0;
          closeTimeStart();
        });
      }, 10);
      //@ts-ignore
      dialogRef.value.dialogId = props.data.id;
      dialogRef.value?.addEventListener("touchstart", (e) => {
        closeTimeEnd();
      });

      dialogRef.value.addEventListener("touchmove", (e) => {
        if (state.touchClient) {
          let targetTouch = e.targetTouches[0];
          let x = targetTouch.clientX - state.touchClient.x;
          let y = targetTouch.clientY - state.touchClient.y;
          list.actions.moveDialog(props.data.id, x, y);
          state.touchClient.x = targetTouch.clientX;
          state.touchClient.y = targetTouch.clientY;
        }
      });
      dialogRef.value.addEventListener("touchend", (e) => {
        state.touchClient = null;
        closeTimeStart();
      });
      dialogRef.value?.addEventListener("mousedown", (e) => {
        closeTimeEnd();
      });
      dialogRef.value?.addEventListener("mousemove", (e) => {
        if (state.dialogId) {
          list.actions.moveDialog(state.dialogId, e.movementX, e.movementY);
        }
      });

      dialogRef.value?.addEventListener("mouseup", (e) => {
        state.dialogId = 0;
        closeTimeStart();
      });
      window.addEventListener("message", (e) => {
        const data = JSON.parse(e.data);
        if (data.type == "start") {
          messageCloseEnd(data.dialogId);
        } else {
          messageCloseStart(data.dialogId);
        }
      });
    });
    onUnmounted(() => {
      closeTimeEnd();
    });
    const closeTimeStart = () => {
      closeTimeEnd();
      closeRef.value = setTimeout(close, 30000);
    };
    const messageCloseStart = (dialogId?: number) => {
      if (dialogId == props.data.id) {
        closeTimeStart();
      }
    };
    const messageCloseEnd = (dialogId?: number) => {
      if (dialogId == props.data.id) {
        closeTimeEnd();
      }
    };
    const closeTimeEnd = () => {
      if (closeRef.value) {
        clearTimeout(closeRef.value);
      }
    };

    function close() {
      state.scale = 0;
      list.actions.closingDialog(props.data);
      setTimeout(() => {
        list.actions.deleteDialog(props.data);
      }, 400);
    }
    const dialogRef = ref<HTMLElement>();
    const dialogMove = (flag: boolean) => {
      if (flag) {
        state.dialogId = props.data.id;
      }
    };
    const dialogTouch = (client: any) => {
      state.touchClient = client;
    };

    return () => (
      <div
        ref={dialogRef}
        class={dialogStyle}
        style={{
          transform: `translate(-50%, -50%) scale(${state.scale})`,
          left: `${pos.value.x}px`,
          top: `${pos.value.y}px`,
          width: Math.floor(state.width / 100) + "rem",
          height: Math.floor(state.height / 100) + "rem",
        }}
      >
        <div class={"dialog_view"}>
          {state.itemData._id && (
            <Item
              data={state.itemData}
              dialogId={props.data.id}
              onClose={close}
              onMove={dialogMove}
              onTouch={dialogTouch}
            />
          )}
        </div>
      </div>
    );
  },
});

const dialogStyle = css`
  transform: scale(0);
  transition: transform 0.4s;
  transform-origin: center;
  transition-timing-function: cubic-bezier(0.22, 0.61, 0.36, 1);
  position: absolute;
  background: url("~@/assets/dialog_bg.png") no-repeat center/cover;
  .dialog_view {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 7rem;
    height: 7rem;
    transform: translate(-50%, -50%);
  }
`;
