<template>
    <div class="report_module">
        <div class="module_title">
            <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">
                        <img v-if="!state.printLoading" src="@/assets/icon/print_icon.webp" alt="打印PDF" />打印PDF
                    </el-button>
                </template>
                <template v-if="showExportBtn">
                    <el-button class="default_button" :loading="state.exportLoading">
                        <img v-if="!state.exportLoading" src="@/assets/icon/export_icon.webp" alt="导出Excel" />导出Excel
                    </el-button>
                </template>
            </div>
        </div>
        <div :class="[`module_${tableOrChart}`, { table_42: tableOrChart == 'table' }]">
            <!-- 表格或图表显示 -->
            <slot name="module_table_chart" />
            <!-- 表格分页 -->
            <div class="page_pagination" v-if="tableOrChart == 'table' && showTablePage && (total > pageSize)">
                <el-pagination background :current-page="currentPage" :page-size="pageSize" :page-sizes="pageSizes"
                    layout="total,sizes,prev,pager,next" :total="total" @size-change="HandleSizeChange"
                    @current-change="HandleCurrentChange" />
            </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 {
    titleList?: string[]
    showTitle?: boolean
    showPrintBtn?: boolean
    showExportBtn?: boolean
    tableOrChart?: 'table' | 'chart'
    showTablePage?: boolean
    currentPage?: number
    pageSize?: number
    pageSizes?: number[]
    total?: number
    showDescribe?: boolean
}

const props = withDefaults(defineProps<TitleListType>(), {
    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<{
    'update:currentPage': [val: number]
    'update:pageSize': [val: number]
}>()

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

const textContainer = ref<HTMLElement | null>(null)
// 分页事件
const HandleSizeChange = (val: number) => {
    emit('update:pageSize', val)
}

const HandleCurrentChange = (val: number) => {
    emit('update:currentPage', 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())
})
</script>

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

    .module_title {
        width: 100%;
        padding: 20px 20px 10px;
        box-sizing: border-box;
        margin: auto;
        font-weight: 600;
        font-size: 16px;
        color: #333333;
        text-align: left;
        line-height: 36px;
        display: flex;
        justify-content: space-between;

        .title_left {
            display: inline-flex;
            align-items: center;
            flex-wrap: wrap;

            .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;

            .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;
                }

                span {
                    display: flex;
                    align-items: center;
                }

                img {
                    width: 16px;
                    height: 16px;
                    margin-right: 4px;
                }

                .el-icon-loading {
                    color: #666;
                }
            }
        }
    }

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

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

    .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;
        }
    }
}
</style>