import {
    memberCenterMock,
    userInfoMock,
    memberCardMock,
    bookingMock
} from './mockData.js'
import { formatMemberCenterPhone, normalizePhoneForStore } from './format.js'
import {
    getDefaultBodyTestState,
    mergeBodyTestState,
    getLatestBodyTestRecord,
    buildBodyReportSummary
} from './bodyTestStore.js'
import {
    getDefaultModuleState,
    mergeModuleState,
    finalizeModules
} from './moduleStore.js'
import {
    getDefaultCourseCatalog,
    mergeCourseCatalog,
    canCancelBooking
} from './bookingStore.js'

const STORAGE_KEY = 'gym_member_info_v1'

function clone(value) {
    return JSON.parse(JSON.stringify(value))
}

export function buildCardTip(remainingDays) {
    return `距离下次到期还有${remainingDays}天，请及时续费`
}

function applyCardInfo(store) {
    const days = computeRemainingDays(store.card.validityEnd)
    store.card.remainingDays = days
    store.cardInfo.remainingDays = days
    store.cardInfo.tip = buildCardTip(days)
    return store
}

export function syncStats(store) {
    store.stats = {
        ...store.stats,
        pointsBalance: store.stats.pointsBalance ?? 1250
    }
    return store
}

function finalizeStore(store) {
    syncStats(store)
    applyCardInfo(store)
    if (store.profile?.avatar) {
        store.memberProfile.avatar = store.profile.avatar
    }
    if (store.profile?.phone) {
        store.memberProfile.phone = formatMemberCenterPhone(store.profile.phone)
    }
    const latestBodyTest = getLatestBodyTestRecord(store)
    if (latestBodyTest) {
        const previous = store.bodyTest.records[1]
        store.bodyReport = buildBodyReportSummary(latestBodyTest, previous)
    }
    if (store.modules) {
        finalizeModules(store)
    }
    return store
}

function getDefaultStore() {
    return finalizeStore({
        profile: { ...userInfoMock, avatar: memberCenterMock.userInfo.avatar },
        memberProfile: { ...memberCenterMock.userInfo },
        stats: { ...memberCenterMock.stats },
        cardInfo: { ...memberCenterMock.cardInfo },
        card: { ...memberCardMock.card },
        records: clone(memberCardMock.records),
        ongoingBookings: clone(bookingMock.ongoing),
        historyBookings: clone(bookingMock.history),
        checkIns: clone(memberCenterMock.checkIns),
        bodyReport: { ...memberCenterMock.bodyReport },
        bodyTest: getDefaultBodyTestState(),
        modules: getDefaultModuleState(),
        courseCatalog: getDefaultCourseCatalog(),
        couponPoints: { ...memberCenterMock.couponPoints },
        referral: { ...memberCenterMock.referral }
    })
}

function mergeDefaults(saved) {
    const defaults = getDefaultStore()
    return finalizeStore({
        profile: { ...defaults.profile, ...(saved.profile || {}) },
        memberProfile: { ...defaults.memberProfile, ...(saved.memberProfile || {}) },
        stats: { ...defaults.stats, ...(saved.stats || {}) },
        cardInfo: { ...defaults.cardInfo, ...(saved.cardInfo || {}) },
        card: { ...defaults.card, ...(saved.card || {}) },
        records: saved.records?.length ? saved.records : defaults.records,
        ongoingBookings: saved.ongoingBookings ?? defaults.ongoingBookings,
        historyBookings: saved.historyBookings ?? defaults.historyBookings,
        checkIns: saved.checkIns?.length ? saved.checkIns : defaults.checkIns,
        bodyReport: { ...defaults.bodyReport, ...(saved.bodyReport || {}) },
        bodyTest: mergeBodyTestState(saved.bodyTest),
        modules: mergeModuleState(saved.modules),
        courseCatalog: mergeCourseCatalog(saved.courseCatalog),
        couponPoints: { ...defaults.couponPoints, ...(saved.couponPoints || {}) },
        referral: { ...defaults.referral, ...(saved.referral || {}) }
    })
}

export function loadMemberStore() {
    try {
        const saved = uni.getStorageSync(STORAGE_KEY)
        if (saved && typeof saved === 'object') {
            return mergeDefaults(saved)
        }
    } catch (e) {
        console.warn('[memberStore] load failed', e)
    }
    return getDefaultStore()
}

export function saveMemberStore(store) {
    uni.setStorageSync(STORAGE_KEY, store)
}

/** 解析为本地 0 点，避免 ISO 字符串时区偏差 */
export function parseLocalDate(dateStr) {
    if (!dateStr) return null
    const str = String(dateStr).trim()
    const iso = str.match(/^(\d{4})-(\d{2})-(\d{2})$/)
    if (iso) {
        return new Date(Number(iso[1]), Number(iso[2]) - 1, Number(iso[3]))
    }
    const cn = str.match(/(\d{4})年(\d{2})月(\d{2})日/)
    if (cn) {
        return new Date(Number(cn[1]), Number(cn[2]) - 1, Number(cn[3]))
    }
    const parsed = new Date(str.replace(/-/g, '/'))
    return Number.isNaN(parsed.getTime()) ? null : parsed
}

function formatIsoDate(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 formatChineseDate(date) {
    const y = date.getFullYear()
    const m = String(date.getMonth() + 1).padStart(2, '0')
    const day = String(date.getDate()).padStart(2, '0')
    return `${y}年${m}月${day}日`
}

function formatRecordTime(date) {
    const y = date.getFullYear()
    const m = String(date.getMonth() + 1).padStart(2, '0')
    const d = String(date.getDate()).padStart(2, '0')
    const h = String(date.getHours()).padStart(2, '0')
    const min = String(date.getMinutes()).padStart(2, '0')
    return `${y}-${m}-${d}  ${h}:${min}`
}

function nextRecordId(records) {
    return (records || []).reduce((max, item) => Math.max(max, item.id || 0), 0) + 1
}

export function computeRemainingDays(endDateStr) {
    const end = parseLocalDate(endDateStr)
    if (!end) return 0
    const now = new Date()
    now.setHours(0, 0, 0, 0)
    end.setHours(0, 0, 0, 0)
    const diff = Math.ceil((end - now) / 86400000)
    return Math.max(0, diff)
}

export function formatUpcomingAlert(booking) {
    if (!booking) return ''
    const timePart = booking.timeRange || booking.schedule?.split(' ')[1] || ''
    return `明天 ${timePart} 有一堂${booking.title}，请提前 30 分钟到场`
}

export function toBookingPreviewItem(item) {
    return {
        id: item.id,
        dateDay: item.dateDay,
        dateMonth: item.dateMonth,
        desc: `${item.title} · ${item.timeRange}`,
        coach: item.coachShort || item.coach.replace('教练', ''),
        location: item.location ? `地点：${item.location}` : '',
        status: item.status,
        statusLabel: item.statusLabel
    }
}

export function getBookingPreview(store, limit = 2) {
    return store.ongoingBookings.slice(0, limit).map(toBookingPreviewItem)
}

export function getCenterPageData(store) {
    return {
        userInfo: { ...store.memberProfile },
        stats: { ...store.stats },
        cardInfo: { ...store.cardInfo },
        bookingPreview: getBookingPreview(store),
        checkIns: store.checkIns.map((item) => ({ ...item })),
        bodyReport: {
            ...store.bodyReport,
            weight: store.profile.weight || store.bodyReport.weight
        },
        couponPoints: {
            ...store.couponPoints,
            points: store.stats.pointsBalance
        },
        referral: { ...store.referral }
    }
}

export function cancelOngoingBooking(store, id) {
    const index = store.ongoingBookings.findIndex((b) => b.id === id)
    if (index < 0) return { ok: false, message: '预约不存在' }

    const item = store.ongoingBookings[index]
    if (!canCancelBooking(item)) {
        return { ok: false, message: '距开课不足2小时，无法取消' }
    }

    const [removed] = store.ongoingBookings.splice(index, 1)
    if (removed.courseId) {
        const course = store.courseCatalog.find((c) => c.id === removed.courseId)
        if (course && course.enrolled > 0) course.enrolled -= 1
    }
    store.historyBookings.unshift({
        ...removed,
        status: 'cancelled',
        statusLabel: '已取消',
        footerText: '用户主动取消',
        canCancel: false
    })
    finalizeStore(store)
    saveMemberStore(store)
    return { ok: true, message: '已取消' }
}

export function renewMemberCard(store, addDays = 90) {
    const now = new Date()
    now.setHours(0, 0, 0, 0)

    let base = parseLocalDate(store.card.validityEnd) || new Date(now)
    base.setHours(0, 0, 0, 0)
    // 已过期：从今天起续费；未过期：从当前到期日起顺延
    if (base < now) {
        base = new Date(now)
    }

    const end = new Date(base)
    end.setDate(end.getDate() + addDays)

    const validityEnd = formatIsoDate(end)
    const validityEndCn = formatChineseDate(end)
    store.card.validityEnd = validityEnd
    store.card.validity = store.card.validityStart
        ? `${store.card.validityStart} - ${validityEndCn}`
        : `2024年01月01日 - ${validityEndCn}`
    store.cardInfo.expireDate = `有效期至 ${validityEndCn}`

    store.records.unshift({
        id: nextRecordId(store.records),
        type: 'consume',
        title: '会员卡续费',
        time: formatRecordTime(new Date()),
        value: `+${addDays}天`,
        valueType: 'positive',
        icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/pluscircle.png',
        iconTheme: 'orange'
    })

    finalizeStore(store)
    saveMemberStore(store)
    return store
}

export function saveUserProfile(store, profile) {
    const phone = normalizePhoneForStore(profile.phone ?? store.profile.phone)
    store.profile = { ...store.profile, ...profile, phone }
    store.memberProfile = {
        ...store.memberProfile,
        name: store.profile.name,
        phone: formatMemberCenterPhone(store.profile.phone),
        avatar: store.profile.avatar || store.memberProfile.avatar
    }
    if (store.profile.weight) {
        store.bodyReport.weight = store.profile.weight
    }
    finalizeStore(store)
    saveMemberStore(store)
    return store
}

export function persistMemberStore(store) {
    finalizeStore(store)
    saveMemberStore(store)
    return store
}
