import { Injectable, inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { Title, Meta } from '@angular/platform-browser';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { filter } from 'rxjs';

const SITE_URL = 'https://andreas-dahm.eu';
const DEFAULT_SEO_KEY = 'DEFAULT';

/**
 * Keeps the document title and SEO/social meta tags in sync with the active
 * route and the selected language. Each route declares its translation key via
 * `data: { seo: 'ABOUT' }`; the matching `SEO.<key>` i18n entry provides the
 * localized title and description.
 */
@Injectable({ providedIn: 'root' })
export class SeoService {
  private readonly router = inject(Router);
  private readonly route = inject(ActivatedRoute);
  private readonly title = inject(Title);
  private readonly meta = inject(Meta);
  private readonly translate = inject(TranslateService);
  private readonly document = inject(DOCUMENT);

  private currentSeoKey = DEFAULT_SEO_KEY;

  init(): void {
    this.router.events
      .pipe(filter((event) => event instanceof NavigationEnd))
      .subscribe(() => {
        this.currentSeoKey = this.resolveSeoKey();
        this.applyTags();
      });

    // Re-translate the tags when the user switches language.
    this.translate.onLangChange.subscribe(() => this.applyTags());
  }

  private resolveSeoKey(): string {
    let active = this.route;
    while (active.firstChild) {
      active = active.firstChild;
    }
    const seoKey = active.snapshot.data['seo'];
    return typeof seoKey === 'string' ? seoKey : DEFAULT_SEO_KEY;
  }

  private applyTags(): void {
    const titleKey = `SEO.${this.currentSeoKey}.TITLE`;
    const descriptionKey = `SEO.${this.currentSeoKey}.DESCRIPTION`;

    this.translate.get([titleKey, descriptionKey]).subscribe((translations) => {
      const title = translations[titleKey];
      const description = translations[descriptionKey];
      const url = SITE_URL + this.router.url.split('?')[0];

      this.title.setTitle(title);
      this.meta.updateTag({ name: 'description', content: description });
      this.meta.updateTag({ property: 'og:title', content: title });
      this.meta.updateTag({ property: 'og:description', content: description });
      this.meta.updateTag({ property: 'og:url', content: url });
      this.meta.updateTag({ name: 'twitter:title', content: title });
      this.meta.updateTag({ name: 'twitter:description', content: description });
      this.updateCanonical(url);
    });
  }

  private updateCanonical(url: string): void {
    let link = this.document.querySelector<HTMLLinkElement>('link[rel="canonical"]');
    if (!link) {
      link = this.document.createElement('link');
      link.setAttribute('rel', 'canonical');
      this.document.head.appendChild(link);
    }
    link.setAttribute('href', url);
  }
}
