<template>
	<view class="page">
		<view class="status-bar" :style="{ height: statusBarHeight + 'px' }"></view>

		<view class="container">
			<view v-if="pageLoading" class="skeleton">
				<view class="skeleton-card"></view>
				<view class="skeleton-card"></view>
				<view class="skeleton-list">
					<view v-for="i in 3" :key="i" class="skeleton-row"></view>
				</view>
			</view>

			<view v-else>
				<view class="stage-card">
					<view class="stage-badge">第 {{ stageDay }}/30 天</view>
					<text class="stage-label">当前减量计划阶段</text>
					<text class="stage-name">阶段 {{ stage }} · {{ stageName }}</text>
					<text class="stage-days">本阶段还剩 {{ daysLeft }} 天</text>
					<view class="stage-progress-row">
						<text class="stage-progress-label">阶段进度</text>
						<text class="stage-progress-value">{{ Math.round(stageProgress * 100) }}%</text>
					</view>
					<view class="stage-progress-bar">
						<view class="stage-progress-fill" :style="{ width: stageProgress * 100 + '%' }"></view>
					</view>
				</view>

				<view class="section">
					<view class="section-header">
						<view class="section-title-row">
							<text class="section-icon">🤖</text>
							<text class="section-title">每日 AI 分析</text>
						</view>
						<text class="refresh-btn" @tap="refreshAiAdvice">刷新</text>
					</view>

					<view v-if="aiLoading" class="ai-loading-card">
						<text class="ai-loading-text">正在生成今日分析...</text>
					</view>

					<view v-else-if="aiStatus === 'available'" class="ai-chat">
						<view class="ai-avatar">🤖</view>
						<view class="ai-chat-content">
							<view class="ai-chat-header">
								<text class="ai-chat-name">AI 教练</text>
								<text class="ai-chat-time">建议日期 {{ aiAdviceDateText }}</text>
							</view>
							<view class="ai-chat-bubble">
								<text class="ai-chat-text">{{ aiAdvice }}</text>
							</view>
						</view>
					</view>

					<view v-else class="ai-empty-card">
						<text class="ai-empty-title">{{ aiStateTitle }}</text>
						<text class="ai-empty-desc">{{ aiStateDesc }}</text>
						<view v-if="aiStatus === 'locked'" class="ai-empty-btn" @tap="goRecord">
							<text class="ai-empty-btn-text">去首页查看解锁入口</text>
						</view>
					</view>
				</view>

				<view class="section">
					<view class="section-header">
						<text class="section-title">今日目标</text>
						<text class="section-badge">已完成 {{ completedGoals }}/{{ goals.length }}</text>
					</view>

					<view v-if="goals.length > 0" class="goals-list">
						<view
							v-for="goal in goals"
							:key="goal.id"
							class="goal-item"
							@tap="toggleGoal(goal)"
						>
							<view class="goal-check" :class="{ 'goal-check-done': goal.done }">
								<text v-if="goal.done" class="goal-check-icon">✓</text>
							</view>
							<text class="goal-text" :class="{ 'goal-text-done': goal.done }">{{ goal.text }}</text>
							<text v-if="goal.icon" class="goal-icon">{{ goal.icon }}</text>
						</view>
					</view>

					<view v-else class="goal-empty">
						<text class="goal-empty-text">暂未生成目标，点击刷新重试</text>
					</view>
				</view>
			</view>
		</view>

		<view class="record-btn" @tap="goRecord">
			<text class="record-icon">➕</text>
			<text>记录吸烟或烟瘾</text>
		</view>
	</view>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { onShareAppMessage } from '@dcloudio/uni-app'
import { useLogin } from '@/hooks/useLogin'
import { useProfileStore } from '@/stores/profile'
import { storage } from '@/utils/storage'
import * as api from '@/api'

const { waitForLogin } = useLogin()
const profileStore = useProfileStore()

const GOALS_STORAGE_KEY = 'ai_daily_goals_v1'

const statusBarHeight = ref(0)
const pageLoading = ref(true)
const aiLoading = ref(false)

const stageDay = ref(1)
const stage = ref(1)
const stageName = ref('记录期')
const daysLeft = ref(6)
const stageProgress = ref(0)

const aiAdvice = ref('')
const aiStatus = ref('empty')
const aiAdviceDateText = ref('--')
const dailyTarget = ref(0)

const goals = ref([])

const completedGoals = computed(() => {
	return goals.value.filter(g => g.done).length
})

const aiStateTitle = computed(() => {
	if (aiStatus.value === 'locked') return '今日 AI 建议未解锁'
	if (aiStatus.value === 'no_data') return '暂无可分析数据'
	if (aiStatus.value === 'unavailable') return 'AI 服务暂不可用'
	return '暂无 AI 建议'
})

const aiStateDesc = computed(() => {
	if (aiStatus.value === 'locked') return '可前往首页按照引导完成解锁后查看。'
	if (aiStatus.value === 'no_data') return '先完成记录，系统会在次日生成更准确建议。'
	if (aiStatus.value === 'unavailable') return '稍后重试，当前将继续使用基础戒烟计划。'
	return '请点击刷新，或先记录行为数据。'
})

function goRecord() {
	uni.switchTab({ url: '/pages/index/index' })
}

function localDateStr(date = new Date()) {
	const y = date.getFullYear()
	const m = String(date.getMonth() + 1).padStart(2, '0')
	const d = String(date.getDate()).padStart(2, '0')
	return `${y}-${m}-${d}`
}

function getDateBefore(days) {
	const date = new Date()
	date.setDate(date.getDate() - days)
	return localDateStr(date)
}

function calculateStage(profile) {
	const startAt = profile?.onboarding_completed_at || profile?.created_at
	if (!startAt) {
		stageDay.value = 1
		stage.value = 1
		stageName.value = '记录期'
		daysLeft.value = 6
		stageProgress.value = 1 / 7
		return
	}

	const start = new Date(startAt)
	if (isNaN(start.getTime())) {
		stageDay.value = 1
		stage.value = 1
		stageName.value = '记录期'
		daysLeft.value = 6
		stageProgress.value = 1 / 7
		return
	}

	const now = new Date()
	const startDayMs = new Date(start.getFullYear(), start.getMonth(), start.getDate()).getTime()
	const nowDayMs = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime()
	const dayIndex = Math.max(1, Math.floor((nowDayMs - startDayMs) / (24 * 60 * 60 * 1000)) + 1)
	const planDay = Math.min(dayIndex, 30)

	stageDay.value = planDay

	// 使用阶段内进度，便于用户感知当前阶段完成度
	if (planDay <= 7) {
		stage.value = 1
		stageName.value = '记录期'
		daysLeft.value = 7 - planDay
		stageProgress.value = planDay / 7
		return
	}

	if (planDay <= 21) {
		stage.value = 2
		stageName.value = '减量期'
		daysLeft.value = 21 - planDay
		stageProgress.value = (planDay - 7) / 14
		return
	}

	stage.value = 3
	stageName.value = '巩固期'
	daysLeft.value = Math.max(30 - planDay, 0)
	stageProgress.value = Math.min((planDay - 21) / 9, 1)
}

function makeGoalTemplates(profile, adviceText) {
	const templates = []
	const target = Number(dailyTarget.value) || Number(profile?.baseline_cigs_per_day) || 0

	if (target > 0) {
		templates.push({
			id: 'limit_target',
			text: `今日吸烟控制在 ${target} 支以内`,
			icon: '🎯'
		})
	}

	const quitMotions = Array.isArray(profile?.quit_motivations) ? profile.quit_motivations : []
	if (quitMotions.includes('身体健康')) {
		templates.push({
			id: 'health_walk',
			text: '完成 10 分钟快走，分散烟瘾注意力',
			icon: '🏃'
		})
	}

	if (quitMotions.includes('省钱')) {
		templates.push({
			id: 'money_track',
			text: '记录今天少抽的支数，观察省钱变化',
			icon: '💰'
		})
	}

	if (adviceText && adviceText.includes('散步')) {
		templates.push({
			id: 'advice_walk',
			text: '按 AI 建议在高峰时段先散步 5 分钟',
			icon: '🌿'
		})
	}

	templates.push({
		id: 'delay_urge',
		text: '烟瘾发作时先延迟 10 分钟并喝一杯水',
		icon: '⏳'
	})

	// 去重后最多展示 3 条，保证信息密度适中
	const uniqueMap = new Map()
	templates.forEach(item => {
		if (!uniqueMap.has(item.id)) {
			uniqueMap.set(item.id, item)
		}
	})

	return Array.from(uniqueMap.values()).slice(0, 3)
}

function loadGoalsByDate(dateStr, templates) {
	const allGoals = storage.get(GOALS_STORAGE_KEY, {})
	const cached = Array.isArray(allGoals?.[dateStr]) ? allGoals[dateStr] : []
	const doneMap = new Map(cached.map(item => [item.id, !!item.done]))

	goals.value = templates.map(item => ({
		...item,
		done: doneMap.get(item.id) || false
	}))
}

function persistGoals() {
	const dateStr = localDateStr()
	const allGoals = storage.get(GOALS_STORAGE_KEY, {})

	allGoals[dateStr] = goals.value.map(item => ({
		id: item.id,
		text: item.text,
		icon: item.icon,
		done: !!item.done
	}))

	// 仅保留最近 14 天的目标完成状态，避免本地缓存无限增长
	const keepDays = 14
	const keys = Object.keys(allGoals).sort()
	if (keys.length > keepDays) {
		const removeKeys = keys.slice(0, keys.length - keepDays)
		removeKeys.forEach(key => {
			delete allGoals[key]
		})
	}

	storage.set(GOALS_STORAGE_KEY, allGoals)
}

function toggleGoal(goal) {
	goal.done = !goal.done
	persistGoals()
}

function applyHomeData(home) {
	const data = home?.data || {}
	const summary = data.summary || {}
	const adviceCard = data.advice_card || {}

	if (summary.daily_target !== undefined && summary.daily_target !== null) {
		dailyTarget.value = Number(summary.daily_target) || 0
	}

	if (adviceCard?.message && !aiAdvice.value) {
		aiAdvice.value = adviceCard.message
		aiStatus.value = 'available'
	}

	if (!aiAdvice.value && adviceCard?.status) {
		const map = {
			locked: 'locked',
			no_data: 'no_data',
			unavailable: 'unavailable',
			empty: 'empty'
		}
		aiStatus.value = map[adviceCard.status] || 'empty'
	}
}

async function fetchAiAdvice() {
	aiLoading.value = true
	const adviceDate = getDateBefore(1)
	aiAdviceDateText.value = adviceDate

	try {
		const res = await api.getAiAdvice(adviceDate)
		const data = res?.data || {}
		const message = data.advice || data.message || ''

		if (message) {
			aiAdvice.value = message
			aiStatus.value = 'available'
		} else {
			aiAdvice.value = ''
			aiStatus.value = 'no_data'
		}

		if (data.date) {
			aiAdviceDateText.value = data.date
		}
	} catch (e) {
		const errMsg = e?.message || ''
		aiAdvice.value = ''

		// 与后端约定：未解锁时返回 403，对应文案包含“会员/广告/解锁”等关键词
		if (errMsg.includes('会员') || errMsg.includes('广告') || errMsg.includes('解锁')) {
			aiStatus.value = 'locked'
		} else {
			aiStatus.value = 'unavailable'
		}
	} finally {
		aiLoading.value = false
	}
}

async function refreshAiAdvice() {
	await fetchAiAdvice()
	const profile = profileStore.profile || {}
	const templates = makeGoalTemplates(profile, aiAdvice.value)
	loadGoalsByDate(localDateStr(), templates)
}

async function initPage() {
	pageLoading.value = true
	try {
		const sys = uni.getSystemInfoSync()
		statusBarHeight.value = sys.statusBarHeight || 0

		await waitForLogin()
		const [profileRes, homeRes] = await Promise.allSettled([
			profileStore.fetchProfile(),
			api.getHome()
		])

		if (profileRes.status === 'fulfilled') {
			calculateStage(profileStore.profile || {})
		}

		if (homeRes.status === 'fulfilled') {
			applyHomeData(homeRes.value)
		}

		await fetchAiAdvice()

		const profile = profileStore.profile || {}
		const templates = makeGoalTemplates(profile, aiAdvice.value)
		loadGoalsByDate(localDateStr(), templates)
	} catch (e) {
		console.error('initPage error:', e)
		aiStatus.value = 'unavailable'
	} finally {
		pageLoading.value = false
	}
}

onMounted(() => {
	initPage()
})

onShareAppMessage(() => {
	return {
		title: '戒烟助手 - AI 戒烟教练陪你',
		path: 'pages/index/index'
	}
})
</script>

<style scoped>
.page {
	min-height: 100vh;
	background: linear-gradient(to bottom, #D1FAE5 0%, #F0FDF4 45%, #FFFFFF 100%);
	box-sizing: border-box;
}

.status-bar {
	background: linear-gradient(to bottom, #D1FAE5, #E9FDF2);
}

.container {
	padding: 24rpx 32rpx 180rpx;
}

.skeleton {
	display: flex;
	flex-direction: column;
	gap: 24rpx;
}

.skeleton-card,
.skeleton-row {
	background: linear-gradient(90deg, #E5E7EB 25%, #F3F4F6 50%, #E5E7EB 75%);
	background-size: 200% 100%;
	animation: shimmer 1.6s infinite;
}

.skeleton-card {
	height: 260rpx;
	border-radius: 24rpx;
}

.skeleton-list {
	padding: 24rpx;
	background-color: #FFFFFF;
	border-radius: 24rpx;
}

.skeleton-row {
	height: 92rpx;
	border-radius: 18rpx;
	margin-bottom: 16rpx;
}

.skeleton-row:last-child {
	margin-bottom: 0;
}

@keyframes shimmer {
	0% { background-position: -200% 0; }
	100% { background-position: 200% 0; }
}

.stage-card {
	background: #FFFFFF;
	border-radius: 28rpx;
	padding: 32rpx;
	margin-bottom: 32rpx;
	position: relative;
	box-shadow: 0 10rpx 28rpx rgba(16, 185, 129, 0.12);
	border: 2rpx solid #ECFDF3;
}

.stage-badge {
	position: absolute;
	top: 24rpx;
	right: 24rpx;
	background-color: #10B981;
	color: #FFFFFF;
	padding: 8rpx 20rpx;
	border-radius: 20rpx;
	font-size: 24rpx;
	font-weight: 600;
}

.stage-label {
	font-size: 24rpx;
	color: #059669;
	display: block;
	margin-bottom: 8rpx;
}

.stage-name {
	font-size: 42rpx;
	font-weight: 700;
	color: #111827;
	display: block;
	margin-bottom: 8rpx;
}

.stage-days {
	font-size: 24rpx;
	color: #6B7280;
	display: block;
	margin-bottom: 24rpx;
}

.stage-progress-row {
	display: flex;
	justify-content: space-between;
	margin-bottom: 12rpx;
}

.stage-progress-label {
	font-size: 24rpx;
	color: #6B7280;
}

.stage-progress-value {
	font-size: 24rpx;
	font-weight: 600;
	color: #10B981;
}

.stage-progress-bar {
	height: 12rpx;
	background-color: #E5E7EB;
	border-radius: 6rpx;
	overflow: hidden;
}

.stage-progress-fill {
	height: 100%;
	background: linear-gradient(90deg, #10B981, #34D399);
	border-radius: 6rpx;
}

.section {
	margin-bottom: 32rpx;
}

.section-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-bottom: 16rpx;
}

.section-title-row {
	display: flex;
	align-items: center;
	gap: 12rpx;
}

.section-icon {
	font-size: 30rpx;
}

.section-title {
	font-size: 30rpx;
	font-weight: 600;
	color: #111827;
}

.refresh-btn {
	font-size: 24rpx;
	color: #10B981;
	background-color: #ECFDF3;
	padding: 8rpx 18rpx;
	border-radius: 16rpx;
}

.section-badge {
	margin-left: auto;
	font-size: 24rpx;
	color: #059669;
	background-color: #ECFDF3;
	padding: 8rpx 16rpx;
	border-radius: 16rpx;
}

.ai-loading-card,
.ai-empty-card,
.ai-chat {
	background-color: #FFFFFF;
	border-radius: 24rpx;
	padding: 28rpx;
	display: flex;
	border: 2rpx solid #ECFDF3;
	box-shadow: 0 8rpx 22rpx rgba(16, 185, 129, 0.08);
}

.ai-loading-card {
	justify-content: center;
}

.ai-loading-text {
	color: #6B7280;
	font-size: 26rpx;
}

.ai-empty-card {
	flex-direction: column;
	gap: 16rpx;
}

.ai-empty-title {
	font-size: 30rpx;
	font-weight: 600;
	color: #111827;
}

.ai-empty-desc {
	font-size: 25rpx;
	color: #6B7280;
	line-height: 1.6;
}

.ai-empty-btn {
	align-self: flex-start;
	background-color: #10B981;
	padding: 14rpx 24rpx;
	border-radius: 16rpx;
}

.ai-empty-btn-text {
	font-size: 24rpx;
	color: #FFFFFF;
}

.ai-chat {
	gap: 20rpx;
}

.ai-avatar {
	width: 64rpx;
	height: 64rpx;
	background-color: #ECFDF3;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 30rpx;
	flex-shrink: 0;
}

.ai-chat-content {
	flex: 1;
}

.ai-chat-header {
	display: flex;
	align-items: center;
	gap: 8rpx;
	margin-bottom: 16rpx;
}

.ai-chat-name {
	font-weight: 600;
	color: #059669;
}

.ai-chat-time {
	font-size: 24rpx;
	color: #9CA3AF;
}

.ai-chat-bubble {
	background-color: #F9FAFB;
	padding: 24rpx;
	border-radius: 24rpx;
	border-top-left-radius: 8rpx;
	border: 2rpx solid #F3F4F6;
}

.ai-chat-text {
	font-size: 28rpx;
	line-height: 1.6;
	color: #111827;
	white-space: pre-wrap;
}

.goals-list {
	display: flex;
	flex-direction: column;
	gap: 16rpx;
}

.goal-item {
	display: flex;
	align-items: center;
	gap: 20rpx;
	background-color: #FFFFFF;
	border-radius: 24rpx;
	padding: 28rpx;
	border: 2rpx solid #ECFDF3;
	box-shadow: 0 6rpx 16rpx rgba(16, 185, 129, 0.08);
}

.goal-check {
	width: 48rpx;
	height: 48rpx;
	border-radius: 50%;
	border: 4rpx solid #D1D5DB;
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
}

.goal-check-done {
	background-color: #10B981;
	border-color: #10B981;
}

.goal-check-icon {
	font-size: 28rpx;
	color: #FFFFFF;
	font-weight: 700;
}

.goal-text {
	flex: 1;
	font-size: 28rpx;
	color: #111827;
}

.goal-text-done {
	text-decoration: line-through;
	color: #6B7280;
}

.goal-icon {
	font-size: 32rpx;
}

.goal-empty {
	background-color: #FFFFFF;
	border-radius: 24rpx;
	border: 2rpx dashed #D1D5DB;
	padding: 32rpx;
}

.goal-empty-text {
	font-size: 26rpx;
	color: #6B7280;
}

.record-btn {
	position: fixed;
	bottom: 140rpx;
	left: 32rpx;
	right: 32rpx;
	height: 96rpx;
	background-color: #10B981;
	border-radius: 48rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 12rpx;
	font-size: 32rpx;
	font-weight: 500;
	color: #FFFFFF;
	box-shadow: 0 12rpx 28rpx rgba(16, 185, 129, 0.25);
}

.record-icon {
	font-size: 32rpx;
}
</style>
