import { firstValueFrom } from 'rxjs';
import { CoreGrpcService } from '../core-grpc.service';

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

export async function resolveOAuthIssuer(core: CoreGrpcService, fallback = 'http://localhost:3000'): Promise<string> {
  const envIssuer = process.env.PUBLIC_API_URL?.trim();
  try {
    const response = (await firstValueFrom(core.settings.GetSetting({ key: 'PUBLIC_API_URL' }))) as { value?: string };
    const fromDb = response.value?.trim();
    if (fromDb) {
      return normalizeBaseUrl(fromDb);
    }
  } catch {
    // fallback ниже
  }

  if (envIssuer) {
    return normalizeBaseUrl(envIssuer);
  }

  try {
    const response = (await firstValueFrom(core.settings.GetSetting({ key: 'PROJECT_DOMAIN' }))) as { value?: string };
    const domain = response.value?.trim();
    if (domain) {
      if (domain.startsWith('http://') || domain.startsWith('https://')) {
        return normalizeBaseUrl(domain);
      }
      return `https://${domain.replace(/^\/+/, '')}`;
    }
  } catch {
    // fallback ниже
  }

  return normalizeBaseUrl(fallback);
}

export async function resolveFrontendUrl(core: CoreGrpcService, fallback = 'http://localhost:3002'): Promise<string> {
  const envFrontend = process.env.PUBLIC_FRONTEND_URL?.trim();
  if (envFrontend) {
    return normalizeBaseUrl(envFrontend);
  }

  try {
    const response = (await firstValueFrom(core.settings.GetSetting({ key: 'PUBLIC_FRONTEND_URL' }))) as { value?: string };
    const fromDb = response.value?.trim();
    if (fromDb) {
      return normalizeBaseUrl(fromDb);
    }
  } catch {
    // fallback ниже
  }

  try {
    const response = (await firstValueFrom(core.settings.GetSetting({ key: 'PROJECT_DOMAIN' }))) as { value?: string };
    const domain = response.value?.trim();
    if (domain) {
      if (domain.startsWith('http://') || domain.startsWith('https://')) {
        return normalizeBaseUrl(domain);
      }
      return `https://${domain.replace(/^\/+/, '')}`;
    }
  } catch {
    // fallback ниже
  }

  return normalizeBaseUrl(fallback);
}

export function buildOpenIdConfiguration(issuer: string) {
  const base = normalizeBaseUrl(issuer);
  return {
    issuer: base,
    authorization_endpoint: `${base}/oauth/authorize`,
    token_endpoint: `${base}/oauth/token`,
    userinfo_endpoint: `${base}/oauth/userinfo`,
    jwks_uri: `${base}/.well-known/jwks.json`,
    response_types_supported: ['code'],
    subject_types_supported: ['public'],
    id_token_signing_alg_values_supported: ['HS256'],
    scopes_supported: ['openid', 'profile', 'email', 'phone', 'address', 'documents'],
    token_endpoint_auth_methods_supported: ['client_secret_post', 'client_secret_basic'],
    grant_types_supported: ['authorization_code', 'refresh_token'],
    code_challenge_methods_supported: ['S256', 'plain'],
    claims_supported: [
      'sub',
      'iss',
      'aud',
      'iat',
      'exp',
      'auth_time',
      'nonce',
      'email',
      'email_verified',
      'phone_number',
      'phone_number_verified',
      'name',
      'preferred_username',
      'picture'
    ]
  };
}
