const gatewayAPIBase = (import.meta.env.VITE_GATEWAY_API_BASE_URL ?? 'http://localhost:8088').replace(/\/$/, '');

export type OIDCRuntimeConfiguration = {
  enabled: boolean;
  oidcLogin: boolean;
  contextTypes: OIDCContextType[];
  loginUrl?: string;
  logoutUrl?: string;
  status: string;
};

export type OIDCContextType = 'platform' | 'tenant';

const disabledRuntime: OIDCRuntimeConfiguration = {
  enabled: false,
  oidcLogin: false,
  contextTypes: [],
  status: 'disabled',
};
let runtimeConfiguration = disabledRuntime;
let runtimeLoaded = false;
let runtimeRequest: Promise<OIDCRuntimeConfiguration> | null = null;

export type OIDCCallbackError = {
  code: string;
  reason?: string;
  diagnosticId?: string;
  message: string;
  retryable: boolean;
};

const callbackErrors: Record<string, Omit<OIDCCallbackError, 'code'>> = {
  OIDC_LOGIN_INVALID: { message: '统一认证登录事务无效或已过期，请重新登录', retryable: true },
  OIDC_TOKEN_EXCHANGE_FAILED: { message: '统一认证登录结果无效，请重新登录', retryable: false },
  OIDC_SESSION_STORE_UNAVAILABLE: { message: '登录会话存储暂时不可用，请稍后重试', retryable: false },
  GATEWAY_USER_NOT_PROVISIONED: { message: '该账号尚未开通 EasyAI Gateway', retryable: false },
  GATEWAY_USER_DISABLED: { message: '该 Gateway 账号已停用，请联系管理员', retryable: false },
  GATEWAY_TENANT_UNAVAILABLE: { message: 'Gateway 租户尚未就绪，请联系管理员', retryable: false },
};

const loginTransactionFailureMessages: Record<string, string> = {
  COOKIE_MISSING: '浏览器未携带统一认证登录事务 Cookie，请允许 localhost Cookie 后重新登录',
  TRANSACTION_INVALID: '统一认证登录事务无法验证或已过期，请重新登录',
  STATE_MISMATCH: '认证回调与当前登录事务不匹配，请关闭重复登录页面后重新登录',
  AUTHORIZATION_RESPONSE_MISSING: '认证中心回调缺少必要参数，请重新登录',
};

export function oidcLoginEnabled() {
  return runtimeConfiguration.enabled && runtimeConfiguration.oidcLogin;
}

export function oidcBrowserSessionEnabled() {
  return oidcLoginEnabled();
}

export function loginEntryAction(
  configuration: OIDCRuntimeConfiguration,
): 'oidc' | 'workspace' {
  return configuration.enabled && configuration.oidcLogin ? 'oidc' : 'workspace';
}

export async function loadOIDCRuntimeConfiguration(force = false): Promise<OIDCRuntimeConfiguration> {
  if (!force && runtimeLoaded) return runtimeConfiguration;
  if (!force && runtimeRequest) return runtimeRequest;
  runtimeRequest = fetch(`${gatewayAPIBase}/api/v1/public/identity`, {
    credentials: 'include',
    headers: { Accept: 'application/json' },
  }).then(async (response) => {
    if (!response.ok) return disabledRuntime;
    const value = await response.json() as Partial<OIDCRuntimeConfiguration>;
    if (typeof value.enabled !== 'boolean' || typeof value.oidcLogin !== 'boolean' || typeof value.status !== 'string') {
      return disabledRuntime;
    }
    return {
      enabled: value.enabled,
      oidcLogin: value.oidcLogin,
      contextTypes: Array.isArray(value.contextTypes)
        ? value.contextTypes.filter(
          (item): item is OIDCContextType =>
            item === 'platform' || item === 'tenant',
        )
        : [],
      status: value.status,
      ...(typeof value.loginUrl === 'string' ? { loginUrl: value.loginUrl } : {}),
      ...(typeof value.logoutUrl === 'string' ? { logoutUrl: value.logoutUrl } : {}),
    };
  }).catch(() => disabledRuntime).then((configuration) => {
    runtimeConfiguration = configuration;
    runtimeLoaded = true;
    runtimeRequest = null;
    return configuration;
  });
  return runtimeRequest;
}

export async function startOIDCLogin(
  contextType?: OIDCContextType,
  configuration?: OIDCRuntimeConfiguration,
) {
  configuration ??= await loadOIDCRuntimeConfiguration(true);
  if (
    !configuration.enabled ||
    !configuration.oidcLogin ||
    !configuration.loginUrl ||
    (contextType !== undefined && !configuration.contextTypes.includes(contextType))
  ) throw new Error('统一认证登录上下文未配置');
  const returnTo = `${window.location.pathname}${window.location.search}${window.location.hash}` || '/';
  const loginURL = new URL(identityEndpointURL(configuration.loginUrl), window.location.origin);
  loginURL.searchParams.set('returnTo', returnTo.startsWith('/') ? returnTo : '/');
  if (contextType !== undefined) loginURL.searchParams.set('contextType', contextType);
  window.location.assign(loginURL.toString());
}

export async function startOIDCLogout() {
	const configuration = await loadOIDCRuntimeConfiguration(true);
  if (!configuration.enabled || !configuration.oidcLogin || !configuration.logoutUrl) return false;
  const form = document.createElement('form');
  form.method = 'POST';
	form.action = identityEndpointURL(configuration.logoutUrl);
  form.style.display = 'none';
  document.body.appendChild(form);
  form.submit();
  return true;
}

function identityEndpointURL(path: string) {
  if (/^https:\/\//i.test(path) || /^http:\/\/(localhost|127\.0\.0\.1)(:|\/)/i.test(path)) return path;
  return `${gatewayAPIBase}/${path.replace(/^\//, '')}`;
}

export function consumeOIDCCallbackError() {
  const params = new URLSearchParams(window.location.search);
  const code = params.get('oidcError') ?? '';
  if (!code) return null;
  const rawReason = params.get('oidcErrorReason') ?? '';
  const reason = code === 'OIDC_LOGIN_INVALID' && loginTransactionFailureMessages[rawReason] ? rawReason : '';
  const rawDiagnosticId = params.get('oidcDiagnosticId') ?? '';
  const diagnosticId = /^[A-Za-z0-9_-]{6,64}$/.test(rawDiagnosticId) ? rawDiagnosticId : '';
  params.delete('oidcError');
  params.delete('oidcErrorReason');
  params.delete('oidcDiagnosticId');
  const query = params.toString();
  window.history.replaceState({}, '', `${window.location.pathname}${query ? `?${query}` : ''}${window.location.hash}`);
  const callbackError = callbackErrors[code] ?? { message: '统一认证登录失败，请重试', retryable: false };
  return {
    code,
    ...(reason ? { reason } : {}),
    ...(diagnosticId ? { diagnosticId } : {}),
    ...callbackError,
    ...(reason ? { message: loginTransactionFailureMessages[reason] } : {}),
  };
}
