import {
  DEFAULT_PUBLIC_API_URL,
  DEFAULT_PUBLIC_FRONTEND_URL,
  inferApiBaseFromProjectDomain
} from './project-domains';

export function normalizeBaseUrl(url: string) {
  return url.trim().replace(/\/+$/, '');
}

export function resolveOAuthApiBase(settings: Record<string, string>, fallback = DEFAULT_PUBLIC_API_URL) {
  const publicApi = settings.PUBLIC_API_URL?.trim();
  if (publicApi) {
    return normalizeBaseUrl(publicApi);
  }

  const domain = settings.PROJECT_DOMAIN?.trim();
  if (domain) {
    const inferred = inferApiBaseFromProjectDomain(domain);
    if (inferred) {
      return inferred;
    }

    if (domain.startsWith('http://') || domain.startsWith('https://')) {
      return normalizeBaseUrl(domain);
    }

    return `https://${domain.replace(/^\/+/, '')}/idp-api`;
  }

  return normalizeBaseUrl(fallback);
}

export function resolveFrontendBase(settings: Record<string, string>, fallback = DEFAULT_PUBLIC_FRONTEND_URL) {
  const publicFrontend = settings.PUBLIC_FRONTEND_URL?.trim();
  if (publicFrontend) {
    return normalizeBaseUrl(publicFrontend);
  }

  const domain = settings.PROJECT_DOMAIN?.trim();
  if (domain) {
    if (domain.startsWith('http://') || domain.startsWith('https://')) {
      return normalizeBaseUrl(domain);
    }
    return `https://${domain.replace(/^\/+/, '')}`;
  }

  return normalizeBaseUrl(fallback);
}

export interface OAuthEndpoints {
  issuer: string;
  authorizationEndpoint: string;
  tokenEndpoint: string;
  userInfoEndpoint: string;
  openIdConfigurationUrl: string;
  jwksUrl: string;
  webIdentityUrl: string;
  fedcmConfigUrl: string;
  fedcmDiscoverUrl: string;
  fedcmAccountsUrl: string;
  fedcmIdAssertionUrl: string;
  widgetUrl: string;
}

export function buildOAuthEndpoints(apiBase: string, frontendBase?: string): OAuthEndpoints {
  const base = normalizeBaseUrl(apiBase);
  const front = normalizeBaseUrl(frontendBase ?? deriveFrontendBaseFromApi(base));
  let webIdentityOrigin = front;

  try {
    webIdentityOrigin = new URL(base).origin;
  } catch {
    // keep frontend origin
  }

  return {
    issuer: base,
    authorizationEndpoint: `${base}/oauth/authorize`,
    tokenEndpoint: `${base}/oauth/token`,
    userInfoEndpoint: `${base}/oauth/userinfo`,
    openIdConfigurationUrl: `${base}/.well-known/openid-configuration`,
    jwksUrl: `${base}/.well-known/jwks.json`,
    webIdentityUrl: `${webIdentityOrigin}/.well-known/web-identity`,
    fedcmConfigUrl: `${base}/fedcm/config.json`,
    fedcmDiscoverUrl: `${base}/fedcm/discover.json`,
    fedcmAccountsUrl: `${base}/fedcm/accounts`,
    fedcmIdAssertionUrl: `${base}/fedcm/id_assertion`,
    widgetUrl: `${front}/sso-widget.js`
  };
}

function deriveFrontendBaseFromApi(apiBase: string) {
  if (apiBase.endsWith('/idp-api')) {
    return apiBase.replace(/\/idp-api$/, '');
  }
  return apiBase;
}

export function buildAuthorizeUrl(
  apiBase: string,
  params: { clientId: string; redirectUri: string; scope: string; userId?: string; state?: string; useStandardParams?: boolean }
) {
  const url = new URL(`${normalizeBaseUrl(apiBase)}/oauth/authorize`);
  if (params.useStandardParams ?? true) {
    url.searchParams.set('client_id', params.clientId);
    url.searchParams.set('redirect_uri', params.redirectUri);
    url.searchParams.set('response_type', 'code');
    url.searchParams.set('scope', params.scope);
    if (params.state) url.searchParams.set('state', params.state);
  } else {
    url.searchParams.set('clientId', params.clientId);
    url.searchParams.set('redirectUri', params.redirectUri);
    url.searchParams.set('scope', params.scope);
    if (params.userId) url.searchParams.set('userId', params.userId);
    if (params.state) url.searchParams.set('state', params.state);
  }
  return url.toString();
}
