<template>
	<view class="page" :class="{ big: isH5 }">
		<view class="panel">
			<view class="title">报告详情</view>
			<view class="subtitle">{{ metaTitle }}</view>
		</view>

		<view v-if="loading" class="placeholder">加载中...</view>
		<view v-else>
			<view v-if="errorMsg" class="panel">
				<view class="error">{{ errorMsg }}</view>
			</view>

			<view v-else class="panel">
				<view class="kv">
					<view class="kv-item"><text class="k">来源</text><text class="v">{{ sourceTypeLabel }}</text></view>
					<view class="kv-item"><text class="k">报告ID</text><text class="v">{{ reportId || '—' }}</text></view>
					<view class="kv-item"><text class="k">生成时间</text><text class="v">{{ formatTime(report.generateTime) }}</text></view>
				</view>

				<view class="section-title">内容</view>
				<view class="content">
					<rich-text :nodes="htmlNodes"></rich-text>
					<view v-if="htmlFallback" class="hint">内容不是标准HTML，已自动按文本格式展示。</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	import { getReport } from '../../api/psychology/report'

	function escapeHtml(str) {
		return String(str)
			.replace(/&/g, '&amp;')
			.replace(/</g, '&lt;')
			.replace(/>/g, '&gt;')
			.replace(/"/g, '&quot;')
			.replace(/'/g, '&#39;')
	}

	function normalizeHtml(raw) {
		let html = raw == null ? '' : String(raw)
		const hasHtmlDoc = /<\s*html[\s\S]*?>/i.test(html)
		if (hasHtmlDoc) {
			const bodyMatch = html.match(/<\s*body[\s\S]*?>([\s\S]*?)<\s*\/\s*body\s*>/i)
			if (bodyMatch && bodyMatch[1] != null) {
				html = bodyMatch[1]
			}
		}

		// Some miniapp rich-text runtimes ignore <style> tags; inject critical styles inline.
		const applyInlineHeadingStyle = (input) => {
			let out = input
			const rules = {
				1: 'font-size:22px;margin:14px 0 10px;line-height:1.55;font-weight:800;',
				2: 'font-size:18px;margin:14px 0 10px;line-height:1.6;font-weight:800;',
				3: 'font-size:16px;margin:12px 0 8px;line-height:1.65;font-weight:800;',
				4: 'font-size:15px;margin:10px 0 8px;line-height:1.7;font-weight:800;'
			}
			out = out.replace(/<h([1-4])([^>]*)>/gi, (m, level, attrs) => {
				const base = 'display:block;white-space:normal;word-break:break-word;overflow-wrap:anywhere;'
				const styleRule = (rules[level] || '') + base
				const a = attrs || ''
				if (/\sstyle\s*=\s*['"][^'"]*['"]/i.test(a)) {
					return `<h${level}${a.replace(/\sstyle\s*=\s*(['"])([^'"]*)\1/i, (sm, q, s) => ` style=${q}${s};${styleRule}${q}`)}>`
				}
				return `<h${level}${a} style="${styleRule}">`
			})
			return out
		}

		const baseCss = `
			.report-wrap{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,'PingFang SC','Hiragino Sans GB','Microsoft YaHei',sans-serif;line-height:1.75;color:#111827;word-break:break-word;font-size:15px;}
			.report-wrap h1,.report-wrap h2,.report-wrap h3,.report-wrap h4{display:block;white-space:normal;word-break:break-word;overflow-wrap:anywhere;}
			.report-wrap h1{font-size:22px;margin:14px 0 10px;line-height:1.45;font-weight:800;}
			.report-wrap h2{font-size:18px;margin:14px 0 10px;line-height:1.5;font-weight:800;}
			.report-wrap h3{font-size:16px;margin:12px 0 8px;line-height:1.55;font-weight:800;}
			.report-wrap h4{font-size:15px;margin:10px 0 8px;line-height:1.6;font-weight:800;}
			.report-wrap p{margin:10px 0;}
			.report-wrap ul,.report-wrap ol{padding-left:20px;margin:10px 0;}
			.report-wrap li{margin:6px 0;}
			.report-wrap img{max-width:100%;height:auto;border-radius:10px;}
			.report-wrap hr{border:0;border-top:1px solid rgba(15,23,42,0.08);margin:14px 0;}
			.report-wrap blockquote{margin:12px 0;padding:10px 12px;border-left:4px solid rgba(22,119,255,0.5);background:rgba(22,119,255,0.06);border-radius:10px;}
			.report-wrap pre{white-space:pre-wrap;word-break:break-word;background:rgba(15,23,42,0.04);padding:12px;border-radius:10px;}
			.report-wrap table{width:100%;border-collapse:collapse;}
			.report-wrap .table-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;border-radius:12px;border:1px solid rgba(15,23,42,0.06);}
			.report-wrap .table-scroll table{min-width:520px;}
			.report-wrap th,.report-wrap td{border:1px solid rgba(15,23,42,0.08);padding:10px;vertical-align:top;word-break:break-word;}
			.report-wrap th{background:rgba(15,23,42,0.04);font-weight:800;}
		`;

		// wrap tables for horizontal scrolling on mobile
		html = html.replace(/<table([\s\S]*?)>([\s\S]*?)<\/table>/gi, (m) => {
			return `<div class="table-scroll">${m}</div>`
		})

		html = applyInlineHeadingStyle(html)

		return `<div class="report-wrap"><style>${baseCss}</style>${html}</div>`
	}

	export default {
		data() {
			return {
				isH5: false,
				loading: false,
				errorMsg: '',
				reportId: '',
				sourceType: '',
				report: {},
				htmlNodes: '',
				htmlFallback: false
			}
		},
		computed: {
			metaTitle() {
				return (this.report && (this.report.reportTitle || this.report.reportType))
					? `${this.report.reportTitle || ''}${this.report.reportType ? ' · ' + this.report.reportType : ''}`
					: '—'
			},
			sourceTypeLabel() {
				if (this.sourceType === 'questionnaire') return '问卷'
				if (this.sourceType === 'assessment') return '测评'
				return this.sourceType || '—'
			}
		},
		onLoad(options) {
			try {
				const info = uni.getSystemInfoSync()
				const p = info ? (info.uniPlatform || info.platform) : ''
				this.isH5 = p === 'web' || p === 'h5'
			} catch (e) {
				this.isH5 = false
			}
			this.reportId = options && options.reportId ? options.reportId : ''
			this.sourceType = options && options.sourceType ? options.sourceType : ''
			if (!this.reportId) {
				this.errorMsg = '缺少 reportId'
				return
			}
			this.fetchDetail()
		},
		methods: {
			formatTime(val) {
				if (!val) return '—'
				try {
					const d = new Date(val)
					if (isNaN(d.getTime())) return '—'
					const y = d.getFullYear()
					const m = String(d.getMonth() + 1).padStart(2, '0')
					const day = String(d.getDate()).padStart(2, '0')
					const hh = String(d.getHours()).padStart(2, '0')
					const mm = String(d.getMinutes()).padStart(2, '0')
					return `${y}-${m}-${day} ${hh}:${mm}`
				} catch (e) {
					return '—'
				}
			},
			buildRender(content) {
				const raw = content == null ? '' : String(content)

				// HTML：如果像HTML就直接渲染；否则用 <pre> 包一层，避免 rich-text 解析异常
				const looksLikeHtml = /<\s*\w+[\s\S]*>/.test(raw)
				if (looksLikeHtml) {
					this.htmlNodes = normalizeHtml(raw)
					this.htmlFallback = false
					return
				}
				this.htmlNodes = normalizeHtml(`<pre>${escapeHtml(raw)}</pre>`)
				this.htmlFallback = true
			},
			fetchDetail() {
				this.loading = true
				this.errorMsg = ''
				const tryTypes = this.sourceType ? [this.sourceType] : ['', 'assessment', 'questionnaire']
				const tryFetch = (idx) => {
					if (idx >= tryTypes.length) {
						this.loading = false
						if (!this.errorMsg) this.errorMsg = '加载失败'
						return Promise.resolve()
					}
					const st = tryTypes[idx]
					return getReport(this.reportId, st)
						.then((res) => {
							const data = res && res.data ? res.data : null
							if (!data || data.code !== 200) {
								this.errorMsg = (data && data.msg) ? data.msg : '加载失败'
								return tryFetch(idx + 1)
							}
							const report = data.data || {}
							const content = report && report.reportContent != null ? String(report.reportContent) : ''
							if (!content && idx + 1 < tryTypes.length) {
								this.errorMsg = ''
								return tryFetch(idx + 1)
							}
							this.loading = false
							this.report = report
							this.sourceType = st || (report.sourceType || this.sourceType)
							this.buildRender(this.report.reportContent)
						})
						.catch((e) => {
							this.errorMsg = e && e.message ? e.message : '网络错误'
							return tryFetch(idx + 1)
						})
				}
				return tryFetch(0)
			}
		}
	}
</script>

<style>
	.page { min-height: 100vh; padding: 32rpx; box-sizing: border-box; background: #f6f7fb; }
	.page.big {
		padding: 14rpx 14rpx 120rpx;
		background-image:
			radial-gradient(1100rpx 520rpx at 50% 14%, rgba(43, 107, 255, 0.30) 0%, rgba(6, 16, 40, 0.0) 65%),
			linear-gradient(180deg, rgba(5, 11, 24, 0.90) 0%, rgba(8, 20, 45, 0.85) 42%, rgba(6, 16, 40, 0.92) 100%),
			url('/static/bg.png');
		background-size: auto, auto, cover;
		background-position: center, center, center;
		background-repeat: no-repeat, no-repeat, no-repeat;
	}
	.panel { background: #fff; border-radius: 20rpx; padding: 24rpx; border: 1px solid rgba(0,0,0,0.05); margin-bottom: 24rpx; }
	.title { font-size: 36rpx; font-weight: 700; color: #1f2329; }
	.subtitle { margin-top: 10rpx; font-size: 24rpx; color: #646a73; line-height: 36rpx; }
	.section-title { margin-top: 18rpx; font-size: 28rpx; font-weight: 700; color: #1f2329; }
	.kv-item { display: flex; justify-content: space-between; padding: 12rpx 0; border-bottom: 1px solid rgba(0,0,0,0.06); }
	.kv-item:last-child { border-bottom: 0; }
	.k { color: #8f959e; font-size: 24rpx; }
	.v { color: #1f2329; font-size: 24rpx; font-weight: 700; }
	.mode-switch { display: flex; margin-top: 14rpx; }
	.chip { padding: 10rpx 18rpx; border-radius: 999rpx; font-size: 24rpx; color: #646a73; background: #f7f8fa; margin-right: 14rpx; }
	.chip.active { color: #1677ff; background: rgba(22,119,255,0.12); }
	.content { margin-top: 14rpx; font-size: 26rpx; color: #1f2329; line-height: 44rpx; }
	.placeholder { height: 240rpx; border-radius: 20rpx; background: #fff; border: 1px dashed rgba(0,0,0,0.15); display: flex; align-items: center; justify-content: center; color: #8f959e; font-size: 24rpx; }
	.error { font-size: 24rpx; color: #ff4d4f; line-height: 36rpx; }
	.hint { margin-top: 10rpx; font-size: 22rpx; color: #8f959e; }
	.page.big .panel,
	.page.big .placeholder {
		border: 1px solid rgba(116, 216, 255, 0.22);
		background: linear-gradient(180deg, rgba(10, 18, 38, 0.75) 0%, rgba(5, 10, 22, 0.55) 100%);
		box-shadow: 0 12rpx 24rpx rgba(0, 0, 0, 0.35);
	}
	.page.big .title,
	.page.big .section-title,
	.page.big .v { color: rgba(235, 248, 255, 0.92); }
	.page.big .subtitle,
	.page.big .k,
	.page.big .hint,
	.page.big .placeholder { color: rgba(201, 242, 255, 0.65); }
	.page.big .placeholder { border-style: solid; }
	.page.big .kv-item { border-bottom-color: rgba(116, 216, 255, 0.12); }
	.page.big .chip { color: rgba(201, 242, 255, 0.70); background: rgba(10, 18, 38, 0.65); border: 1px solid rgba(116, 216, 255, 0.20); }
	.page.big .chip.active { color: #0b1226; background: linear-gradient(90deg, rgba(116, 216, 255, 0.95) 0%, rgba(43, 107, 255, 0.90) 100%); border-color: rgba(116, 216, 255, 0.5); }
	.page.big .content { color: rgba(235, 248, 255, 0.88); }
</style>
