/**
 * Resolvers para iam/account. Cargan en paralelo las relaciones necesarias
 * para el form combinado: tenants, roles, tags, clients y langs (estas
 * últimas vía el adapter upstream `coreGetLangs` que sirve un JSON estático).
 *
 * Overrides codegen scaffold — see excludedFiles en cliter/iam/account.aurora.yaml.
 */
import { inject } from '@angular/core';
import { type ResolveFn } from '@angular/router';
import {
  buildSortOrder,
  DEFAULT_PAGE_SIZE,
  getRelationIncludes,
  LangService,
  queryFindById,
  queryPaginate,
  type DataTableData,
} from '@aurora';
import {
  type CoreLang,
  type IamAccount,
  type IamRole,
  type IamTag,
  type IamTenant,
  type OAuthClient,
} from '@src/src/app/aurora.types';
import { forkJoin, from, map } from 'rxjs';
import { CLIENT_LIST_CONFIG } from '../../../o-auth/client/data-access/client.list-config';
import { ROLE_LIST_CONFIG } from '../../role/data-access/role.list-config';
import { TAG_LIST_CONFIG } from '../../tag/data-access/tag.list-config';
import { TENANT_LIST_CONFIG } from '../../tenant/data-access/tenant.list-config';
import { getAccountStandaloneColumns } from '../account.columns';
import { ACCOUNT_DETAIL_CONFIG } from './account.detail-config';
import { ACCOUNT_LIST_CONFIG } from './account.list-config';

const optionList$ = <T>(config: {
  queryPagination: unknown;
  paginationKey: string;
  fields: string;
}) =>
  queryPaginate<T>(config.queryPagination as never, config.paginationKey, config.fields, {
    query: { offset: 0, limit: 1000, order: buildSortOrder([]) },
  }).pipe(map((data) => data.rows));

/**
 * Delegates to the shared `LangService` (singleton, providedIn: 'root') so
 * the resolver and the site-header language switcher consume the same
 * fetched list — single source of truth + zero duplicate requests.
 */
const langOptions$ = () => {
  const langService = inject(LangService);
  return from(langService.load()).pipe(map(() => langService.active()));
};

export const accountListResolver: ResolveFn<{
  pagination: DataTableData<IamAccount>;
  tenantOptions: IamTenant[];
}> = () => {
  const { queryPagination, paginationKey, fields } = ACCOUNT_LIST_CONFIG;
  const include = getRelationIncludes(getAccountStandaloneColumns());
  const pagination$ = queryPaginate<IamAccount>(queryPagination, paginationKey, fields, {
    query: {
      offset: 0,
      limit: DEFAULT_PAGE_SIZE,
      order: buildSortOrder([]),
      include: include.length > 0 ? include : undefined,
    },
  });
  return forkJoin({
    pagination: pagination$,
    tenantOptions: optionList$<IamTenant>(TENANT_LIST_CONFIG),
  });
};

export const accountNewResolver: ResolveFn<{
  tenantOptions: IamTenant[];
  roleOptions: IamRole[];
  tagOptions: IamTag[];
  clientOptions: OAuthClient[];
  langOptions: CoreLang[];
}> = () =>
  forkJoin({
    tenantOptions: optionList$<IamTenant>(TENANT_LIST_CONFIG),
    roleOptions: optionList$<IamRole>(ROLE_LIST_CONFIG),
    tagOptions: optionList$<IamTag>(TAG_LIST_CONFIG),
    clientOptions: optionList$<OAuthClient>(CLIENT_LIST_CONFIG),
    langOptions: langOptions$(),
  });

export const accountDetailResolver: ResolveFn<
  {
    item: IamAccount | null;
    tenantOptions: IamTenant[];
    roleOptions: IamRole[];
    tagOptions: IamTag[];
    clientOptions: OAuthClient[];
    langOptions: CoreLang[];
  } | null
> = (route) => {
  const id = route.paramMap.get('id');
  if (!id) return null;
  const { queryObject, objectKey, fields } = ACCOUNT_DETAIL_CONFIG;
  const item$ = queryFindById<IamAccount>(queryObject, objectKey, id, fields, {
    constraint: {
      include: [
        { association: 'user' },
        { association: 'tenants' },
        { association: 'roles' },
        { association: 'client' },
      ],
    },
  });
  return forkJoin({
    item: item$,
    tenantOptions: optionList$<IamTenant>(TENANT_LIST_CONFIG),
    roleOptions: optionList$<IamRole>(ROLE_LIST_CONFIG),
    tagOptions: optionList$<IamTag>(TAG_LIST_CONFIG),
    clientOptions: optionList$<OAuthClient>(CLIENT_LIST_CONFIG),
    langOptions: langOptions$(),
  });
};
