<template>
  <div class="report_module">
    <div class="module_title" v-if="showHeader">
      <div class="title_left">
        <template v-if="showTitle && titleList.length">
          <template v-for="(item, index) in titleList">
            <span :class="{ span_item: index != titleList.length - 1 }">{{
              item
            }}</span>
            <span v-if="index != titleList.length - 1" class="split_line"
              >/</span
            >
          </template>
        </template>
        <slot name="title_left" />
      </div>
      <div class="title_right">
        <slot name="title_right" />
        <template v-if="showPrintBtn">
          <el-button
            class="default_button"
            :loading="state.printLoading"
            @click="PrintPdf"
          >
            <img
              v-if="!state.printLoading"
              src="@/assets/icon/print_icon.webp"
            />打印PDF
          </el-button>
        </template>
        <template v-if="showExportBtn">
          <el-button
            class="default_button"
            :loading="state.exportLoading"
            @click="ExportExcel"
          >
            <img
              v-if="!state.exportLoading"
              src="@/assets/icon/export_icon.webp"
            />导出Excel
          </el-button>
        </template>
      </div>
    </div>
    <div
      :class="[`module_${tableOrChart}`, { table_42: tableOrChart == 'table' }]"
    >
      <!-- 其他 -->
      <slot name="module_qita" />
      <!-- 表格或图表显示 -->
      <slot name="module_table_chart" />
      <!-- 表格分页 -->
      <div
        class="page_pagination"
        v-if="tableOrChart == 'table' && showTablePage"
      >
        <el-pagination
          background
          :current-page="currentPage"
          :page-size="pageSize"
          :page-sizes="pageSizes"
          :layout="total > pageSize ? 'total,sizes,prev,pager,next' : 'total,sizes'"
          :total="total"
          @size-change="ChangePageSize"
          @current-change="ChangeCurrentPage"
        />
      </div>
    </div>
    <!-- 描述 -->
    <div v-if="showDescribe" class="module_describe">
      <div
        ref="textContainer"
        class="text_container"
        :class="{ expanded: state.isExpanded }"
      >
        <slot name="module_describe"></slot>
      </div>
      <button
        v-if="state.showExpandButton"
        @click="ToggleExpand"
        class="toggle_button"
        :class="state.isExpanded ? 'show_expanded' : 'hide_expanded'"
      >
        {{ state.isExpanded ? "收起" : "展开" }}
      </button>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { onMounted, reactive, nextTick, ref } from "vue";

interface TitleListType {
  showHeader?: boolean;
  titleList?: string[];
  showTitle?: boolean;
  showPrintBtn?: boolean;
  showExportBtn?: boolean;
  tableOrChart?: "table" | "chart" | "qita";
  showTablePage?: boolean;
  currentPage?: number;
  pageSize?: number;
  pageSizes?: number[];
  total?: number;
  showDescribe?: boolean;
}

const props = withDefaults(defineProps<TitleListType>(), {
  showHeader: true,
  titleList: () => [], //标题
  showTitle: true, //是否显示标题
  showPrintBtn: true, //是否显示打印按钮
  showExportBtn: true, //是否显示导出按钮
  tableOrChart: "table", //表格、图表、其他
  showTablePage: true, //是否显示分页
  currentPage: 1,
  pageSize: 10,
  pageSizes: () => [10, 20, 30, 40, 50, 100],
  total: 0,
  showDescribe: true, //是否显示描述
});

const emit = defineEmits<{
  ChangeCurrentPage: [val: number];
  ChangePageSize: [val: number];
  PrintPdf: [];
  ExportExcel: [];
}>();

// 状态管理
const state = reactive({
  printLoading: false,
  exportLoading: false,
  isExpanded: false,
  showExpandButton: true,
});

const textContainer = ref<HTMLElement | null>(null);
// 分页大小事件
const ChangePageSize = (val: number) => {
  emit("ChangePageSize", val);
};
// 当前页码事件
const ChangeCurrentPage = (val: number) => {
  emit("ChangeCurrentPage", val);
};
// 打印PDF
const PrintPdf = () => {
  emit("PrintPdf");
};
// 设置打印PDF加载状态
const SetPrintLoading = (val: boolean) => {
  state.printLoading = val;
};
// 导出Excel
const ExportExcel = () => {
  emit("ExportExcel");
};
// 设置导出Excel加载状态
const SetExportLoading = (val: boolean) => {
  state.exportLoading = val;
};
//文本展开收起逻辑
const checkLines = () => {
  const container = textContainer.value;
  if (!container) return;

  const lineHeight = parseInt(
    window.getComputedStyle(container).lineHeight || "24",
    10,
  );
  const textHeight = container.scrollHeight;
  const lines = Math.ceil(textHeight / lineHeight);
  state.showExpandButton = lines > 3;
};
// 文本展开收起事件
const ToggleExpand = () => {
  state.isExpanded = !state.isExpanded;
};

onMounted(() => {
  nextTick(() => checkLines());
});
defineExpose({
  SetExportLoading,
  SetPrintLoading,
});
</script>

<style lang="scss" scoped>
.report_module {
  width: 100%;
  background-color: #fff;
  margin-top: 10px;
  border-radius: 10px;

  &:nth-child(1) {
    margin-top: 0;
  }

  .module_title {
    width: 100%;
    padding: 20px 20px 10px;
    box-sizing: border-box;
    margin: auto;
    display: flex;
    align-items: center;
    justify-content: space-between;

    .title_left {
      display: inline-flex;
      align-items: center;
      flex-wrap: wrap;
      font-weight: 600;
      font-size: 16px;
      color: #333333;
      text-align: left;
      line-height: 36px;

      .span_item {
        font-weight: 400;
        font-size: 16px;
        color: #999999;
      }

      .split_line {
        font-weight: 400;
        font-size: 16px;
        color: #999999;
        margin: 0 6px;
      }
    }

    .title_right {
      display: flex;
      justify-content: flex-end;
      align-items: center;
      gap: 10px;
      :deep(.el-button) {
        span {
          display: flex;
          align-items: center;
        }

        img {
          width: 16px;
          height: 16px;
          margin-right: 4px;
        }
      }
      .default_button {
        margin-left: 0px;
        height: 36px;
        line-height: 36px;
        padding: 0 10px;
        font-weight: 400;
        font-size: 14px;
        color: #666666;
        display: flex;
        align-items: center;

        &:active,
        &:focus {
          outline: none; // 去掉点击后的轮廓
          box-shadow: none; // 去掉点击后的阴影
          background-color: inherit; // 保持背景颜色不变
          color: #666666; // 保持文字颜色不变
          border: 1px solid #dcdfe6;
        }

        &:hover {
          background-color: #f9f9f9;
          border: 1px solid #dcdfe6;
          color: #666;
        }
      }
      :deep(.button_set_header) {
        //设置表头
        font-size: 14px;
        color: #2e64fa;
        border: 1px solid #2e64fa;
        padding: 0px 10px !important;
      }
      :deep(.right_item) {
        font-size: 14px;
        color: #999;
        font-weight: 400;
        cursor: pointer;
        height: 30px;
        line-height: 30px;
        margin-right: 5px;
        border-bottom: 2px solid #ffffff;
        &.no_border {
          border-bottom: 0 !important;
        }

        &.item_active {
          font-size: 14px;
          color: #2e64fa;
          font-weight: 500;
          cursor: pointer;
          border-bottom: 2px solid #2e64fa;
        }
      }
    }
  }

  .module_table {
    width: 100%;
    padding: 0 20px 14px;
    box-sizing: border-box;
    border-collapse: collapse;

    :deep(.el-table) {
      border-radius: 6px;
      border-left: 0px;
      border-right: 0px;

      .el-table__header {
        .cell {
          font-size: 14px;
        }
      }
      .cell {
        display: block;
        text-align: center;
        white-space: nowrap;
        padding: 0 0 0 4px !important;
      }
    }

    :deep(.table_row_blue) {
      color: #2e64fa;
      cursor: pointer;
    }
  }

  .module_chart {
    width: 100%;
    padding: 0 20px;
    box-sizing: border-box;
    min-height: 360px;

    //无数据显示
    :deep(.no_content_data) {
      background-image: url("../assets/bg/no_content_bg.png");
      background-repeat: no-repeat;
      background-size: 360px auto;
      background-position: 50% 30%;
      color: #999999;
      justify-content: center;
      display: flex;
      align-items: center;
      min-height: 360px;

      span {
        margin-top: 80px;
        font-size: 14px;
      }
    }
  }

  .module_describe {
    width: 100%;
    padding: 14px 20px;
    box-sizing: border-box;
    font-weight: 400;
    font-size: 14px;
    color: #999999;
    line-height: 24px;
    text-align: left;

    .text_container {
      position: relative;
      overflow: hidden;
      text-overflow: ellipsis;
      display: -webkit-box;
      -webkit-line-clamp: 3;
      -webkit-box-orient: vertical;
      transition: max-height 0.3s ease-out;
      max-height: 72px;

      p {
        line-height: 22px;
      }
    }

    .text_container.expanded {
      -webkit-line-clamp: unset;
      max-height: none;
    }

    .toggle_button {
      margin-top: 8px;
      cursor: pointer;
      background: none;
      border: none;
      color: #2e64fa;
      font-size: 14px;
      line-height: 1;
      width: 100%;
      height: 24px;
      text-align: right;
      padding: 0 20px 0 0;
    }

    .show_expanded {
      background-image: url("@/assets/icon/up_expanded.webp");
      background-size: 16px 16px;
      background-position: 100% 50%;
      background-repeat: no-repeat;
    }

    .hide_expanded {
      background-image: url("@/assets/icon/down_expanded.webp");
      background-size: 16px 16px;
      background-position: 100% 50%;
      background-repeat: no-repeat;
    }
  }

  .module_qita {
    width: 100%;
    display: flex;
    :deep(.content_left) {
      padding-left: 20px;
      box-sizing: border-box;
    }
    :deep(.content_right) {
      padding-right: 20px;
      box-sizing: border-box;
    }
    :deep(.table_42) {
      padding-bottom: 0;
      .el-table {
        border-left: 0px;
        border-right: 0px;
        .cell {
          display: block;
          text-align: center;
          white-space: nowrap;
          padding: 0 0 0 4px !important;
        }
      }
    }
  }
  :deep(.el-loading-spinner) {
    .el-loading-text {
      font-size: 14px;
      margin: 0 auto;
    }
    .circular {
      width: 20px;
      height: 20px;
      color: #2e64fa;
    }
  }
}
</style>
