/**
 * Which navigation entry the page you are on belongs to.
 *
 * Pure, with nothing under it, because the sidebar is a client component and
 * the rule it needs is a string comparison rather than a query. Tested here so
 * the answer can be argued with without opening a browser.
 *
 * **Longest match wins, and that is the whole design.** Two entries point into
 * the same branch of the tree: `/tasks` is My tasks and `/tasks/new` is Create
 * and assign, or My recurring to-dos for a staff member. A rule that took the
 * first entry whose url is a prefix would light up My tasks while somebody is
 * writing a duty. Taking the longest match settles it without either entry
 * having to know the other exists.
 *
 * A single task page, `/tasks/<id>`, belongs to My tasks: there is no entry of
 * its own for it and it is where the list sends you.
 */

/**
 * A `#` is an entry for a screen that does not exist yet. It is never the
 * answer, and it must not be, because `"#"` is a prefix of nothing and would
 * otherwise match by accident the day somebody writes a looser comparison.
 */
const NOT_A_SCREEN = "#"

export function activeUrl(
  pathname: string,
  urls: readonly string[],
): string | null {
  let best: string | null = null

  for (const url of urls) {
    if (url === NOT_A_SCREEN) continue
    /*
      Either the page itself, or something below it. The trailing slash is what
      stops `/team` from claiming `/teamwork`: without it the comparison is a
      string prefix and not a path prefix, and the two stop agreeing the day
      somebody adds a route whose name begins with another one.
    */
    const matches = pathname === url || pathname.startsWith(`${url}/`)
    if (!matches) continue
    if (best === null || url.length > best.length) best = url
  }

  return best
}
