import { Injectable } from '@angular/core';

/**
 * Internal service that tracks which component is currently managing the page title.
 * This ensures that in nested component hierarchies (parent/child routes),
 * the deepest (most recently registered) component's title takes precedence.
 *
 * When a child component is destroyed, the parent component's title is automatically restored.
 *
 * @internal
 */
@Injectable({ providedIn: 'root' })
export class TitleRegistryService {
  #registrations = new Map<symbol, () => void>();
  #activeRegistration: symbol | null = null;

  /**
   * Register a new title updater. The most recently registered updater
   * becomes the active one and will control the title.
   *
   * This implements a stack-like behavior where the last component to register
   * (deepest in the component hierarchy) takes precedence.
   *
   * @param updater - Function that updates the title
   * @returns A symbol that uniquely identifies this registration
   */
  register(updater: () => void): symbol {
    const id = Symbol('title-registration');
    this.#registrations.set(id, updater);
    this.#activeRegistration = id;

    // Execute the updater immediately since it's now active
    updater();

    return id;
  }

  /**
   * Unregister a title updater. If this was the active updater,
   * the previous one (if any) becomes active and its title is restored.
   *
   * This ensures that when a child component is destroyed, the parent
   * component's title is automatically restored.
   *
   * @param id - The symbol identifying the registration to remove
   */
  unregister(id: symbol): void {
    this.#registrations.delete(id);

    // If we just unregistered the active one, activate the most recent remaining one
    if (this.#activeRegistration === id) {
      // Get the last registration (most recent)
      const entries = Array.from(this.#registrations.entries());
      if (entries.length > 0) {
        const [lastId, lastUpdater] = entries[entries.length - 1];
        this.#activeRegistration = lastId;
        // Restore the previous component's title
        lastUpdater();
      } else {
        this.#activeRegistration = null;
      }
    }
  }

  /**
   * Execute the updater only if it's the currently active registration.
   *
   * This prevents inactive (parent) components from overwriting the title
   * set by active (child) components.
   *
   * @param id - The symbol identifying the registration
   * @param updater - Function to execute if this registration is active
   */
  updateIfActive(id: symbol, updater: () => void): void {
    if (this.#activeRegistration === id) {
      updater();
    }
  }
}
