import {CommonModule} from '@angular/common';
import {Component, Input, Optional} from '@angular/core';
import {MiniMessageComponent as MiniMessageNode, ResolvedStyle} from '../../mini-message/mini-message.types';
import {hoverEventToTitle, mergeStyle, ownText, styleToNgStyle} from '../../mini-message/mini-message.util';
import {ObfuscatedDirective} from '../../mini-message/obfuscated.directive';
import {MiniMessageInteractionService} from '../../mini-message/mini-message-interaction.service';

/**
 * Renders a Paper/Adventure component-JSON tree as styled HTML.
 *
 * Usage:
 *   providers: [MiniMessageInteractionService]   // once, at the root that hosts <mini-message>
 *   <mini-message [node]="myComponentJson"></mini-message>
 *
 * Then subscribe to click events (run_command / suggest_command / copy_to_clipboard /
 * change_page) via the injected MiniMessageInteractionService.clicks$; open_url is handled
 * natively as a real link so no subscription is needed for that case.
 */
@Component({
  selector: 'mini-message',
  standalone: true,
  imports: [CommonModule, ObfuscatedDirective],
  templateUrl: './mini-message.component.html',
  styleUrl: './mini-message.component.scss',
})
export class MiniMessageComponent {
  @Input() node!: MiniMessageNode;
  @Input() parentStyle?: ResolvedStyle;

  constructor(@Optional() private readonly interaction: MiniMessageInteractionService | null) {
  }

  get style(): ResolvedStyle {
    return mergeStyle(this.parentStyle, this.node);
  }

  get ngStyle(): Record<string, string> {
    return styleToNgStyle(this.style);
  }

  get text(): string {
    return ownText(this.node);
  }

  get hoverTitle(): string | null {
    return hoverEventToTitle(this.node.hoverEvent);
  }

  get isUrlLink(): boolean {
    return this.node.clickEvent?.action === 'open_url';
  }

  get hasNonUrlClick(): boolean {
    return !!this.node.clickEvent && this.node.clickEvent.action !== 'open_url';
  }

  onClick(): void {
    const click = this.node.clickEvent;
    if (!click) return;

    if (click.action === 'copy_to_clipboard') {
      navigator.clipboard?.writeText(click.value);
    }

    this.interaction?.emitClick({action: click.action, value: click.value});
  }
}
