import appSettings from '@/core/config/app-settings'
import { buildRestPath } from '@/core/config/api-paths'
import { get } from '@/core/http/http-client'
import { STORAGE } from '@/core/constants/storage-keys'
import {
	fetchAppConfig,
	readCachedAppConfig,
	persistAppConfig
} from '@/features/shell/app-config-gateway'

const pxToRpx = (value) =>
	String(value).replace(/\d*\.?\d+px/g, (m) => `${parseFloat(m) * 2}rpx`)

function transformModuleStyles(modules) {
	const items = modules?.homeModules?.item
	if (!Array.isArray(items)) return
	items.forEach((row) => {
		;['style', 'params'].forEach((bucket) => {
			const target = row[bucket]
			if (!target) return
			Object.keys(target).forEach((key) => {
				if (target[key]) target[key] = pxToRpx(target[key])
			})
		})
	})
}

export default {
	namespaced: true,
	state: {
		appStyle: {},
		appConfig: {},
		appUrl: { api: appSettings.appurl, oss: appSettings.cdnurl },
		appInfo: { adVersion: '0', serviceVersion: '0' },
		adData: { openAdverts: {}, pageAdverts: [], categoryAdverts: [], firstAdverts: [], otherAdverts: [] },
		modulesData: { homeModules: {}, categoryModules: [], searchModules: [] },
		config: { screenshot: false, position: true, map: true },
		version: appSettings.versionName,
		versionCode: appSettings.versionCode
	},
	mutations: {
		patchConfig(state, payload) {
			Object.keys(payload || {}).forEach((key) => {
				if (key in state.config) state.config[key] = payload[key]
			})
		},
		hydrateAppConfigFromCache(state) {
			const cached = readCachedAppConfig()
			if (cached) state.appConfig = cached
		},
		applyAppConfig(state, payload) {
			if (!payload || typeof payload !== 'object') return
			state.appConfig = { ...state.appConfig, ...payload }
			persistAppConfig(state.appConfig)
		},
		applyServices(state, payload) {
			if (payload.appConfig && typeof payload.appConfig === 'object') {
				state.appConfig = { ...state.appConfig, ...payload.appConfig }
				persistAppConfig(state.appConfig)
			}
			state.appStyle = payload.appStyle
			state.modulesData = payload.modulesData
		},
		applyAds(state, payload) {
			state.adData = payload
		}
	},
	actions: {
		async bootstrap({ commit, dispatch, rootState }) {
			commit('hydrateAppConfigFromCache')
			const cachedUser = uni.getStorageSync(STORAGE.user)
			try {
				const { msg } = await get(buildRestPath('token/check'))
				if (msg === 'ok') {
					if (cachedUser) Object.assign(rootState.user, cachedUser)
					rootState.user.isLogin = true
				} else {
					dispatch('clearSession', null, { root: true })
				}
			} catch (_) {
				// #ifdef APP-PLUS
				plus.navigator.closeSplashscreen()
				// #endif
			}
			await Promise.all([
				dispatch('fetchAds'),
				dispatch('fetchServices'),
				dispatch('fetchAppConfig')
			])
		},
		async fetchAppConfig({ state, commit }) {
			try {
				const cfg = await fetchAppConfig({
					lang: undefined,
					version: state.version
				})
				if (cfg) commit('applyAppConfig', cfg)
			} catch (e) {
				console.warn('[shell] fetchAppConfig', e)
			}
		},
		async fetchServices({ state, commit }) {
			try {
				const { data } = await get(buildRestPath('common/init'), { version: state.version })
				transformModuleStyles(data.modulesData)
				commit('applyServices', data)
			} catch (e) {
				console.warn('[shell] fetchServices', e)
			}
		},
		async fetchAds({ state, commit }) {
			try {
				const { data } = await get(buildRestPath('common/adverts'), { version: state.version })
				if (data?.syspopup) {
					uni.showModal({ content: data.syspopup })
					return
				}
				// #ifdef APP-PLUS
				setTimeout(() => plus.navigator.closeSplashscreen(), 100)
				// #endif
				commit('applyAds', data.data || data)
			} catch (e) {
				console.warn('[shell] fetchAds', e)
			}
		}
	}
}
