import type { Request } from 'express';
import { firstValueFrom } from 'rxjs';
import { CoreGrpcService } from '../core-grpc.service';
import {
  resolveFrontendUrl,
  resolveOAuthIssuer,
  resolveProjectDomainApiUrl,
  resolveProjectDomainFrontendUrl
} from './oauth-issuer';
import {
  isLocalDevBaseUrl,
  isValidFedcmEndpointUrl,
  normalizePublicBaseUrl,
  pickBestPublicBase,
  resolveFedcmWebIdentityOrigin
} from './public-url';

export interface FedcmEndpoints {
  issuer: string;
  frontendUrl: string;
  projectName: string;
  configUrl: string;
  accountsEndpoint: string;
  clientMetadataEndpoint: string;
  idAssertionEndpoint: string;
  loginUrl: string;
  signupUrl: string;
  webIdentityUrl: string;
}

function buildFedcmEndpointUrls(issuer: string, frontendUrl: string) {
  const base = normalizePublicBaseUrl(issuer);
  const front = normalizePublicBaseUrl(frontendUrl);
  const webIdentityOrigin = resolveFedcmWebIdentityOrigin(base, front);

  return {
    configUrl: `${base}/fedcm/config.json`,
    accountsEndpoint: `${base}/fedcm/accounts`,
    clientMetadataEndpoint: `${base}/fedcm/client_metadata`,
    idAssertionEndpoint: `${base}/fedcm/id_assertion`,
    // FedCM: login_url MUST be same-origin with config.json (W3C FedCM / Chrome).
    // На split-domain UI проксируется через nginx: api.idpmvk.lpr/auth/login → frontend.
    loginUrl: `${base}/auth/login?fedcm=1`,
    signupUrl: `${front}/auth/register`,
    webIdentityUrl: `${webIdentityOrigin}/.well-known/web-identity`
  };
}

async function resolveCanonicalFedcmIssuer(core: CoreGrpcService): Promise<string> {
  const stored = await resolveOAuthIssuer(core);
  const fromProject = await resolveProjectDomainApiUrl(core);
  const issuer = pickBestPublicBase(
    [stored, fromProject],
    stored
  );
  if (isValidFedcmEndpointUrl(issuer)) {
    return issuer;
  }
  if (fromProject && isValidFedcmEndpointUrl(fromProject)) {
    return fromProject;
  }
  return issuer;
}

async function resolveCanonicalFedcmFrontend(core: CoreGrpcService): Promise<string> {
  const stored = await resolveFrontendUrl(core);
  const fromProject = await resolveProjectDomainFrontendUrl(core);
  const frontend = pickBestPublicBase(
    [stored, fromProject],
    stored
  );
  if (isValidFedcmEndpointUrl(frontend) && !isLocalDevBaseUrl(frontend)) {
    return frontend;
  }
  if (fromProject && isValidFedcmEndpointUrl(fromProject)) {
    return fromProject;
  }
  return frontend;
}

export async function resolveFedcmEndpoints(core: CoreGrpcService, _req?: Request): Promise<FedcmEndpoints> {
  // FedCM: web-identity (idpmvk.lpr) и config.json (api.idpmvk.lpr) ОБЯЗАНЫ
  // возвращать одинаковые login_url / accounts_endpoint / configUrl.
  // Хост запроса разный — никогда не выводим URL из req.headers.host.
  const issuer = await resolveCanonicalFedcmIssuer(core);
  const frontendUrl = await resolveCanonicalFedcmFrontend(core);
  let projectName = 'MVK ID';

  try {
    const setting = (await firstValueFrom(core.settings.GetSetting({ key: 'PROJECT_NAME' }))) as { value?: string };
    if (setting.value?.trim()) {
      projectName = setting.value.trim();
    }
  } catch {
    // fallback
  }

  return {
    issuer,
    frontendUrl,
    projectName,
    ...buildFedcmEndpointUrls(issuer, frontendUrl)
  };
}

export function buildFedcmProviderConfig(endpoints: FedcmEndpoints) {
  const base = normalizePublicBaseUrl(endpoints.issuer);
  const front = normalizePublicBaseUrl(endpoints.frontendUrl);
  return {
    accounts_endpoint: `${base}/fedcm/accounts`,
    client_metadata_endpoint: `${base}/fedcm/client_metadata`,
    id_assertion_endpoint: `${base}/fedcm/id_assertion`,
    login_url: endpoints.loginUrl,
    branding: {
      name: endpoints.projectName,
      background_color: '#ffffff',
      color: '#1f2430',
      icons: [
        { url: `${front}/icon.svg`, size: 40 },
        { url: `${base}/favicon.ico`, size: 32 }
      ]
    }
  };
}

export function buildFedcmWebIdentityManifest(endpoints: FedcmEndpoints) {
  return {
    provider_urls: [endpoints.configUrl],
    accounts_endpoint: endpoints.accountsEndpoint,
    login_url: endpoints.loginUrl
  };
}

export function buildFedcmDiscoverPayload(endpoints: FedcmEndpoints, enabled = true) {
  return {
    enabled,
    apiBase: endpoints.issuer,
    frontendUrl: endpoints.frontendUrl,
    projectName: endpoints.projectName,
    configUrl: endpoints.configUrl,
    webIdentityUrl: endpoints.webIdentityUrl,
    accountsEndpoint: endpoints.accountsEndpoint,
    loginUrl: endpoints.loginUrl,
    // Поля для navigator.credentials.get({ identity: { fields: [...] } }) на стороне RP (Chrome 132+).
    suggestedFields: ['name', 'email', 'picture', 'tel']
  };
}

async function readOneTapEnabled(core: CoreGrpcService): Promise<boolean> {
  try {
    const setting = (await firstValueFrom(core.settings.GetSetting({ key: 'ONE_TAP_ENABLED' }))) as { value?: string };
    const raw = setting.value?.trim().toLowerCase();
    if (!raw) return true;
    return ['true', '1', 'yes'].includes(raw);
  } catch {
    return true;
  }
}

export { readOneTapEnabled };
