import { AsyncPipe } from '@angular/common';
import { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core';
import { toObservable } from '@angular/core/rxjs-interop';
import { SafeHtml } from '@angular/platform-browser';
import { TuiButton } from '@taiga-ui/core/components/button';
import { TuiLoader } from '@taiga-ui/core/components/loader';
import { TuiAccordion } from '@taiga-ui/kit/components/accordion';
import { Observable, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';

import {
  eventPayloadJson,
  isKeyboardTelemetryEvent,
  parseKeyboardHighlightKeyIds,
  parseKeyboardVirtualKey,
} from '../../../core/keyboard/keyboard-payload.util';
import { KeyboardSvgHighlightService } from '../../../core/keyboard/keyboard-svg-highlight.service';
import type { ParsedEvent } from '../../../core/models/api.types';
import { UserErrorNotifyService } from '../../../core/notifications/user-error-notify.service';
import { TelemetryEventTypePipe } from '../../../core/sessions/telemetry-event-type.pipe';
import { formatTimestamp } from '../../../shared/utils/date-time.util';

@Component({
  selector: 'app-telemetry-event-detail',
  imports: [AsyncPipe, TuiButton, TuiLoader, TelemetryEventTypePipe, ...TuiAccordion],
  templateUrl: './telemetry-event-detail.html',
  styleUrl: './telemetry-event-detail.css',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TelemetryEventDetailComponent {
  private readonly keyboardSvg = inject(KeyboardSvgHighlightService);
  private readonly userErrors = inject(UserErrorNotifyService);

  readonly event = input.required<ParsedEvent>();

  protected readonly keyboardModel = computed(() => {
    const e = this.event();
    if (!isKeyboardTelemetryEvent(e)) {
      return { kind: 'none' as const };
    }
    const keyIds = parseKeyboardHighlightKeyIds(e.data);
    const vk = parseKeyboardVirtualKey(e.data);
    return { kind: 'keyboard' as const, vk, keyIds };
  });

  protected readonly keyboardSvg$: Observable<SafeHtml | null> = toObservable(this.keyboardModel).pipe(
    switchMap((m) => (m.kind === 'keyboard' ? this.keyboardSvg.svgWithHighlight(m.keyIds) : of(null))),
  );

  protected formatTime(ms: number): string {
    return formatTimestamp(new Date(ms).toISOString());
  }

  protected payloadText(e: ParsedEvent): string {
    return eventPayloadJson(e.data);
  }

  protected async copyEventPayload(): Promise<void> {
    const text = this.payloadText(this.event());
    try {
      await navigator.clipboard.writeText(text);
      this.userErrors.notifySuccess('JSON события скопирован в буфер обмена.', 'Готово');
    } catch {
      // clipboard
    }
  }

  protected keyboardKeyIds(): string[] {
    const m = this.keyboardModel();
    return m.kind === 'keyboard' ? m.keyIds : [];
  }
}
