import { Injectable } from '@angular/core';
import { BootstrapConfig } from '../../shared/models/config';

export interface MediaUsageEntry {
  labelKey: string;
  detail: string;
}

const TOP_LEVEL_LABEL_KEYS: Record<string, string> = {
  branding: 'mediaLibrary.usage.brand',
  theme: 'mediaLibrary.usage.theme',
  header: 'mediaLibrary.usage.header',
  footer: 'mediaLibrary.usage.footer',
  staticPages: 'mediaLibrary.usage.staticPage',
  pages: 'mediaLibrary.usage.homepage',
  catalog: 'mediaLibrary.usage.catalog',
  productPage: 'mediaLibrary.usage.productPage',
  widgetRegistry: 'mediaLibrary.usage.widget',
  company: 'mediaLibrary.usage.company',
  seo: 'mediaLibrary.usage.seo',
  navigation: 'mediaLibrary.usage.navigation',
};

/**
 * Finds every place a media asset's URL is actually referenced inside the current
 * bootstrap config, by walking the object rather than guessing from a fixed schema.
 * Never fabricates usage - an asset with no matches is reported as unused.
 */
@Injectable({ providedIn: 'root' })
export class MediaUsageService {
  findUsages(bootstrap: BootstrapConfig | null, url: string): MediaUsageEntry[] {
    if (!bootstrap || !url) {
      return [];
    }
    const entries: MediaUsageEntry[] = [];
    for (const [topKey, value] of Object.entries(bootstrap as unknown as Record<string, unknown>)) {
      this.walk(value, url, [topKey], entries, 0);
    }
    return entries;
  }

  private walk(value: unknown, url: string, path: string[], entries: MediaUsageEntry[], depth: number): void {
    if (depth > 8 || value == null) {
      return;
    }
    if (typeof value === 'string') {
      if (value === url) {
        entries.push({
          labelKey: TOP_LEVEL_LABEL_KEYS[path[0]] ?? 'mediaLibrary.usage.other',
          detail: path.join(' › '),
        });
      }
      return;
    }
    if (Array.isArray(value)) {
      value.forEach((item, index) => this.walk(item, url, [...path, String(index)], entries, depth + 1));
      return;
    }
    if (typeof value === 'object') {
      for (const [key, nested] of Object.entries(value as Record<string, unknown>)) {
        this.walk(nested, url, [...path, key], entries, depth + 1);
      }
    }
  }
}
