import Taro from '@tarojs/taro';

import { PageUrl, PluginUrl } from '@/constants/app';
import { logWithPrefix, safeJsonParse } from '@/utils/common';

type ValidUrl = PageUrl | PluginUrl;

const log = logWithPrefix('route-utils');

function completeUrl(path: string) {
  if (path.startsWith('pages')) {
    return `/${path}`;
  }
  return path;
}

export function getJumpUrl(page: ValidUrl, params: Record<string, BL.Anything> = {}) {
  const query = Object.entries(params)
    .filter(([_k, v]) => typeof v !== 'undefined')
    .map(([k, v]) => `${k}=${typeof v === 'object' ? encodeURIComponent(JSON.stringify(v)) : v}`)
    .join('&');
  const url = completeUrl(`${page}${query ? `?${query}` : ''}`);
  return url;
}

export function switchTab(page: PageUrl, params: Record<string, BL.Anything> = {}) {
  const url = getJumpUrl(page, params);
  log('switchTab', url);
  return new Promise((resolve, reject) => {
    Taro.switchTab({ url, success: resolve, fail: reject });
  });
}

export function redirectTo(page: PageUrl, params: Record<string, BL.Anything> = {}) {
  const url = getJumpUrl(page, params);
  log('redirectTo', url);
  return new Promise((resolve, reject) => {
    Taro.redirectTo({ url, success: resolve, fail: reject });
  });
}

export function navigateTo(page: ValidUrl, params: Record<string, BL.Anything> = {}) {
  const url = getJumpUrl(page, params);
  log('navigateTo', url);
  return new Promise((resolve, reject) => {
    Taro.navigateTo({ url, success: resolve, fail: reject });
  });
}

export function navigateBack(delta: number = 1) {
  return new Promise((resolve, reject) => {
    Taro.navigateBack({ delta, success: resolve, fail: reject });
  });
}

export function getPageQuery<T = Record<string, BL.Anything>>() {
  const params = (Taro.getCurrentInstance().router?.params || {}) as T;
  return params;
}

export function parseQuery<T = BL.Anything>(obj: string, defaultValue: BL.Anything = null) {
  return safeJsonParse<T>(decodeURIComponent(obj), defaultValue);
}
