import type { ResolvedSdkTarget, SdkSymbolKind } from '@mintlify/models';

import type { SdkPage, SdkPageTarget, SdkReference } from './types.js';

const KIND_DIRS: Record<SdkSymbolKind, string> = {
  class: 'classes',
  interface: 'interfaces',
  enum: 'enums',
  function: 'functions',
  type: 'types',
  variable: 'variables',
  method: 'methods',
  property: 'properties',
};

export function matchesSdkPageTarget(
  pageTarget: SdkPageTarget | undefined,
  target: Pick<ResolvedSdkTarget, 'kind' | 'name' | 'parent'>
): boolean {
  if (!pageTarget) return false;
  if (pageTarget.kind !== target.kind || pageTarget.name !== target.name) return false;
  if (target.parent) return pageTarget.parent === target.parent;
  return pageTarget.parent === undefined;
}

function matchesSdkPageHeuristic(
  page: SdkPage,
  target: Pick<ResolvedSdkTarget, 'kind' | 'name' | 'parent'>
): boolean {
  if (target.parent) {
    return (
      page.title === `${target.parent}.${target.name}` ||
      page.slug.endsWith(`/${slugify(target.parent)}/${slugify(target.name)}`)
    );
  }
  // Only slug matches encode the symbol kind; a bare title match could return
  // a same-named symbol of a different kind.
  const dir = KIND_DIRS[target.kind];
  return (
    page.slug === `${dir}/${slugify(target.name)}` ||
    page.slug.endsWith(`/${dir}/${slugify(target.name)}`)
  );
}

function slugify(name: string): string {
  return name.replace(/[^a-zA-Z0-9-_.]+/g, '-').replace(/^-+|-+$/g, '') || 'item';
}

export function findSdkPage(
  reference: SdkReference,
  target: Pick<ResolvedSdkTarget, 'kind' | 'name' | 'parent'>
): SdkPage | undefined {
  return (
    reference.pages.find((page) => matchesSdkPageTarget(page.target, target)) ??
    reference.pages.find((page) => matchesSdkPageHeuristic(page, target))
  );
}

export function renderSdkTarget(
  reference: SdkReference,
  target: Pick<ResolvedSdkTarget, 'kind' | 'name' | 'parent'>
): SdkPage {
  const page = findSdkPage(reference, target);
  if (!page) {
    const qualified = target.parent ? `${target.parent}.${target.name}` : target.name;
    throw new Error(`SDK symbol not found: ${target.kind} ${qualified}`);
  }
  return page;
}
