import supa from '@/components/supadb/aksupainstance.uts'
import { HOME_REDIRECT } from '@/ak/config.uts'
import { AkReq } from '@/uni_modules/ak-req/index.uts'
import { getCurrentUser, logout, state } from '@/utils/store.uts'
import type { UserProfile } from '@/types/mall-types.uts'

export type MerchantInfo = {
	id: string
	merchant_id: string
	shop_name: string
	shop_logo: string
	shop_banner: string
	description: string
	contact_name: string
	contact_phone: string
	status: number | null
}

export type MerchantAuthOptions = {
	redirectOnFail?: boolean
	toastOnFail?: boolean
	redirect?: string
	message?: string
}

export type MerchantAuthResult = {
	ok: boolean
	message: string
	userInfo: UserProfile | null
	merchantInfo: MerchantInfo | null
}

const MERCHANT_LOGIN_PATH = '/pages/user/login?mode=merchant'
const MERCHANT_HOME_PATH = HOME_REDIRECT !== '' ? HOME_REDIRECT : '/pages/mall/merchant/index'

let redirectingToMerchantLogin = false

function hasText(value: string | null): boolean {
	return value != null && value !== ''
}

function getCurrentRoute(): string {
	try {
		const pages = getCurrentPages() as Array<UTSJSONObject>
		if (pages.length === 0) {
			return ''
		}
		const currentPage = pages[pages.length - 1]
		const route = currentPage['route']
		if (route != null) {
			return '/' + route
		}
	} catch (e) {}
	return ''
}

function isMerchantRoute(route: string): boolean {
	return route.startsWith('/pages/mall/merchant/')
}

function shouldShowToast(enabled: boolean | null): boolean {
	return enabled == null || enabled === true
}

function shouldRedirect(enabled: boolean | null): boolean {
	return enabled == null || enabled === true
}

function buildMerchantInfo(raw: UTSJSONObject): MerchantInfo {
	return {
		id: raw.getString('id') ?? '',
		merchant_id: raw.getString('merchant_id') ?? '',
		shop_name: raw.getString('shop_name') ?? '',
		shop_logo: raw.getString('shop_logo') ?? '',
		shop_banner: raw.getString('shop_banner') ?? '',
		description: raw.getString('description') ?? '',
		contact_name: raw.getString('contact_name') ?? '',
		contact_phone: raw.getString('contact_phone') ?? '',
		status: raw.getNumber('status')
	}
}

function persistMerchantInfo(info: MerchantInfo): void {
	const payload = new UTSJSONObject()
	payload.set('id', info.id)
	payload.set('merchant_id', info.merchant_id)
	payload.set('shop_name', info.shop_name)
	payload.set('shop_logo', info.shop_logo)
	payload.set('shop_banner', info.shop_banner)
	payload.set('description', info.description)
	payload.set('contact_name', info.contact_name)
	payload.set('contact_phone', info.contact_phone)
	if (info.status != null) {
		payload.set('status', info.status)
	}
	uni.setStorageSync('merchant_info', JSON.stringify(payload))
	if (hasText(info.merchant_id)) {
		uni.setStorageSync('merchant_id', info.merchant_id)
	} else {
		uni.removeStorageSync('merchant_id')
	}
}

function buildFailureResult(message: string, userInfo: UserProfile | null = null): MerchantAuthResult {
	return {
		ok: false,
		message,
		userInfo,
		merchantInfo: null
	}
}

async function fetchMerchantInfoByUserId(userId: string): Promise<MerchantInfo | null> {
	let response = await supa
		.from('ml_shops')
		.select('id, merchant_id, shop_name, shop_logo, shop_banner, description, contact_name, contact_phone, status')
		.eq('merchant_id', userId)
		.limit(1)
		.execute()

	if (response.error == null && response.data != null) {
		const rows = response.data as Array<UTSJSONObject>
		if (rows.length > 0) {
			return buildMerchantInfo(rows[0])
		}
	}

	response = await supa
		.from('ml_shops')
		.select('id, merchant_id, shop_name, shop_logo, shop_banner, description, contact_name, contact_phone, status')
		.eq('id', userId)
		.limit(1)
		.execute()

	if (response.error == null && response.data != null) {
		const rows = response.data as Array<UTSJSONObject>
		if (rows.length > 0) {
			return buildMerchantInfo(rows[0])
		}
	}

	return null
}

function getRedirectTarget(explicitRedirect: string | null): string {
	if (hasText(explicitRedirect)) {
		return explicitRedirect as string
	}
	const currentRoute = getCurrentRoute()
	if (hasText(currentRoute) && currentRoute !== '/pages/user/login') {
		return currentRoute
	}
	return MERCHANT_HOME_PATH
}

function handleFailure(message: string, options?: MerchantAuthOptions, userInfo: UserProfile | null = null): MerchantAuthResult {
	clearAuth()
	if (shouldShowToast(options?.toastOnFail ?? null) && hasText(message)) {
		uni.showToast({ title: message, icon: 'none' })
	}
	if (shouldRedirect(options?.redirectOnFail ?? null)) {
		redirectToMerchantLogin(getRedirectTarget(options?.redirect ?? null))
	}
	return buildFailureResult(message, userInfo)
}

export function getToken(): string {
	const token = AkReq.getToken()
	return token != null ? token : ''
}

export async function getUserInfo(): Promise<UserProfile | null> {
	try {
		const profile = state.userProfile
		if (profile != null && hasText(profile.id ?? null)) {
			return profile as UserProfile
		}
	} catch (e) {}
	return await getCurrentUser()
}

export function getMerchantInfo(): MerchantInfo | null {
	try {
		const raw = uni.getStorageSync('merchant_info') as string | null
		if (hasText(raw)) {
			const parsed = JSON.parse(raw as string) as UTSJSONObject
			return buildMerchantInfo(parsed)
		}
	} catch (e) {
		console.error('[merchantAuth] 读取 merchant_info 失败:', e)
	}
	return null
}

export function setMerchantInfo(info: MerchantInfo): void {
	persistMerchantInfo(info)
}

export function isLoggedIn(): boolean {
	try {
		const session = supa.getSession()
		const hasSession = session != null && session.user != null
		const storedId = uni.getStorageSync('user_id') as string | null
		const hasStoredId = hasText(storedId)
		return hasSession || hasStoredId
	} catch (e) {
		return false
	}
}

export function isMerchantRole(userInfo: UserProfile | null): boolean {
	if (userInfo == null) {
		return false
	}
	const role = userInfo.role != null ? userInfo.role : ''
	return role === 'merchant'
}

export async function checkMerchantAccount(userInfo: UserProfile): Promise<MerchantInfo | null> {
	const userId = userInfo.id != null ? userInfo.id : ''
	if (!hasText(userId)) {
		return null
	}
	try {
		return await fetchMerchantInfoByUserId(userId)
	} catch (e) {
		console.error('[merchantAuth] 查询商家信息失败:', e)
		return null
	}
}

export function clearAuth(): void {
	try {
		AkReq.clearToken()
	} catch (e) {}
	uni.removeStorageSync('user_id')
	uni.removeStorageSync('merchant_id')
	uni.removeStorageSync('merchant_info')
	uni.removeStorageSync('merchant_idx_cache')
	try {
		logout()
	} catch (e) {}
}

export function redirectToMerchantLogin(redirect?: string): void {
	const currentRoute = getCurrentRoute()
	if (currentRoute === '/pages/user/login') {
		return
	}
	if (redirectingToMerchantLogin) {
		return
	}
	redirectingToMerchantLogin = true
	let targetUrl = MERCHANT_LOGIN_PATH
	const redirectTarget = getRedirectTarget(redirect != null ? redirect : null)
	if (hasText(redirectTarget)) {
		targetUrl = `${MERCHANT_LOGIN_PATH}&redirect=${encodeURIComponent(redirectTarget)}`
	}
	uni.reLaunch({
		url: targetUrl,
		complete: () => {
			setTimeout(() => {
				redirectingToMerchantLogin = false
			}, 300)
		}
	})
}

export function goMerchantHome(): void {
	uni.reLaunch({ url: MERCHANT_HOME_PATH })
}

export async function requireMerchantAuth(options?: MerchantAuthOptions): Promise<MerchantAuthResult> {
	const currentRoute = getCurrentRoute()
	if (currentRoute === '/pages/user/login') {
		return {
			ok: true,
			message: '',
			userInfo: null,
			merchantInfo: null
		}
	}

	if (!isLoggedIn()) {
		return handleFailure(options?.message ?? '请先登录商家账号', options)
	}

	const userInfo = await getUserInfo()
	if (userInfo == null || !hasText(userInfo.id ?? null)) {
		return handleFailure('登录状态已失效，请重新登录', options)
	}

	if (!isMerchantRole(userInfo)) {
		const message = options?.message != null && options.message !== ''
			? options.message
			: '当前账号不是商家账号'
		return handleFailure(message, options, userInfo)
	}

	const merchantInfo = await checkMerchantAccount(userInfo)
	if (merchantInfo == null) {
		return handleFailure('当前账号未绑定商家信息', options, userInfo)
	}

	if (merchantInfo.status != null) {
		if (merchantInfo.status === 0) {
			return handleFailure('当前商家信息待审核', options, userInfo)
		}
		if (merchantInfo.status !== 1) {
			return handleFailure('当前商家状态异常，暂不可登录', options, userInfo)
		}
	}

	persistMerchantInfo(merchantInfo)
	return {
		ok: true,
		message: '',
		userInfo,
		merchantInfo
	}
}

export function isCurrentMerchantPage(): boolean {
	return isMerchantRoute(getCurrentRoute())
}