<template>
    <div class="app-container monthly-report-container">
        <splitpanes class="default-theme">
            <!-- 左侧：年份和月份选择 -->
            <pane :size="20" min-size="15" max-size="40">
                <el-card shadow="never" class="sidebar-card">
                    <template #header>
                        <div class="card-header">选择年月</div>
                    </template>

                    <div class="year-selector">
                        <el-date-picker
                            v-model="selectedYear"
                            type="year"
                            placeholder="请选择年份"
                            format="YYYY"
                            value-format="YYYY"
                            :disabled-date="disabledYearDate"
                            @change="onYearChange"
                            style="width: 100%"
                        />
                    </div>

                    <div class="month-list">
                        <div
                            v-for="month in monthOptions"
                            :key="month.value"
                            class="month-item"
                            :class="{ active: selectedMonth === month.value }"
                            @click="onMonthClick(month.value)"
                        >
                            {{ month.label }}
                        </div>
                    </div>
                </el-card>
            </pane>

            <!-- 右侧：PDF预览区域 -->
            <pane :size="80" min-size="60">
                <el-card shadow="never" class="preview-card">
                    <template #header>
                        <div class="card-header-wrapper">
                            <div class="card-header">
                                {{ reportTitle }}
                            </div>
                            <ComButton
                                type="primary"
                                icon="Download"
                                @click="onDownload"
                                v-hasPermi="['monthReport:monthlyReport:download']"
                            >
                                下载
                            </ComButton>
                        </div>
                    </template>

                    <div class="docx-preview-container" v-loading="loading">
                        <VueOfficeDocx
                            v-if="docxFile"
                            :src="docxFile"
                            style="height: 100%"
                            @rendered="onDocxRendered"
                            @error="onDocxError"
                        />
                        <el-empty v-else description="请选择年月查看月报" :image-size="120" />
                    </div>
                </el-card>
            </pane>
        </splitpanes>
    </div>
</template>

<script setup name="MonthlyReport">
import { ref, computed, onMounted } from 'vue'
import { getCurrentInstance } from 'vue'
import { Splitpanes, Pane } from 'splitpanes'
import 'splitpanes/dist/splitpanes.css'
import VueOfficeDocx from '@vue-office/docx'
import '@vue-office/docx/lib/index.css'
import ComButton from '@/components/ComButton/index.vue'
import { getToken } from '@/utils/auth'

const { proxy } = getCurrentInstance()

const selectedYear = ref(String(new Date().getFullYear()))
const selectedMonth = ref('')
const loading = ref(false)
const docxFile = ref(null)

// 获取当前年月
const currentYear = new Date().getFullYear()
const currentMonth = new Date().getMonth() + 1

// 生成月份选项（升序排列）
const monthOptions = computed(() => {
    if (!selectedYear.value) {
        return []
    }
    const year = parseInt(selectedYear.value)
    const months = []

    // 如果选择的是当前年份，只显示已过完的月份和当月
    if (year === currentYear) {
        for (let i = 1; i <= currentMonth; i++) {
            months.push({
                label: `${selectedYear.value}-${String(i).padStart(2, '0')}`,
                value: `${selectedYear.value}-${String(i).padStart(2, '0')}`,
            })
        }
    } else {
        // 如果选择的是过去的年份，显示所有12个月
        for (let i = 1; i <= 12; i++) {
            months.push({
                label: `${selectedYear.value}-${String(i).padStart(2, '0')}`,
                value: `${selectedYear.value}-${String(i).padStart(2, '0')}`,
            })
        }
    }
    return months // 升序排列
})

// 年份选择器禁用日期（禁用未来年份）
const disabledYearDate = (date) => {
    const year = date.getFullYear()
    return year > currentYear
}

// 报告标题
const reportTitle = computed(() => {
    if (selectedMonth.value) {
        const [year, month] = selectedMonth.value.split('-')
        return `${year}年${parseInt(month)}月作业项目分析`
    }
    return '月报预览'
})

// 年份变化
const onYearChange = (year) => {
    if (year) {
        selectedYear.value = year
    }
    selectedMonth.value = ''
    docxFile.value = null
}

// docx 渲染完成
const onDocxRendered = () => {
    console.log('DOCX 文件渲染完成')
}

// docx 渲染错误
const onDocxError = (error) => {
    console.error('DOCX 文件渲染失败:', error)
    proxy.$modal.msgError('文档预览失败，请稍后重试')
}

// 月份点击
const onMonthClick = async (month) => {
    if (selectedMonth.value === month) {
        return
    }
    selectedMonth.value = month
    await fetchReport()
}

// 检查是否是有效的 docx 文件（docx 文件是 ZIP 格式，以 PK 开头）
const isValidDocx = async (blob) => {
    try {
        const arrayBuffer = await blob.slice(0, 4).arrayBuffer()
        const uint8Array = new Uint8Array(arrayBuffer)
        // ZIP 文件签名：PK\x03\x04 (50 4B 03 04)
        return (
            uint8Array[0] === 0x50 &&
            uint8Array[1] === 0x4b &&
            uint8Array[2] === 0x03 &&
            uint8Array[3] === 0x04
        )
    } catch (e) {
        return false
    }
}

// 检查是否是 JSON 错误响应
const isJsonError = async (blob) => {
    try {
        const text = await blob.slice(0, 100).text()
        return text.trim().startsWith('{') || text.trim().startsWith('[')
    } catch (e) {
        return false
    }
}

// 使用原生 fetch 获取文件流，避免 axios 拦截器将二进制数据转换为字符串
const fetchReport = async () => {
    if (!selectedMonth.value) {
        return
    }

    loading.value = true
    docxFile.value = null

    // 如果之前有 Object URL，先释放
    if (
        docxFile.value &&
        typeof docxFile.value === 'string' &&
        docxFile.value.startsWith('blob:')
    ) {
        URL.revokeObjectURL(docxFile.value)
    }

    try {
        const baseURL = import.meta.env.VITE_APP_BASE_API
        const url = `${baseURL}/download/monthReport`

        console.log('使用 fetch 获取文件:', url, '参数:', { month: selectedMonth.value })

        // 构建查询参数
        const params = new URLSearchParams({
            month: selectedMonth.value,
        })

        const response = await fetch(`${url}?${params.toString()}`, {
            method: 'POST',
            headers: {
                Authorization: 'Bearer ' + getToken(),
            },
        })

        // 检查响应状态
        if (!response.ok) {
            // 尝试读取错误信息
            const errorText = await response.text()
            try {
                const errorData = JSON.parse(errorText)
                proxy.$modal.msgError(errorData.msg || '获取月报失败')
            } catch (e) {
                proxy.$modal.msgError(`获取月报失败: ${response.status} ${response.statusText}`)
            }
            docxFile.value = null
            return
        }

        // 检查 Content-Type
        const contentType = response.headers.get('content-type') || ''
        console.log('响应 Content-Type:', contentType)

        // 获取 Blob
        const blob = await response.blob()
        console.log('获取到 Blob，大小:', blob.size, '字节，类型:', blob.type)

        // 检查 Blob 大小是否合理
        if (blob.size < 1024) {
            console.warn('警告：Blob 大小异常小，可能数据不完整')
            // 尝试读取文本看看是否是错误信息
            try {
                const text = await blob.text()
                const errorData = JSON.parse(text)
                if (errorData.code && errorData.code !== 200) {
                    proxy.$modal.msgError(errorData.msg || '获取月报失败')
                    docxFile.value = null
                    return
                }
            } catch (e) {
                // 不是 JSON，继续处理
            }
        }

        // 检查是否是有效的 docx 文件
        const isValid = await isValidDocx(blob)
        console.log('是否为有效的 docx 文件:', isValid)

        if (!isValid) {
            // 如果不是有效的 docx，尝试读取文本看看是否是错误信息
            try {
                const text = await blob.text()
                console.log('文件内容预览（前500字符）:', text.substring(0, 500))
                const errorData = JSON.parse(text)
                if (errorData.code && errorData.code !== 200) {
                    proxy.$modal.msgError(errorData.msg || '获取月报失败')
                    docxFile.value = null
                    return
                }
            } catch (e) {
                console.error('文件格式检查失败:', e)
                proxy.$modal.msgError(
                    '返回的文件不是有效的 docx 格式，请检查后端接口是否正确返回文件流',
                )
                docxFile.value = null
                return
            }
        }

        // @vue-office/docx 支持 Blob、ArrayBuffer 或 URL
        // 直接使用 Blob 对象
        docxFile.value = blob
        console.log('DOCX 文件准备完成，Blob 大小:', blob.size, '字节')
    } catch (error) {
        console.error('获取月报失败:', error)
        proxy.$modal.msgError('获取月报失败，请稍后重试。错误：' + (error.message || error))
        docxFile.value = null
    } finally {
        loading.value = false
    }
}

// 下载月报
const onDownload = async () => {
    // if (!selectedMonth.value) {
    //     proxy.$modal.msgWarning('请先选择年月')
    //     return
    // }
    // const result = await downloadMonthlyReportAPI({
    //     month: selectedMonth.value,
    // })
    // console.log('result', result)
    try {
        proxy.download(
            '/download/monthReport',
            {
                month: selectedMonth.value,
            },
            `${selectedYear.value}年${parseInt(
                selectedMonth.value.split('-')[1],
            )}月作业项目分析.docx`,
        )
    } catch (error) {
        console.error('下载月报失败:', error)
        proxy.$modal.msgError('下载月报失败，请稍后重试')
    }
}

// 初始化：默认选择当前月份
onMounted(() => {
    const now = new Date()
    selectedYear.value = String(now.getFullYear())
    const currentMonth = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`
    selectedMonth.value = currentMonth
    fetchReport()
})
</script>

<style scoped lang="scss">
.monthly-report-container {
    height: calc(100vh - 84px);
    padding: 20px;

    :deep(.splitpanes__pane) {
        overflow: hidden;
    }

    .sidebar-card {
        height: 100%;
        display: flex;
        flex-direction: column;

        :deep(.el-card__body) {
            flex: 1;
            display: flex;
            flex-direction: column;
            overflow: hidden;
        }
    }

    .card-header {
        font-weight: 600;
        font-size: 16px;
        color: #1f2937;
    }

    .year-selector {
        margin-bottom: 20px;
    }

    .month-list {
        flex: 1;
        overflow-y: auto;
        display: flex;
        flex-direction: column;
        gap: 8px;

        .month-item {
            padding: 12px 16px;
            border-radius: 6px;
            cursor: pointer;
            transition: all 0.3s;
            background-color: #f9fafb;
            border: 1px solid #e5e7eb;
            text-align: center;
            font-size: 14px;
            color: #374151;

            &:hover {
                background-color: #f3f4f6;
                border-color: #d1d5db;
            }

            &.active {
                background-color: #e0f2fe;
                border-color: #1677ff;
                color: #1677ff;
                font-weight: 500;
            }
        }
    }

    .preview-card {
        height: 100%;
        display: flex;
        flex-direction: column;

        :deep(.el-card__body) {
            flex: 1;
            display: flex;
            flex-direction: column;
            overflow: hidden;
            padding: 0;
        }

        .card-header-wrapper {
            display: flex;
            justify-content: space-between;
            align-items: center;
            width: 100%;

            .card-header {
                font-weight: 600;
                font-size: 16px;
                color: #1f2937;
            }
        }

        .docx-preview-container {
            flex: 1;
            position: relative;
            overflow: hidden;
            background-color: #f5f5f5;

            :deep(.vue-office-docx) {
                height: 100%;
                width: 100%;
            }
        }
    }
}
</style>
