import { IconAdd, IconMove } from "@/assets/icons";
import { DesignComp } from "@/modules/editor/objects/DesignTemp/DesignComp";
import { css, cx } from "@linaria/core";
import { IconDelete } from "@queenjs/icons";
import "animate.css";
import {
  defineComponent,
  inject,
  onMounted,
  onUnmounted,
  reactive,
  ref,
} from "vue";
import { bool, string } from "vue-types";
import { useEditor } from "../../..";
import { useCompEditLayerRef, useCompRef } from "./hooks";

let intersectionObserver: any;
export const View = defineComponent({
  props: {
    compId: string().isRequired,
    editlayer: bool().def(true),
    showMask: bool().def(false),
    meta: bool().def(true),
  },
  emits: ["dblclick", "click"],
  setup(props, { slots, emit, attrs }) {
    const { store, actions, helper, controls } = useEditor();
    const compRef = useCompRef(props.compId, props.meta);
    const editorLayerRef = props.editlayer
      ? useCompEditLayerRef(props.compId)
      : ref();

    const isLongPage = controls.screenCtrl.isLongPage;
    const isPreview = inject("isPreview", false);

    const state = reactive({
      showAnimation: false,
    });

    function createBgStyles() {
      let bgS = {
        position: "absolute",
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        zIndex: -1,
      };
      return bgS;
    }

    function getAniStyles(comp: any) {
      if (!comp.layout.anim) return "";
      if (
        comp.layout.anim &&
        state.showAnimation &&
        ((!props.showMask && store.isEditMode) || !store.isEditMode)
      ) {
        return `animate__animated animate__${comp.layout.anim} animate__delay-0.1s`;
      } else {
        return "opacity-0";
      }
    }

    onUnmounted(() => {
      intersectionObserver.disconnect();
    });

    onMounted(() => {
      intersectionObserver = new IntersectionObserver((entries) => {
        if (entries[0].intersectionRatio <= 0) {
          if (isLongPage) return;
          state.showAnimation = false;
        } else {
          state.showAnimation = true;
        }
      });
      intersectionObserver.observe(compRef.value);
    });

    const pageCtrl = controls.pageCtrl;

    return () => {
      const comp = helper.findComp(props.compId);
      if (!comp) return store.isEditMode ? <div>无效组件</div> : null;
      const isStreamCard = helper.isStreamCard(props.compId);
      const gizmo = controls.selectCtrl.gizmo;
      const page = controls.pageCtrl;

      const showBgDiv = isPreview && !isLongPage;
      const isContiner = comp.compKey == "Container";

      let isFocus =
        store.isEditMode &&
        gizmo.state.transform.selected.length > 1 &&
        gizmo.state.lastId == props.compId;

      const style = helper.createStyle(comp.layout, comp);
      if (comp.compKey == "Container") {
        delete style.transform;
        style["transform-origin"] = "center center";
      }

      const cardStyles = helper.createViewStyles(comp.layout, comp);
      let bgStyles: any = {};
      if (showBgDiv) {
        bgStyles = createBgStyles();
        bgStyles.background = cardStyles.background;
        delete cardStyles.background;
      }
      if (comp.compKey == "Text") {
        cardStyles["overflow"] = "visible";
      }

      if (isStreamCard) {
        style.overflow = "unset";
        style.position = "relative";
      }
      if (store.isPreview) {
        style.overflow = "hidden";
      }

      const aniStyles = getAniStyles(comp);

      function RenderPre() {
        if (
          page.state.currStreamCardId != props.compId ||
          !isStreamCard ||
          !store.isEditMode
        )
          return;
        let i = pageCtrl.streamCardIds.indexOf(props.compId);
        if (i > 0) {
          const c = helper.findComp(
            pageCtrl.streamCardIds[i - 1]
          ) as DesignComp;
          const PreComp = controls.compUICtrl.state.components.get(
            c.compKey
          ) as any;
          return (
            <div
              class="absolute w-full h-150px pointer-events-none"
              style={{
                bottom: style.height,
              }}
            >
              {/* <div class="absolute w-full h-150px pointer-events-none overflow-hidden">
                <PreComp.Component
                  compId={c.id}
                  key={c.id}
                  style={{ position: "absolute", bottom: "0" }}
                />
              </div> */}
              {/* <div class={maskStyleUp}></div> */}
              <div class={[divideStyle, "bottom"]}>
                {/* <span class="tip">上一页分割线</span> */}
              </div>
            </div>
          );
        }
      }

      function RenderAfter() {
        if (
          page.state.currStreamCardId != props.compId ||
          !isStreamCard ||
          !store.isEditMode
        )
          return;

        let i = pageCtrl.streamCardIds.indexOf(props.compId);
        if (i < pageCtrl.streamCardIds.length - 1) {
          const c = helper.findComp(
            pageCtrl.streamCardIds[i + 1]
          ) as DesignComp;
          const AfterComp = controls.compUICtrl.state.components.get(
            c.compKey
          ) as any;
          return (
            <div class="relative pointer-events-none">
              {/* <div class="h-150px pointer-events-none overflow-hidden">
                <AfterComp.Component compId={c.id} key={c.id} />
              </div> */}

              {/* <div class={maskStyle}></div> */}
              <div class={[divideStyle, "top"]}>
                {/* <span class="tip">下一页分割线</span> */}
              </div>
            </div>
          );
        }
      }

      return (
        <>
          {showBgDiv && isContiner && <div style={bgStyles}></div>}
          <div
            {...attrs}
            ref={compRef}
            class={[
              comp.compKey,
              viewStyle,
              page.state.currStreamCardId == props.compId &&
                store.isEditMode &&
                !isPreview &&
                CurrCompStyle,
              isFocus && AnchorCompStyle,
              isFocus && groupCompCls,
            ]}
            style={style}
            onClick={(e) => {
              if (!store.isEditMode) {
                e.stopPropagation();
                emit("click");
              }
            }}
            onDblclick={() => emit("dblclick")}
          >
            <div
              class={aniStyles}
              style={cardStyles}
              onMousemove={(e) => {
                if (
                  !store.isEditMode ||
                  !controls.dragAddCtrl.dragingCompKey ||
                  !helper.isStreamCard(props.compId)
                )
                  return;
                controls.editorCtrl.clickPickComp(props.compId);
              }}
            >
              {showBgDiv && !isContiner && <div style={bgStyles}></div>}
              {slots.default?.()}
            </div>

            {/* {store.isEditMode &&
            isStreamCard &&
            store.currStreamCardId == props.compId && (
              <Hudop compId={props.compId} />
            )} */}

            {store.isEditMode && props.editlayer && (
              <div ref={editorLayerRef} class={editAreaStyle}></div>
            )}

            {props.showMask && isLongPage && (
              <>
                {RenderPre()}
                {RenderAfter()}
              </>
            )}
            {props.showMask &&
              !isLongPage &&
              controls.screenCtrl.state.screen.useFor == "mobile" && (
                <div
                  class={cx(
                    safeAreaStyles,
                    "absolute left-0 top-1/2 w-1/1 translate -translate-y-1/2 transform pointer-events-none"
                  )}
                  style={{
                    height: `${controls.screenCtrl.state.safeFactor * 100}%`,
                  }}
                >
                  <div class={[divideStyle, "top"]}>
                    <span class="tip"> 安全线</span>
                  </div>
                  <div class={[divideStyle, "bottom"]}>
                    <span class="tip"> 安全线</span>
                  </div>
                </div>
              )}
          </div>
        </>
      );
    };
  },
});

export const Hudop = defineComponent({
  props: {
    compId: string().isRequired,
  },
  setup(props) {
    const { store, actions, helper, controls } = useEditor();

    const opref = ref();

    onMounted(() => {
      opref.value.editable = "hudop";
    });

    const page = controls.pageCtrl;

    return () => (
      <div class="hudop shadow" ref={opref}>
        {page.streamCardIds.length > 1 && (
          <IconMove
            class="draganchor"
            onMousedown={() => controls.editorCtrl.clickPickComp(props.compId)}
          />
        )}
        {page.streamCardIds.length > 1 && (
          <IconDelete
            onClick={(e: any) => {
              e.stopPropagation();
              actions.removeStreamCard(props.compId);
            }}
          />
        )}
        <IconAdd
          onClick={(e: any) => {
            e.stopPropagation();
            const index = page.streamCardIds.indexOf(props.compId) + 1;
            actions.addCompToDesign("Container", index);
          }}
        />
      </div>
    );
  },
});

const viewStyle = css`
  position: relative;
  font-size: 0;
  cursor: pointer;
  flex-shrink: 0;

  > :first-child {
    width: 100%;
    height: 100%;
  }

  .hudop {
    position: absolute;
    top: 0px;
    left: -46px;
    background-color: white;
    flex-direction: column;
    color: black;
    display: flex;
    font-size: 12px;
    width: 28px;
    align-items: center;
    border-radius: 4px;
    z-index: 997;
    .inficon {
      padding: 8px;
    }
  }
`;

const editCompStyle = css`
  &:hover {
    outline: 2px dashed @inf-primary-color;
  }
`;

const CurrCompStyle = css`
  position: relative;
  z-index: 998;
  box-shadow: 0 0 0 3000px rgba(0, 0, 0, 0.5);
  &:before {
    content: "";
    position: absolute;
    left: -1px;
    right: -1px;
    top: -1px;
    bottom: -1px;
    z-index: 999;
    pointer-events: none;
    background-image: repeating-linear-gradient(
        to right,
        @inf-primary-color 0%,
        @inf-primary-color 50%,
        transparent 50%,
        transparent 100%
      ),
      repeating-linear-gradient(
        to right,
        @inf-primary-color 0%,
        @inf-primary-color 50%,
        transparent 50%,
        transparent 100%
      ),
      repeating-linear-gradient(
        to bottom,
        @inf-primary-color 0%,
        @inf-primary-color 50%,
        transparent 50%,
        transparent 100%
      ),
      repeating-linear-gradient(
        to bottom,
        @inf-primary-color 0%,
        @inf-primary-color 50%,
        transparent 50%,
        transparent 100%
      );
    background-position: left top, left bottom, left top, right top;
    background-repeat: repeat-x, repeat-x, repeat-y, repeat-y;
    background-size: 8px 1px, 8px 1px, 1px 8px, 1px 8px;
  }
`;
const AnchorCompStyle = css`
  &:before {
    background-size: 8px 2px, 8px 2px, 2px 8px, 2px 8px;
  }
`;

const groupCompCls = css`
  outline: 2px dashed @inf-primary-color !important;
`;

const editAreaStyle = css`
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
`;

// const editAreaTestStyle = css`
//   position: absolute;
//   top: 0;
//   left: 0;
//   width: 100px;
//   height: 100px;
//   background-color: red;
// `;
const maskStyle = css`
  background: rgba(0, 0, 0, 0.3);
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
`;

const maskStyleUp = css`
  background: rgba(0, 0, 0, 0.3);
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
`;

const divideStyle = css`
  position: absolute;
  left: -5%;
  width: 110%;
  height: 1px;
  background-image: linear-gradient(
    to right,
    #eb684e 0%,
    #eb684e 50%,
    transparent 50%
  );
  background-size: 8px 1px;
  background-repeat: repeat-x;

  &.top {
    top: 0;
  }

  &.bottom {
    bottom: 0;
  }
  .tip {
    margin-left: 15px;
    font-size: 12px;
    position: absolute;
    left: 100%;
    width: 80px;
    top: -10px;
    color: #eb684e;
  }
`;

const safeAreaStyles = css`
  box-shadow: 0 0 0 3000px rgba(0, 0, 0, 0.3);
`;
