import { Component, OnInit, inject, signal } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { DatePipe } from '@angular/common';
import { marked, Renderer } from 'marked';
import { createHighlighter, Highlighter } from 'shiki';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { BlogService } from '@core/services/blog.service';
import { SeoService } from '@core/services/seo.service';
import { OpenPanelService } from '@core/services/openpanel.service';
import { BlogPost } from '@core/models/blog-posts.model';
import { BlogNavComponent } from '../../components/blog-nav/blog-nav.component';

const SHIKI_LANGS = ['html', 'css', 'scss', 'javascript', 'typescript', 'sql', 'python'] as const;
const SHIKI_THEME = 'ayu-light';

@Component({
  selector: 'app-blog-detail',
  imports: [DatePipe, BlogNavComponent],
  templateUrl: './blog-detail.component.html',
  styleUrl: './blog-detail.component.scss',
})
export class BlogDetailComponent implements OnInit {
  private readonly route = inject(ActivatedRoute);
  private readonly blogService = inject(BlogService);
  private readonly seo = inject(SeoService);
  private readonly op = inject(OpenPanelService);
  private readonly sanitizer = inject(DomSanitizer);

  post = signal<BlogPost | null>(null);
  loading = signal(true);
  notFound = signal(false);
  parsedContent = signal<SafeHtml>('');

  private highlighter: Highlighter | null = null;

  private async getHighlighter(): Promise<Highlighter> {
    if (!this.highlighter) {
      this.highlighter = await createHighlighter({
        themes: [SHIKI_THEME],
        langs: [...SHIKI_LANGS],
      });
    }
    return this.highlighter;
  }

  private async parseContent(content: string): Promise<SafeHtml> {
    const highlighter = await this.getHighlighter();
    const loadedLangs = highlighter.getLoadedLanguages();

    const renderer = new Renderer();
    renderer.code = ({ text, lang }) => {
      const language = lang && loadedLangs.includes(lang as any) ? lang : 'text';
      return highlighter.codeToHtml(text, { lang: language, theme: SHIKI_THEME });
    };

    marked.use({ renderer });
    const html = await marked(content);
    return this.sanitizer.bypassSecurityTrustHtml(html);
  }

  async ngOnInit(): Promise<void> {
    const slug = this.route.snapshot.paramMap.get('slug') ?? '';

    this.blogService.getPostBySlug(slug).subscribe({
      next: async (post) => {
        if (!post) {
          this.notFound.set(true);
          this.loading.set(false);
          return;
        }
        this.post.set(post);

        if (post.content) {
          this.parsedContent.set(await this.parseContent(post.content));
        }

        this.loading.set(false);

        this.seo.updateMetadata({
          title: post.title,
          description: post.summary,
          image: post.cover_image
            ? this.blogService.getAssetUrl(post.cover_image, { width: 1200, quality: 85 })
            : undefined,
          type: 'article',
        });

        this.op.track('blog_post_view', { slug, title: post.title });
      },
      error: () => {
        this.notFound.set(true);
        this.loading.set(false);
      },
    });
  }

  getCoverUrl(post: BlogPost): string | null {
    if (!post.cover_image) return null;
    return this.blogService.getAssetUrl(post.cover_image, { width: 1200, quality: 85 });
  }
}
