<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-two 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" v-if="!messageList.length" class="text-body-r text-primary-text" v-html="message"></span>
        <div ref="spanRef" v-else-if="showField" class="toast-list">
          <div
            class="toast-list_item flx-start pl-12 pr-12 pt-4 pb-4 mt-4"
            v-for="(item, index) in messageList"
            :key="index"
            @click="messageClick(item, showField.field)"
          >
            <div class="flx-1 flx-col mr-8">
              <span class="text-h5-m text-primary-text">
                {{ item[showField.field] }}
              </span>
              <span class="text-body-c text-secondary-text">
                {{ showField.title }}
              </span>
            </div>
            <div class="flx-shrink toast-list_item-right">
              <i class="iconfont iconLocation_light"></i>
            </div>
          </div>
        </div>
      </main>
      <footer class="flx-justify-between flx-shrink mt-8">
        <div class="left">
          <el-text v-if="message" type="primary" @click.stop="copyFunc" style="cursor: pointer">Copy</el-text>
        </div>
        <div class="right">
          <el-button v-if="ifOver" text bg :icon="ifExpanded ? ArrowUp : ArrowDown" @click="handleExpand">
            {{ ifExpanded ? "put away" : "expand" }}
          </el-button>
        </div>
      </footer>
    </div>
  </div>
</template>

<script setup lang="tsx" name="ToastErrCopyList">
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 ShowFieldType {
  field: string;
  title: string;
}

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

const eventIcon = computed(() => {
  let icon: any = 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", "messageClick"]);

/**
 * @description 事件: 一键复制
 */
const copyFunc = () => {
  const input = document.createElement("textarea");
  input.value = props.title ? props.title + "\r" + props.message : props.message;
  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;
};

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

const messageClick = (row: any, field: string) => {
  emit("messageClick", row, field);
};
</script>

<style lang="scss" scoped>
.toast-list {
  .toast-list_item {
    cursor: pointer;
    background-color: $color-gray-2;
    transition: all $ease-in-back 0.2s;
    border-radius: $br-sm;
    .toast-list_item-right {
      opacity: 0;
      transition: all $ease-in-back 0.2s;
    }
    &:hover {
      background-color: $color-gray-3;
      .toast-list_item-right {
        opacity: 1;
      }
    }
  }
}
</style>
