<template>
	<view class="page">
		<view class="nav-placeholder" :style="{ height: navBarHeight + 'px' }"></view>

		<view v-if="loading" class="skeleton">
			<view class="skeleton-card skeleton-card-lg"></view>
			<view class="skeleton-card skeleton-card-md"></view>
			<view class="skeleton-grid">
				<view class="skeleton-card"></view>
				<view class="skeleton-card"></view>
			</view>
			<view class="skeleton-card skeleton-card-sm"></view>
		</view>

		<view v-else class="dashboard">
			<view class="header-card">
				<view class="user-info">
					<image class="avatar" :src="userAvatar" mode="aspectFill"></image>
					<view class="greeting">
						<text class="greeting-text">{{ greetingTitle }}</text>
						<text class="greeting-sub">{{ greetingSubtitle }}</text>
					</view>
				</view>
				<view class="mode-chip" :class="isQuitMode ? 'mode-chip-quit' : 'mode-chip-record'">
					{{ isQuitMode ? '戒烟模式' : '记录模式' }}
				</view>
			</view>

			<view v-if="isQuitMode">
				<view class="hero-card hero-card-quit">
					<text class="hero-label">已坚持</text>
					<view class="hero-value-row">
						<text class="hero-value">{{ quitDays }}</text>
						<text class="hero-unit">天</text>
					</view>
					<text class="hero-sub">{{ quitSubtitle }}</text>
				</view>

				<view class="primary-action" :class="{ 'primary-action-done': todayChecked }" @tap="handleQuitCheckin">
					<text class="primary-action-icon">{{ todayChecked ? '✓' : '🔥' }}</text>
					<text class="primary-action-title">{{ todayChecked ? '今日已打卡' : '今天没抽，去打卡' }}</text>
					<text class="primary-action-desc">{{ todayChecked ? `已于 ${todayCheckinTime} 记录` : '把今天记成无烟的一天' }}</text>
				</view>

				<view class="stats-grid">
					<view class="stat-card">
						<text class="stat-label">已省下</text>
						<text class="stat-value">¥{{ savedMoney }}</text>
						<text class="stat-desc">按日均 {{ baselineCigsPerDay }} 支估算</text>
					</view>
					<view class="stat-card">
						<text class="stat-label">恢复进度</text>
						<text class="stat-value">{{ healthProgress }}%</text>
						<text class="stat-desc">{{ healthTip }}</text>
					</view>
				</view>

				<view class="note-card">
					<text class="note-title">今日提醒</text>
					<text class="note-text">{{ quitEncouragement }}</text>
				</view>
			</view>

			<view v-else>
				<view class="hero-card hero-card-record">
					<text class="hero-label">距上次抽烟</text>
					<text class="hero-value hero-value-time">{{ timerDisplay }}</text>
					<text class="hero-sub">{{ nextSmokeTimeText ? `下次建议：${nextSmokeTimeText}` : '先把今天的抽烟情况记下来' }}</text>
				</view>

				<view class="stats-grid">
					<view class="stat-card">
						<text class="stat-label">今日已抽</text>
						<text class="stat-value">{{ todayCount }}<text class="stat-unit">根</text></text>
						<text class="stat-desc">目标 {{ dailyTarget }} 根，{{ changeText }}</text>
					</view>
					<view class="stat-card">
						<text class="stat-label">今天忍住</text>
						<text class="stat-value">{{ resistedCount }}<text class="stat-unit">次</text></text>
						<text class="stat-desc">每次忍住都在拉开间隔</text>
					</view>
				</view>

				<view class="action-row">
					<view class="action-btn action-btn-record" @tap="openSmokeDialog">
						<text class="action-icon">🚬</text>
						<text class="action-title">记录抽烟</text>
						<text class="action-desc">补记这一根</text>
					</view>
					<view class="action-btn action-btn-resist" @tap="openResistedDialog">
						<text class="action-icon">💪</text>
						<text class="action-title">想抽忍住了</text>
						<text class="action-desc">记一次成功抵抗</text>
					</view>
				</view>
			</view>
		</view>

		<smoke-record-dialog
			v-if="!isQuitMode"
			v-model:show="showDialog"
			:type="dialogType"
			@submit="handleSubmit"
		/>
	</view>
</template>

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

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

const loading = ref(true)
const navBarHeight = ref(0)
const showDialog = ref(false)
const dialogType = ref('smoke')
const homeData = ref(null)
const pageReady = ref(false)
const quitState = ref(defaultQuitState())

let timerInterval = null
const timerBaseSeconds = ref(-1)
const timerSeconds = ref(0)

const isQuitMode = computed(() => userStore.mode === 'quit')
const homeSummary = computed(() => homeData.value?.summary || {})
const homeTimer = computed(() => homeData.value?.timer || {})

const userName = computed(() => homeData.value?.greeting?.nickname || userStore.user?.nickname || '戒烟用户')
const userAvatar = computed(() => homeData.value?.greeting?.avatar_url || userStore.user?.avatar_url || 'https://linghu-wmr.oss-cn-beijing.aliyuncs.com/smt/avatar.png')

const greetingTitle = computed(() => {
	const hour = new Date().getHours()
	let greeting = '晚上好'
	if (hour < 6) greeting = '凌晨好'
	else if (hour < 12) greeting = '早上好'
	else if (hour < 14) greeting = '中午好'
	else if (hour < 18) greeting = '下午好'
	return `${greeting}，${userName.value}`
})

const greetingSubtitle = computed(() => {
	if (isQuitMode.value) {
		return todayChecked.value ? '今天已经记下来了，继续保持。' : '先把今天记成无烟的一天。'
	}
	return '记录越及时，后面的趋势越准。'
})

const todayCount = computed(() => homeSummary.value.today_count ?? 0)
const dailyTarget = computed(() => {
	const target = homeSummary.value.daily_target
	if (target !== undefined && target !== null) return target
	return profileStore.profile?.baseline_cigs_per_day || 0
})
const resistedCount = computed(() => homeSummary.value.resisted_count ?? 0)

const changeText = computed(() => {
	const reduced = homeSummary.value.reduced_from_yesterday
	if (reduced === undefined || reduced === null) return '较昨日暂无对比'
	if (reduced === 0) return '较昨日持平'
	return homeSummary.value.exceeded_yesterday ? `较昨日多 ${reduced} 根` : `较昨日少 ${reduced} 根`
})

const timerDisplay = computed(() => {
	if (timerBaseSeconds.value < 0) return '--:--:--'
	const totalSeconds = timerBaseSeconds.value + timerSeconds.value
	const hours = Math.floor(totalSeconds / 3600)
	const minutes = Math.floor((totalSeconds % 3600) / 60)
	const seconds = totalSeconds % 60
	return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`
})

const nextSmokeTimeText = computed(() => {
	const timer = homeTimer.value
	if (!timer) return ''
	if (timer.next_suggested_clock) return timer.next_suggested_clock
	if (!timer.next_suggested_at) return ''
	const date = new Date(timer.next_suggested_at)
	if (Number.isNaN(date.getTime())) return ''
	return `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`
})

const baselineCigsPerDay = computed(() => profileStore.profile?.baseline_cigs_per_day || 10)
const packPriceYuan = computed(() => (profileStore.profile?.pack_price_cent || 2500) / 100)
const quitDays = computed(() => {
	if (!quitState.value.lastCheckinDate) return 0
	const gap = diffDays(quitState.value.lastCheckinDate, formatDate(new Date()))
	if (gap > 1) return 0
	return Number(quitState.value.streakDays || 0)
})
const todayChecked = computed(() => quitState.value.lastCheckinDate === formatDate(new Date()))
const todayCheckinTime = computed(() => formatClock(quitState.value.lastCheckinAt))
const savedMoney = computed(() => {
	const total = (quitDays.value * baselineCigsPerDay.value / 20) * packPriceYuan.value
	return Math.round(total)
})
const healthProgress = computed(() => {
	if (quitDays.value >= 365) return 100
	if (quitDays.value >= 180) return 86
	if (quitDays.value >= 90) return 72
	if (quitDays.value >= 30) return 58
	if (quitDays.value >= 14) return 38
	if (quitDays.value >= 7) return 18
	if (quitDays.value >= 1) return 6
	return 0
})
const healthTip = computed(() => {
	if (quitDays.value >= 365) return '肺部功能已进入长期恢复阶段'
	if (quitDays.value >= 180) return '血液循环和咳嗽症状通常会继续改善'
	if (quitDays.value >= 30) return '味觉和嗅觉通常会逐步恢复'
	if (quitDays.value >= 7) return '一周后，呼吸会比开始时更轻松一些'
	if (quitDays.value >= 1) return '第一阶段最难，坚持住就有意义'
	return '打卡从今天开始，先拿下第一天'
})
const quitSubtitle = computed(() => {
	if (!quitState.value.lastCheckinDate) return '还没有开始记录，先拿下第一天。'
	const gap = diffDays(quitState.value.lastCheckinDate, formatDate(new Date()))
	if (gap > 1) return '连续记录已中断，今天重新开始。'
	if (todayChecked.value) return '今天已经打卡，明天继续。'
	return '别漏掉今天这次打卡。'
})
const quitEncouragement = computed(() => {
	if (todayChecked.value) return '今天的无烟记录已经落下，尽量把第一支拖得更晚一些。'
	if (quitDays.value === 0) return '先不要想很久，只把今天守住就够了。'
	return `连续 ${quitDays.value} 天很难得，今天再补上一天。`
})

function defaultQuitState() {
	return {
		lastCheckinDate: '',
		lastCheckinAt: '',
		streakDays: 0
	}
}

function formatDate(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 diffDays(fromDate, toDate) {
	if (!fromDate || !toDate) return 0
	const from = new Date(`${fromDate}T00:00:00`)
	const to = new Date(`${toDate}T00:00:00`)
	const diff = to.getTime() - from.getTime()
	return Math.floor(diff / (24 * 60 * 60 * 1000))
}

function formatClock(value) {
	if (!value) return '--:--'
	const date = new Date(value)
	if (Number.isNaN(date.getTime())) return '--:--'
	return `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`
}

function setupNavBar() {
	const systemInfo = uni.getSystemInfoSync()
	const statusBarH = systemInfo.statusBarHeight || 0
	try {
		const menuBtn = uni.getMenuButtonBoundingClientRect()
		navBarHeight.value = menuBtn.bottom + (menuBtn.top - statusBarH)
	} catch (e) {
		navBarHeight.value = statusBarH + 44
	}
}

function loadQuitState() {
	quitState.value = {
		...defaultQuitState(),
		...(storage.get(QUIT_CHECKIN_KEY) || {})
	}
}

function saveQuitState(nextState) {
	quitState.value = {
		...defaultQuitState(),
		...nextState
	}
	storage.set(QUIT_CHECKIN_KEY, quitState.value)
}

function startTimer() {
	stopTimer()
	if (timerBaseSeconds.value < 0) return
	timerInterval = setInterval(() => {
		timerSeconds.value++
	}, 1000)
}

function stopTimer() {
	if (!timerInterval) return
	clearInterval(timerInterval)
	timerInterval = null
}

function openSmokeDialog() {
	dialogType.value = 'smoke'
	showDialog.value = true
}

function openResistedDialog() {
	dialogType.value = 'resisted'
	showDialog.value = true
}

function applyHomeData(data) {
	homeData.value = data
	const seconds = data?.timer?.seconds_since_last
	timerBaseSeconds.value = typeof seconds === 'number' ? seconds : -1
	timerSeconds.value = 0
	startTimer()
}

async function fetchRecordHomeData() {
	const res = await api.getHome()
	const data = res.data || {}
	applyHomeData(data)
	return data
}

async function handleSubmit(submitData) {
	try {
		if (dialogType.value === 'smoke') {
			await api.createLog(submitData)
			timerBaseSeconds.value = 0
			timerSeconds.value = 0
			startTimer()
			uni.showToast({ title: '记录成功', icon: 'success' })
		} else {
			await api.createResistedLog({
				smoke_time: submitData.smoke_time,
				smoke_at: submitData.smoke_at,
				remark: submitData.remark,
				level: submitData.level,
				num: submitData.num
			})
			uni.showToast({ title: '已记下这次忍住', icon: 'success' })
		}
		await fetchRecordHomeData()
	} catch (e) {
		console.error('handleSubmit error:', e)
		uni.showToast({ title: '保存失败', icon: 'none' })
	}
}

function handleQuitCheckin() {
	if (todayChecked.value) {
		uni.showToast({ title: '今天已经打过卡', icon: 'none' })
		return
	}

	const today = formatDate(new Date())
	const previousDate = quitState.value.lastCheckinDate
	let streakDays = 1

	if (previousDate) {
		const gap = diffDays(previousDate, today)
		if (gap === 1) {
			streakDays = Number(quitState.value.streakDays || 0) + 1
		} else if (gap === 0) {
			streakDays = Number(quitState.value.streakDays || 0)
		}
	}

	saveQuitState({
		lastCheckinDate: today,
		lastCheckinAt: new Date().toISOString(),
		streakDays
	})

	uni.showToast({ title: '打卡成功', icon: 'success' })
}

async function ensureProfileReady() {
	const profileData = await profileStore.fetchProfile()
	const profile = profileData.profile
	const isCompleted = profileData.is_completed ||
		(profile && profile.onboarding_completed_at) ||
		(profile && profile.baseline_cigs_per_day > 0)

	if (!profileData.exists || !isCompleted) {
		uni.navigateTo({ url: '/pages/onboarding/index' })
		return false
	}

	return true
}

async function refreshCurrentMode() {
	if (!userStore.mode) return

	const profileReady = await ensureProfileReady()
	if (!profileReady) return

	if (isQuitMode.value) {
		stopTimer()
		loadQuitState()
		return
	}

	await fetchRecordHomeData()
}

async function initPage() {
	setupNavBar()
	loading.value = true

	try {
		await waitForLogin()
		await profileStore.fetchProfile()

		if (!userStore.mode) {
			uni.navigateTo({ url: '/pages/mode-select/index' })
			return
		}

		await refreshCurrentMode()
	} catch (e) {
		console.error('initPage error:', e)
	} finally {
		pageReady.value = true
		loading.value = false
	}
}

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

onShow(async () => {
	if (!pageReady.value) return
	try {
		await refreshCurrentMode()
	} catch (e) {
		console.error('home onShow error:', e)
	}
})

onUnmounted(() => {
	stopTimer()
})

onShareAppMessage(() => {
	return {
		title: isQuitMode.value ? '我在坚持戒烟打卡' : '我在记录自己的抽烟变化',
		path: 'pages/index/index'
	}
})
</script>

<style scoped>
.page {
	min-height: 100vh;
	background:
		radial-gradient(circle at top left, rgba(16, 185, 129, 0.16), transparent 36%),
		linear-gradient(180deg, #ecfdf5 0%, #f0fdf4 42%, #ffffff 100%);
	box-sizing: border-box;
}

.nav-placeholder {
	background: transparent;
}

.dashboard {
	padding: 24rpx 24rpx 160rpx;
}

.header-card,
.hero-card,
.primary-action,
.stat-card,
.note-card,
.action-btn,
.skeleton-card {
	background: rgba(255, 255, 255, 0.88);
	border-radius: 28rpx;
	border: 2rpx solid rgba(236, 253, 245, 0.9);
	box-shadow: 0 16rpx 42rpx rgba(15, 23, 42, 0.08);
}

.header-card {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 28rpx;
	margin-bottom: 24rpx;
}

.user-info {
	display: flex;
	align-items: center;
	gap: 20rpx;
}

.avatar {
	width: 88rpx;
	height: 88rpx;
	border-radius: 50%;
	border: 4rpx solid #a7f3d0;
	background: #ecfdf5;
}

.greeting-text {
	display: block;
	font-size: 34rpx;
	font-weight: 700;
	color: #111827;
}

.greeting-sub {
	display: block;
	margin-top: 8rpx;
	font-size: 24rpx;
	line-height: 1.5;
	color: #6b7280;
}

.mode-chip {
	padding: 10rpx 18rpx;
	border-radius: 999rpx;
	font-size: 22rpx;
	font-weight: 600;
}

.mode-chip-quit {
	background: rgba(16, 185, 129, 0.12);
	color: #047857;
}

.mode-chip-record {
	background: rgba(248, 113, 113, 0.12);
	color: #b91c1c;
}

.hero-card {
	padding: 34rpx 30rpx;
	margin-bottom: 24rpx;
}

.hero-card-quit {
	background: linear-gradient(135deg, rgba(220, 252, 231, 0.92), rgba(255, 255, 255, 0.92));
}

.hero-card-record {
	background: linear-gradient(135deg, rgba(254, 242, 242, 0.92), rgba(255, 255, 255, 0.92));
}

.hero-label {
	display: block;
	font-size: 24rpx;
	color: #6b7280;
	letter-spacing: 2rpx;
}

.hero-value-row {
	display: flex;
	align-items: baseline;
	gap: 12rpx;
	margin-top: 18rpx;
}

.hero-value,
.hero-value-time {
	display: block;
	margin-top: 18rpx;
	font-size: 84rpx;
	line-height: 1;
	font-weight: 800;
	color: #111827;
}

.hero-unit {
	font-size: 28rpx;
	color: #4b5563;
}

.hero-sub {
	display: block;
	margin-top: 18rpx;
	font-size: 26rpx;
	line-height: 1.6;
	color: #4b5563;
}

.primary-action {
	display: flex;
	flex-direction: column;
	align-items: center;
	padding: 38rpx 30rpx;
	margin-bottom: 24rpx;
	background: linear-gradient(135deg, #10b981 0%, #34d399 100%);
	color: #ffffff;
}

.primary-action-done {
	background: linear-gradient(135deg, #059669 0%, #10b981 100%);
}

.primary-action-icon {
	font-size: 58rpx;
	font-weight: 700;
}

.primary-action-title {
	display: block;
	margin-top: 12rpx;
	font-size: 34rpx;
	font-weight: 700;
}

.primary-action-desc {
	display: block;
	margin-top: 12rpx;
	font-size: 24rpx;
	opacity: 0.88;
}

.stats-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 20rpx;
	margin-bottom: 24rpx;
}

.stat-card {
	padding: 28rpx 24rpx;
}

.stat-label {
	display: block;
	font-size: 24rpx;
	color: #6b7280;
}

.stat-value {
	display: block;
	margin-top: 18rpx;
	font-size: 48rpx;
	line-height: 1.1;
	font-weight: 800;
	color: #111827;
}

.stat-unit {
	font-size: 26rpx;
	font-weight: 600;
	color: #6b7280;
}

.stat-desc {
	display: block;
	margin-top: 16rpx;
	font-size: 23rpx;
	line-height: 1.5;
	color: #6b7280;
}

.note-card {
	padding: 28rpx;
}

.note-title {
	display: block;
	font-size: 24rpx;
	color: #047857;
	font-weight: 700;
}

.note-text {
	display: block;
	margin-top: 14rpx;
	font-size: 26rpx;
	line-height: 1.7;
	color: #374151;
}

.action-row {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 20rpx;
}

.action-btn {
	padding: 30rpx 24rpx;
}

.action-btn-record {
	background: linear-gradient(135deg, rgba(254, 226, 226, 0.92), rgba(255, 255, 255, 0.92));
}

.action-btn-resist {
	background: linear-gradient(135deg, rgba(220, 252, 231, 0.92), rgba(255, 255, 255, 0.92));
}

.action-icon {
	font-size: 40rpx;
}

.action-title {
	display: block;
	margin-top: 14rpx;
	font-size: 30rpx;
	font-weight: 700;
	color: #111827;
}

.action-desc {
	display: block;
	margin-top: 10rpx;
	font-size: 23rpx;
	color: #6b7280;
}

.skeleton {
	padding: 24rpx;
}

.skeleton-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 20rpx;
	margin-bottom: 20rpx;
}

.skeleton-card {
	height: 180rpx;
	background: linear-gradient(90deg, #d1fae5 25%, #ecfdf5 50%, #d1fae5 75%);
	background-size: 200% 100%;
	animation: shimmer 1.5s infinite;
	margin-bottom: 20rpx;
}

.skeleton-card-lg {
	height: 140rpx;
}

.skeleton-card-md {
	height: 260rpx;
}

.skeleton-card-sm {
	height: 120rpx;
}

@keyframes shimmer {
	0% {
		background-position: -200% 0;
	}
	100% {
		background-position: 200% 0;
	}
}
</style>
