<template>
  <div
    class="swipe-container"
    data-weiling-mobile-ui-wl-steps
    @mouseenter="handleMouseEnter"
    @mouseleave="handleMouseLeave"
  >
    <span
      class="top-btn"
      :style="[cssButtonColor, { opacity: showTopButton ? '1' : '0' }]"
      @click="actionHandle"
      v-if="!hideTop && isPc"
    >
      {{ buttonText }}
    </span>
    <div
      class="swipe-wrapper"
      ref="swipeWrapper"
    >
      <div
        class="swipe-content"
        @touchstart="onTouchStart"
        @touchmove="onTouchMove"
        @touchend="onTouchEnd"
      >
        <slot></slot>
      </div>
    </div>
    <div
      class="swipe-actions"
      :style="{ width: actionWidth / 100 + 'rem' }"
    >
      <div
        class="action-wrapper"
        @click="actionHandle"
      >
        <slot name="actions">
          <button
            class="swipe-action"
            :style="cssButtonWidth"
          >
            {{ buttonText }}
          </button>
        </slot>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
export default {
  name: "WlSwipeCell",
};
</script>

<script lang="ts" setup>
import { ref, computed } from "vue";
import { judgePcOrH5 } from "@mobileUI/utils";

type Props = {
  width: number;
  buttonText: string;
  hideTop: boolean;
  noSliding: boolean;
  topButtonBgColor: string;
  topButtonBdColor: string;
  topButtonColor: string;
};
const props = withDefaults(defineProps<Props>(), {
  width: 56,
  buttonText: "置顶",
  hideTop: false,
  noSliding: false,
  topButtonBgColor: "#1c9fff",
  topButtonBdColor: "#1c9fff",
  topButtonColor: "#fff",
});

const touchStartX = ref(0);
const touchCurrentX = ref(0);
const actionWidth = ref(props.width);
const swipeWrapper = ref(null);
const hasMoved = ref(false);
const swipeThreshold = 50;

const cssButtonColor = computed(() => {
  return {
    "--cssButtonBgColor": props.topButtonBgColor,
    "--cssButtonBdColor": props.topButtonBdColor,
    "--cssButtonColor": props.topButtonColor,
  };
});

const cssButtonWidth = computed(() => {
  return { "--cssButtonWidth": props.width / 100 + "rem" };
});

const isPc = judgePcOrH5() === "PC";

const emit = defineEmits<{
  (e: "onAction", val: any);
}>();

const onTouchStart = (event: TouchEvent) => {
  if (props.noSliding || isPc) return;
  touchStartX.value = event.touches[0].clientX;
};

const onTouchMove = (event: TouchEvent) => {
  if (props.noSliding || isPc) return;
  touchCurrentX.value = event.touches[0].clientX;
  const deltaX = touchStartX.value - touchCurrentX.value;
  hasMoved.value = true;
  if (deltaX > swipeThreshold) {
    swipeWrapper.value.style.transform = `translateX(-${Math.min(
      deltaX / 100,
      actionWidth.value / 100
    )}rem)`;
  }
};

const onTouchEnd = (event: TouchEvent) => {
  if (props.noSliding || isPc) {
    hasMoved.value = false;
    return;
  }
  const deltaX = touchStartX.value - touchCurrentX.value;
  if (hasMoved.value) {
    if (deltaX > actionWidth.value / 2) {
      swipeWrapper.value.style.transform = `translateX(-${actionWidth.value / 100
        }rem)`;
    } else {
      swipeWrapper.value.style.transform = "translateX(0)";
    }
  }
  hasMoved.value = false;
};

const showTopButton = ref(false);
let timer: number | undefined;

const handleMouseEnter = () => {
  if (!isPc) return;
  timer = window.setTimeout(() => {
    showTopButton.value = true;
  }, 500);
};

const handleMouseLeave = () => {
  if (!isPc) return;
  window.clearTimeout(timer);
  showTopButton.value = false;
};

const actionHandle = () => {
  if (isPc) {
    showTopButton.value = false;
  }
  swipeWrapper.value.style.transform = "translateX(0)";
  emit("onAction", "");
};
</script>

<style lang="scss">
.swipe-container[data-weiling-mobile-ui-wl-steps] {
  position: relative;
  overflow: hidden;

  .swipe-wrapper {
    display: grid;
    grid-template-columns: 1fr auto;
    transition: transform 0.3s;
    z-index: 2;
    position: relative;
  }

  .swipe-content {
    position: relative;
    overflow: hidden;
  }

  .swipe-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    position: absolute;
    right: 0;
    top: 0;
    height: 100%;
    font-size: j(16);
  }

  .action-wrapper {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    height: 100%;
  }

  .swipe-action {
    display: flex;
    align-items: center;
    justify-content: center;
    width: var(--cssButtonWidth);
    height: 100%;
    background-color: #bfedff;
    color: #1c9fff;
    border: none;
    padding: 0 5px;
  }

  .top-btn {
    position: absolute;
    top: 8px;
    right: 10px;
    opacity: 0;
    transition: opacity 1.8s;
    height: j(20);
    line-height: j(20);
    text-align: center;
    border: j(1) solid rgb(228, 233, 237);
    background: #fff;
    color: #919699;
    border-radius: j(4);
    font-size: j(12);
    cursor: pointer;
    z-index: 3;
    padding: 0 j(6);

    &:hover {
      background: var(--cssButtonBgColor);
      border-color: var(--cssButtonBdColor);
      color: var(--cssButtonColor);
    }
  }

  &:hover .top-btn {
    opacity: 1;
  }
}</style>
