import { Component, ChangeDetectionStrategy, OnInit, OnDestroy, inject, input, output, computed } from '@angular/core';
import * as util from '../utils/util';
import { KENDO_WINDOW } from '@progress/kendo-angular-dialog';
import { KENDO_SVGICON } from '@progress/kendo-angular-icons';
import { FastButtonComponent } from './fast-button.component';
import { FastWindowComponent } from "./fast-window.component";
import { FastHRComponent } from "./fast-hr.component";
import { DomSanitizer } from '@angular/platform-browser';
import { QueryStringBuilder } from '../utils/queryStringBuilder';

@Component({
  selector: 'fast-frame',
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [FastButtonComponent, KENDO_WINDOW, KENDO_SVGICON, FastWindowComponent, FastHRComponent],
  styles: `
    :host { @apply absolute w-full h-full }`
  ,
  template: `
  @if(isWindow()) {
    <fast-window (close)="close()" [height]="height()" [width]="width()" [title]="title()">
        <!-- use an iframe even when you could use a component because kendo window popups inside the componenent don't position correctly otherwise -->
        <!-- this also helps with escape key handling and error encapsulation -->
        <iframe class="flex flex-grow" [src]="sanitizedSrc()"></iframe>
        @if (isCloseVisible) {
        <fast-hr />
        <div class="flex justify-end">
          <fast-button class="m-2" (click)="close()">
            <kendo-svg-icon [icon]="icons.cancelIcon"></kendo-svg-icon>Close
          </fast-button>
        </div>
        }
    </fast-window>
    }
  @else {
    <iframe class="flex flex-grow" [src]="sanitizedSrc()"></iframe>
  }
  `,
})
export class FastFrameComponent implements OnInit, OnDestroy {
  title = input<string>('');
  src = input<string>('');
  externalParams = input<unknown>(null);
  width = input<number>(1800);
  height = input<number>(0);
  isCloseVisible = input<boolean>(true);
  closed = output();
  isWindow = input<boolean>(true);

  sanitizer = inject(DomSanitizer);

  sanitizedSrc = computed(() => {
    let url = this.src();

    if (this.externalParams()) {
      const params = QueryStringBuilder.buildFromObj(this.externalParams());
      url = url + '?' + params.toString();
    }

    const safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(url);
    return safeUrl;
  });

  // this is needed so we can add and remove the same event listener correctly
  private boundHandleMessage: (event: MessageEvent) => void;

  icons = util.icons;

  ngOnInit(): void {
    // console.log('FastFrameComponent.ngOnInit()');
    this.boundHandleMessage = this.handleMessage.bind(this);
    this.addMessageEventListener();
  }

  ngOnDestroy(): void {
    // console.log('FastFrameComponent.ngOnDestroy()');
    this.removeMessageEventListener();
  }

  handleMessage(event: MessageEvent): void {
    // console.log('FastFrameComponent.handleMessage()');
    // console.log(event);
    if (event.data === 'close') {
      // console.log('FastFrameComponent:  window close message received');
      this.close();
    }
  }

  addMessageEventListener(): void {
    // console.log('FastFrameComponent.addMessageEventListener()');
    window.addEventListener('message', this.boundHandleMessage);
  }

  removeMessageEventListener(): void {
    // console.log('FastFrameComponent.removeMessageEventListener()');
    window.removeEventListener('message', this.boundHandleMessage);
  }

  close(): void {
    // console.log('FastFrameComponent.close()');
    this.closed.emit();
  }
}
