<template>
  <div class="flx-start-start flx-1">
    <el-icon class="mt-4 mr-13" size="24" v-if="icon"><component :is="eventIcon" /></el-icon>
    <div class="flx-col flx-1 h-full">
      <header class="flx-start flx-shrink">
        <div class="text-primary-text text-h4-m text-ellipsis-one2 flx-1" v-if="title">
          {{ title }}
        </div>
        <el-button
          v-if="!hideClose"
          circle
          text
          class="close-btn flx-shrink"
          :icon="CloseBold"
          @click="emit('close-toast')"
        ></el-button>
      </header>
      <main
        ref="mainRef"
        class="toast-message"
        :class="{ 'is-expand': !ifExpanded }"
        :style="{ height: ifOver && !ifExpanded ? lineHeight * line + 'px' : 'auto' }"
      >
        <span ref="spanRef" class="text-body-r text-primary-text" v-html="message"></span>
        <div ref="spanRef" v-if="ifExpanded && Boolean(hideMsg)" class="text-body-r text-primary-text" v-html="hideMsg"></div>
      </main>
      <footer class="flx-justify-between flx-shrink mt-8">
        <template v-if="actions.length">
          <el-button
            v-for="(item, index) in actions"
            :key="'toast-action' + index"
            v-bind="item.props"
            @click="handleAction(item)"
          >
            {{ item.label }}
          </el-button>
        </template>
        <template v-else>
          <el-text type="primary" @click.stop="copyFunc" style="cursor: pointer">Copy</el-text>
          <el-button v-if="ifOver || Boolean(hideMsg)" text bg :icon="ifExpanded ? ArrowUp : ArrowDown" @click="handleExpand">
            {{ ifExpanded ? "Put away" : "Expand" }}
          </el-button>
        </template>
      </footer>
    </div>
  </div>
</template>

<script setup lang="tsx" name="ToastErrCopy">
import { ref, computed, onMounted, onBeforeUnmount } from "vue";
import { ElMessage } from "element-plus";
import {
  InfoFilled,
  CircleCheckFilled,
  WarningFilled,
  CircleCloseFilled,
  WarnTriangleFilled,
  CloseBold,
  ArrowUp,
  ArrowDown
} from "@element-plus/icons-vue";

interface actionProps {
  label: string;
  value: number;
  props?: any;
}

interface ToastErrCopyProps {
  /**
   * @description 类型
   */
  type?: "default" | "info" | "success" | "error" | "warning";
  /**
   * @description 标题
   */
  title?: string;
  /**
   * @description 内容
   */
  message: string;
  /**
   * @description 是否隐藏关闭按钮
   */
  hideClose?: boolean;
  /**
   * @description 是否显示图标
   */
  icon?: boolean;
  /**
   * @description 行高
   */
  lineHeight?: number;
  /**
   * @description 超过N行就折叠
   */
  line?: number;
  actions?: actionProps[];
  /**
   * @description 隐藏信息
   */
  hideMsg?: string;
}
const props = withDefaults(defineProps<ToastErrCopyProps>(), {
  type: "default",
  title: "",
  message: "",
  hideClose: false,
  icon: true,
  lineHeight: 22,
  line: 4,
  actions: () => []
});

const eventIcon = computed(() => {
  let icon = undefined;
  switch (props.type) {
    case "info":
      icon = WarningFilled;
      break;
    case "success":
      icon = CircleCheckFilled;
      break;
    case "error":
      icon = CircleCloseFilled;
      break;
    case "warning":
      icon = WarnTriangleFilled;
      break;
    default:
      icon = InfoFilled;
      break;
  }
  return icon;
});

const ifOver = ref(false);
const ifExpanded = ref(false);

const emit = defineEmits(["close-toast", "actionClick"]);

/**
 * @description 事件: 一键复制
 */
const copyFunc = () => {
  const input = document.createElement("textarea");
  input.value = props.title ? props.title + "\r" + props.message : props.message;
  if (Boolean(props.hideMsg)) {
    input.value += props.hideMsg;
  }
  document.body.appendChild(input);
  input.select();
  document.execCommand("Copy");
  document.body.removeChild(input);
  ElMessage({
    type: "success",
    message: "复制成功"
  });
};

/**
 * @description 判断是否有内容超出
 */
const spanRef = ref();
const mainRef = ref();
onMounted(() => {
  ifOver.value =
    spanRef.value.offsetHeight > mainRef.value.offsetHeight || props.lineHeight * props.line < spanRef.value.offsetHeight;
  if (ifOver.value) {
    mainRef.value.addEventListener("scroll", mainScrollFunc);
  }
});

/**
 * @description 滚动监听事件
 */
const mainScrollFunc = () => {
  ifExpanded.value = true;
  mainRef.value.removeEventListener("scroll", mainScrollFunc);
};

/**
 * @description 事件: 展开与收起
 */
const handleExpand = () => {
  if (ifExpanded.value && ifOver.value) {
    mainRef.value.addEventListener("scroll", mainScrollFunc);
  }
  ifExpanded.value = !ifExpanded.value;
};

const handleAction = (action: actionProps) => {
  emit("actionClick", action);
};

onBeforeUnmount(() => {
  ifOver.value && mainRef.value.removeEventListener("scroll", mainScrollFunc);
});
</script>
