<template>
    <div class="tracking-matrix" v-loading="loading">
        <div class="toolbar">
            <el-radio-group v-model="rangeMode" @change="onRangeModeChange">
                <el-radio-button value="7">最近 7 天</el-radio-button>
                <el-radio-button value="30">最近 30 天</el-radio-button>
                <el-radio-button value="custom">自定义</el-radio-button>
            </el-radio-group>

            <el-date-picker
                v-if="rangeMode === 'custom'"
                v-model="customRange"
                type="daterange"
                value-format="YYYY-MM-DD"
                range-separator="至"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
                :clearable="false"
                size="default"
                :disabled-date="disabledFutureDate"
                @change="onCustomRangeChange"
            />

            <span class="hint">
                超阈值红字↑（年龄分段：&lt;50：空7/餐9，≥50：空8/餐10）
            </span>
        </div>

        <el-empty
            v-if="!loading && visibleDates.length === 0"
            description="所选区间内无任何打卡记录"
            :image-size="80"
        />

        <el-table
            v-else
            :data="rows"
            border
            stripe
            class="matrix-table"
            empty-text="暂无数据"
            row-key="date"
            max-height="640"
        >
            <el-table-column prop="dateLabel" label="日期" width="120" fixed="left" />
            <el-table-column label="血糖 (mmol/L)" min-width="180">
                <template #default="{ row }">
                    <div v-if="row.bloodAny" class="cell-blood">
                        <span :class="{ 'cell-high': row.fastingHigh }">
                            空
                            <span class="value">{{ row.fasting ?? '—' }}</span>
                            <span v-if="row.fastingHigh" class="cell-up">↑</span>
                        </span>
                        <span :class="{ 'cell-high': row.postprandialHigh }">
                            餐
                            <span class="value">{{ row.postprandial ?? '—' }}</span>
                            <span v-if="row.postprandialHigh" class="cell-up">↑</span>
                        </span>
                        <span :class="{ 'cell-high': row.otherHigh }">
                            其他
                            <span class="value">{{ row.other ?? '—' }}</span>
                            <span v-if="row.otherHigh" class="cell-up">↑</span>
                        </span>
                    </div>
                    <span v-else class="cell-empty">—</span>
                </template>
            </el-table-column>
            <el-table-column label="血压 (mmHg)" width="120" align="center">
                <template #default="{ row }">
                    <span v-if="row.bp" :class="{ 'cell-high': row.bpHigh }">
                        {{ row.bp }}
                        <span v-if="row.bpHigh" class="cell-up">↑</span>
                    </span>
                    <span v-else class="cell-empty">—</span>
                </template>
            </el-table-column>
            <el-table-column label="西药" min-width="120" show-overflow-tooltip>
                <template #default="{ row }">
                    <span v-if="row.westernMedicine">{{ row.westernMedicine }}</span>
                    <span v-else class="cell-empty">—</span>
                </template>
            </el-table-column>
            <el-table-column label="胰岛素" min-width="120" show-overflow-tooltip>
                <template #default="{ row }">
                    <span v-if="row.insulin">{{ row.insulin }}</span>
                    <span v-else class="cell-empty">—</span>
                </template>
            </el-table-column>
            <el-table-column label="饮食打卡" width="110" align="center">
                <template #default="{ row }">
                    <el-tooltip
                        v-if="row.diet"
                        placement="top"
                        :disabled="!row.diet"
                        effect="light"
                    >
                        <template #content>
                            <div class="diet-tip">
                                <div>早：{{ row.diet.breakfast || '—' }}</div>
                                <div>午：{{ row.diet.lunch || '—' }}</div>
                                <div>晚：{{ row.diet.dinner || '—' }}</div>
                            </div>
                        </template>
                        <span class="cell-checked">已打卡</span>
                    </el-tooltip>
                    <span v-else class="cell-empty">—</span>
                </template>
            </el-table-column>
            <el-table-column label="运动打卡" min-width="160" align="center">
                <template #default="{ row }">
                    <el-tooltip v-if="row.exercise" placement="top" effect="light">
                        <template #content>
                            <div class="exercise-tip">
                                <div>强度：{{ row.exercise.intensityText || '—' }}</div>
                                <div>时长：{{ row.exercise.duration ? row.exercise.duration + ' min' : '—' }}</div>
                                <div v-if="row.exercise.remark">备注：{{ row.exercise.remark }}</div>
                            </div>
                        </template>
                        <span class="cell-checked">
                            已打卡
                            <span v-if="row.exercise.duration" class="meta">· {{ row.exercise.duration }}min</span>
                            <span v-if="row.exercise.intensityText" class="meta">· {{ row.exercise.intensityText }}</span>
                        </span>
                    </el-tooltip>
                    <span v-else class="cell-empty">—</span>
                </template>
            </el-table-column>
        </el-table>
    </div>
</template>

<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue'
import {
    isHighFastingBloodSugar,
    isHighPostprandialBloodSugar,
    isHighOtherBloodSugar,
    isHighBloodPressure,
    formatBp
} from '@/utils/blood-thresholds'
import { diagnosisTrackingWindow } from '@/api/tcm'

interface BloodRecord {
    record_date?: string
    record_date_ts?: number
    fasting_blood_sugar?: any
    postprandial_blood_sugar?: any
    other_blood_sugar?: any
    systolic_pressure?: any
    diastolic_pressure?: any
    western_medicine?: string
    insulin?: string
    [key: string]: any
}

interface DietRecord {
    record_date?: string
    breakfast?: string
    lunch?: string
    dinner?: string
    [key: string]: any
}

interface ExerciseRecord {
    record_date?: string
    duration?: number
    intensity?: number
    intensity_text?: string
    remark?: string
    [key: string]: any
}

interface Props {
    diagnosisId: number
    age?: number | null
}

const props = withDefaults(defineProps<Props>(), {
    age: null
})

type RangeMode = '7' | '30' | 'custom'
const rangeMode = ref<RangeMode>('30')
const customRange = ref<[string, string] | null>(null)

const loading = ref(false)
const bloodRecords = ref<BloodRecord[]>([])
const dietRecords = ref<DietRecord[]>([])
const exerciseRecords = ref<ExerciseRecord[]>([])

let requestSeq = 0

/** 把今天本地时间格式成 Y-m-d，避免 toISOString 的时区漂移 */
const formatDate = (d: Date): string =>
    `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`

const computeRange = (mode: RangeMode): { start: string; end: string } => {
    if (mode === 'custom') {
        const [s, e] = customRange.value || ['', '']
        return { start: s || '', end: e || '' }
    }
    const days = mode === '7' ? 7 : 30
    const end = new Date()
    end.setHours(0, 0, 0, 0)
    const start = new Date(end)
    start.setDate(start.getDate() - (days - 1))
    return { start: formatDate(start), end: formatDate(end) }
}

const disabledFutureDate = (date: Date) => date.getTime() > Date.now()

const fetchTracking = async () => {
    if (!props.diagnosisId || props.diagnosisId <= 0) {
        bloodRecords.value = []
        dietRecords.value = []
        exerciseRecords.value = []
        return
    }
    const range = computeRange(rangeMode.value)
    if (rangeMode.value === 'custom' && (!range.start || !range.end)) {
        // 等待用户选完日期
        return
    }

    const seq = ++requestSeq
    loading.value = true
    try {
        const res: any = await diagnosisTrackingWindow({
            id: props.diagnosisId,
            start_date: range.start,
            end_date: range.end
        })
        if (seq !== requestSeq) return
        bloodRecords.value = res?.blood_records || []
        dietRecords.value = res?.diet_records || []
        exerciseRecords.value = res?.exercise_records || []
    } catch {
        if (seq === requestSeq) {
            bloodRecords.value = []
            dietRecords.value = []
            exerciseRecords.value = []
        }
    } finally {
        if (seq === requestSeq) loading.value = false
    }
}

const onRangeModeChange = () => {
    if (rangeMode.value === 'custom') {
        // 默认填入「最近 30 天」作为初值，让用户在此基础上调整
        if (!customRange.value) {
            const r = computeRange('30')
            customRange.value = [r.start, r.end]
        }
    }
    fetchTracking()
}

const onCustomRangeChange = () => {
    if (rangeMode.value === 'custom') fetchTracking()
}

watch(
    () => props.diagnosisId,
    (id) => {
        if (id && id > 0) fetchTracking()
    }
)

onMounted(() => {
    if (props.diagnosisId && props.diagnosisId > 0) fetchTracking()
})

/**
 * 把同一天可能多条的血糖记录聚合：每段取第一条非空值（与 BloodRecordLogic 趋势图一致）
 */
const bloodByDate = computed(() => {
    const map = new Map<string, BloodRecord>()
    for (const r of bloodRecords.value) {
        const d = String(r.record_date || '')
        if (!d) continue
        if (!map.has(d)) {
            map.set(d, {
                record_date: d,
                record_date_ts: r.record_date_ts
            })
        }
        const acc = map.get(d)!
        const fields: Array<keyof BloodRecord> = [
            'fasting_blood_sugar',
            'postprandial_blood_sugar',
            'other_blood_sugar',
            'systolic_pressure',
            'diastolic_pressure',
            'western_medicine',
            'insulin'
        ]
        for (const f of fields) {
            if (
                (acc[f] === undefined || acc[f] === null || acc[f] === '') &&
                r[f] !== undefined &&
                r[f] !== null &&
                r[f] !== ''
            ) {
                ;(acc as any)[f] = r[f]
            }
        }
    }
    return map
})

const dietByDate = computed(() => {
    const map = new Map<string, DietRecord>()
    for (const r of dietRecords.value) {
        const d = String(r.record_date || '')
        if (!d) continue
        if (!map.has(d)) map.set(d, r)
    }
    return map
})

const exerciseByDate = computed(() => {
    const map = new Map<string, ExerciseRecord>()
    for (const r of exerciseRecords.value) {
        const d = String(r.record_date || '')
        if (!d) continue
        if (!map.has(d)) map.set(d, r)
    }
    return map
})

/**
 * 已经由后端按区间过滤，前端只需取三类记录的日期并集 + desc 排序
 */
const visibleDates = computed<string[]>(() => {
    const set = new Set<string>()
    for (const r of bloodRecords.value) if (r.record_date) set.add(String(r.record_date))
    for (const r of dietRecords.value) if (r.record_date) set.add(String(r.record_date))
    for (const r of exerciseRecords.value) if (r.record_date) set.add(String(r.record_date))
    const list = Array.from(set).filter((d) => d.length === 10)
    list.sort((a, b) => (a < b ? 1 : a > b ? -1 : 0))
    return list
})


const rows = computed(() =>
    visibleDates.value.map((date) => {
        const blood = bloodByDate.value.get(date)
        const diet = dietByDate.value.get(date)
        const exercise = exerciseByDate.value.get(date)

        const fasting = blood?.fasting_blood_sugar ?? null
        const postprandial = blood?.postprandial_blood_sugar ?? null
        const other = blood?.other_blood_sugar ?? null
        const sys = blood?.systolic_pressure ?? null
        const dia = blood?.diastolic_pressure ?? null

        const bloodAny =
            (fasting !== null && fasting !== '') ||
            (postprandial !== null && postprandial !== '') ||
            (other !== null && other !== '')

        const bp = sys || dia ? formatBp({ systolic_pressure: sys, diastolic_pressure: dia }) : ''

        return {
            date,
            dateLabel: `${date}`,
            // 血糖
            bloodAny,
            fasting: fasting ?? '—',
            postprandial: postprandial ?? '—',
            other: other ?? '—',
            fastingHigh: isHighFastingBloodSugar(fasting, props.age),
            postprandialHigh: isHighPostprandialBloodSugar(postprandial, props.age),
            otherHigh: isHighOtherBloodSugar(other, props.age),
            // 血压
            bp,
            bpHigh: isHighBloodPressure({ systolic_pressure: sys, diastolic_pressure: dia }),
            // 用药
            westernMedicine: blood?.western_medicine || '',
            insulin: blood?.insulin || '',
            // 饮食
            diet: diet
                ? {
                      breakfast: diet.breakfast || '',
                      lunch: diet.lunch || '',
                      dinner: diet.dinner || ''
                  }
                : null,
            // 运动
            exercise: exercise
                ? {
                      duration: exercise.duration || 0,
                      intensityText: exercise.intensity_text || '',
                      remark: exercise.remark || ''
                  }
                : null
        }
    })
)

defineExpose({ refresh: fetchTracking })
</script>

<style lang="scss" scoped>
.tracking-matrix {
    .toolbar {
        display: flex;
        align-items: center;
        gap: 12px;
        margin-bottom: 12px;
        flex-wrap: wrap;

        .hint {
            font-size: 12px;
            color: var(--el-text-color-secondary);
        }
    }

    .matrix-table {
        width: 100%;
    }

    .cell-blood {
        display: flex;
        flex-direction: column;
        gap: 2px;
        font-size: 12.5px;
        line-height: 1.55;

        > span {
            display: inline-flex;
            align-items: center;
            gap: 4px;

            .value {
                font-variant-numeric: tabular-nums;
                font-weight: 600;
            }
        }
    }

    .cell-high {
        color: #dc2626;
        font-weight: 700;
    }

    .cell-up {
        font-size: 13px;
        color: #dc2626;
    }

    .cell-empty {
        color: var(--el-text-color-placeholder);
    }

    .cell-checked {
        color: #2563eb;
        font-weight: 500;

        .meta {
            color: var(--el-text-color-secondary);
            font-weight: 400;
            margin-left: 2px;
        }
    }
}

.diet-tip,
.exercise-tip {
    font-size: 12.5px;
    line-height: 1.55;

    > div {
        margin-bottom: 2px;

        &:last-child {
            margin-bottom: 0;
        }
    }
}
</style>
