import CryptoJS from 'crypto-js';
import { encryptedStorage } from '@/utils/storage';

export const ACTIVE_QR_URL_CACHE_KEY = 'cashier:property:active-url';
export const ACTIVE_QR_HASH_CACHE_KEY = 'cashier:property:active-url-hash';
export const PENDING_MERCHANT_URL_KEY = 'cashier:pending-merchant-url';

const decodeOption = (value?: string) => {
	if (!value) return '';
	try {
		return decodeURIComponent(value);
	} catch (error) {
		return value;
	}
};

export const resolveMerchantUrlFromOptions = (options: Record<string, string>) => {
	return decodeOption(options.url || options.qr_url || '');
};

const readQueryParam = (raw: string, key: string) => {
	const match = raw.match(new RegExp(`[?&]${key}=([^&]+)`));
	return match ? decodeOption(match[1]) : '';
};

export const resolveMerchantUrlFromScanResult = (raw: string) => {
	const text = (raw || '').trim();
	if (!text) return '';

	if (/^https?:\/\//i.test(text)) {
		return text;
	}

	const fromUrl = readQueryParam(text, 'url') || readQueryParam(text, 'qr_url');
	if (fromUrl) return fromUrl;

	const fromQ = readQueryParam(text, 'q');
	if (fromQ) return resolveMerchantUrlFromScanResult(fromQ);

	return '';
};

export const setPendingMerchantUrl = (merchantUrl: string) => {
	if (!merchantUrl) return;
	encryptedStorage.set(PENDING_MERCHANT_URL_KEY, merchantUrl);
	// @ts-ignore
	if (uni.$globalData) {
		// @ts-ignore
		uni.$globalData.pendingMerchantUrl = merchantUrl;
	}
};

export const getPendingMerchantUrl = () => {
	// @ts-ignore
	const fromMemory = uni.$globalData?.pendingMerchantUrl;
	if (fromMemory) return String(fromMemory);

	return encryptedStorage.get<string>(PENDING_MERCHANT_URL_KEY) || '';
};

export const clearPendingMerchantUrl = () => {
	encryptedStorage.remove(PENDING_MERCHANT_URL_KEY);
	// @ts-ignore
	if (uni.$globalData) {
		// @ts-ignore
		uni.$globalData.pendingMerchantUrl = '';
	}
};

const resolveMerchantUrlFromRawEntry = (raw?: string) => {
	if (!raw) return '';
	return resolveMerchantUrlFromScanResult(decodeOption(raw));
};

const getLaunchQuery = () => {
	try {
		const launchOptions = uni.getLaunchOptionsSync?.();
		return (launchOptions?.query || {}) as Record<string, string>;
	} catch (error) {
		return {};
	}
};

/** App.onLaunch / App.onShow：捕获支付宝普通二维码 qrCode */
export const captureMerchantUrlFromLaunchOptions = (options: Record<string, any> = {}) => {
	const query = options.query || {};
	const qrCode = query.qrCode || query.qr_code || '';
	if (!qrCode) return '';

	const merchantUrl = resolveMerchantUrlFromRawEntry(String(qrCode));
	if (!merchantUrl) return '';

	setPendingMerchantUrl(merchantUrl);
	return merchantUrl;
};

/**
 * 统一解析进页 merchantUrl：
 * 1. ?url= / ?qr_url=（开发调试、内部跳转）
 * 2. 微信普通二维码 options.q
 * 3. 支付宝 query.qrCode（页面参数 / getLaunchOptionsSync）
 * 4. App 缓存 pendingMerchantUrl
 */
export const resolveMerchantUrlFromEntry = (options: Record<string, any> = {}) => {
	const direct = resolveMerchantUrlFromOptions(options as Record<string, string>);
	if (direct) {
		const merchantUrl = resolveMerchantUrlFromScanResult(direct);
		if (merchantUrl) return merchantUrl;
	}

	if (options.q) {
		const fromQ = resolveMerchantUrlFromRawEntry(String(options.q));
		if (fromQ) return fromQ;
	}

	const pageQrCode = options.qrCode || options.qr_code;
	if (pageQrCode) {
		const fromPageQr = resolveMerchantUrlFromRawEntry(String(pageQrCode));
		if (fromPageQr) return fromPageQr;
	}

	const launchQuery = getLaunchQuery();
	const launchQrCode = launchQuery.qrCode || launchQuery.qr_code;
	if (launchQrCode) {
		const fromLaunch = resolveMerchantUrlFromRawEntry(String(launchQrCode));
		if (fromLaunch) return fromLaunch;
	}

	return getPendingMerchantUrl();
};

export const getMerchantUrlHash = (merchantUrl: string) => {
	return CryptoJS.SHA256(merchantUrl).toString();
};

export const getPropertyBindingCacheKeyByHash = (hash: string) => {
	// Hash key keeps cache key short/stable and avoids raw URL special characters.
	return `cashier:property:binding:${hash}`;
};

export const getSupplierCacheKeyByHash = (hash: string) => {
	return `cashier:supplier:detail:${hash}`;
};

export const getPropertyBindingCacheKey = (merchantUrl: string) => {
	return getPropertyBindingCacheKeyByHash(getMerchantUrlHash(merchantUrl));
};

export const getSupplierCacheKey = (merchantUrl: string) => {
	return getSupplierCacheKeyByHash(getMerchantUrlHash(merchantUrl));
};

export const syncActiveMerchantContext = (merchantUrl: string) => {
	const currentHash = getMerchantUrlHash(merchantUrl);
	const previousHash = encryptedStorage.get<string>(ACTIVE_QR_HASH_CACHE_KEY) || '';
	encryptedStorage.set(ACTIVE_QR_URL_CACHE_KEY, merchantUrl);
	encryptedStorage.set(ACTIVE_QR_HASH_CACHE_KEY, currentHash);

	return {
		currentHash,
		previousHash,
		switched: Boolean(previousHash && previousHash !== currentHash)
	};
};

export const getActiveMerchantUrl = () => encryptedStorage.get<string>(ACTIVE_QR_URL_CACHE_KEY) || '';

export const clearActiveMerchantContext = () => {
	encryptedStorage.remove(ACTIVE_QR_URL_CACHE_KEY);
	encryptedStorage.remove(ACTIVE_QR_HASH_CACHE_KEY);
};
