import { initPreferences } from '@vben/preferences';
import { merge, unmountGlobalLoading } from '@vben/utils';

import { overridesPreferences } from './preferences';

/**
 * 从 URL 路径中解析 appCode 和模式
 * URL 格式：
 * - /app/:appCode/... （正常模式）
 */
function getAppInfoFromUrl(): { appCode: null | string } {
  const path = window.location.pathname;

  const appMatch = path.match(/^\/app\/([^/]+)/);
  if (appMatch?.[1]) {
    return { appCode: appMatch[1] };
  }

  return { appCode: null };
}

/**
 * 根据 appCode 获取应用详情
 */
async function getApplicationByCode(
  appCode: string,
): Promise<null | { id: string }> {
  try {
    const apiURL = import.meta.env.VITE_GLOB_API_URL || '';
    const response = await fetch(
      `${apiURL}/api/core/applications/code/${appCode}`,
      {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
        },
      },
    );

    if (response.ok) {
      const result = await response.json();
      // 后端直接返回应用数据，不包装 code/data
      if (result && result.id) {
        return result;
      }
    }
  } catch (error) {
    console.warn('[应用加载] 获取应用详情失败', error);
  }
  return null;
}

/**
 * 从后端加载UI配置
 * 如果加载失败则返回空对象，使用前端默认配置
 * @param applicationId 应用ID，不传则获取主应用配置
 */
async function loadBackendPreferences(
  applicationId?: string,
): Promise<Record<string, any>> {
  try {
    const apiURL = import.meta.env.VITE_GLOB_API_URL || '';
    const url = applicationId
      ? `${apiURL}/api/core/ui_config/preferences?applicationId=${applicationId}`
      : `${apiURL}/api/core/ui_config/preferences`;
    const response = await fetch(url, {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
      },
    });

    if (response.ok) {
      const result = await response.json();
      // 后端直接返回配置数据，不包装 code/data
      if (result && typeof result === 'object') {
        console.log(
          '[配置加载] 成功从后端加载UI配置',
          applicationId ? `(应用: ${applicationId})` : '(主应用)',
        );
        return result;
      }
    }
  } catch (error) {
    console.warn('[配置加载] 后端UI配置加载失败，使用前端默认配置', error);
  }
  return {};
}

/**
 * 应用初始化完成之后再进行页面加载渲染
 */
async function initApplication() {
  // name用于指定项目唯一标识
  // 用于区分不同项目的偏好设置以及存储数据的key前缀以及其他一些需要隔离的数据
  const env = import.meta.env.PROD ? 'prod' : 'dev';
  const appVersion = import.meta.env.VITE_APP_VERSION;
  const baseNamespace = `${import.meta.env.VITE_APP_NAMESPACE}-${appVersion}-${env}`;

  // 1. 检查是否为子应用模式，获取 appCode 和 applicationId
  const { appCode } = getAppInfoFromUrl();
  let applicationId: string | undefined;

  if (appCode) {
    const appInfo = await getApplicationByCode(appCode);
    applicationId = appInfo?.id;
    console.log('[应用初始化] 子应用模式', {
      appCode,
      applicationId,
    });
  } else {
    console.log('[应用初始化] 主应用模式');
  }

  // 2. 根据应用模式生成不同的 namespace，确保主应用和子应用的 localStorage 隔离
  // 主应用: vben-admin-1.0.0-dev
  // 子应用正常模式: vben-admin-1.0.0-dev-crm
  let namespace = baseNamespace;
  if (appCode) {
    namespace = `${baseNamespace}-${appCode}`;
  }

  // 3. 从后端加载UI配置（传递 applicationId 获取对应应用的配置）
  const backendPreferences = await loadBackendPreferences(applicationId);
  console.log('[配置加载] 后端配置:', backendPreferences);
  console.log('[配置加载] 前端默认配置:', overridesPreferences);

  // 4. 合并配置：后端配置优先级高于前端配置
  // defu/merge 的特点是第一个参数优先，所以后端配置放前面
  const finalPreferences = merge({}, backendPreferences, overridesPreferences);
  if (!applicationId && overridesPreferences.app) {
    finalPreferences.app = finalPreferences.app || {};
    finalPreferences.app.name = overridesPreferences.app.name;
    finalPreferences.app.defaultHomePath = overridesPreferences.app.defaultHomePath;
  }
  if (!applicationId && overridesPreferences.copyright) {
    finalPreferences.copyright = merge(
      {},
      overridesPreferences.copyright,
      finalPreferences.copyright,
    );
  }
  if (!applicationId && overridesPreferences.logo) {
    finalPreferences.logo = merge(
      {},
      overridesPreferences.logo,
      finalPreferences.logo,
    );
  }
  if (!applicationId && overridesPreferences.widget) {
    finalPreferences.widget = merge(
      {},
      overridesPreferences.widget,
      finalPreferences.widget,
    );
  }
  console.log('[配置加载] 合并后配置:', finalPreferences);

  // 5. app偏好设置初始化
  await initPreferences({
    namespace,
    overrides: finalPreferences,
  });

  // 启动应用并挂载
  // vue应用主要逻辑及视图
  const { bootstrap } = await import('./bootstrap');
  await bootstrap(namespace);

  // 移除并销毁loading
  unmountGlobalLoading();
}

initApplication();
