import {
  ChangeDetectionStrategy,
  Component,
  ComponentRef,
  EventEmitter,
  inject,
  Output,
  TemplateRef,
  ViewChild,
  ViewContainerRef
} from '@angular/core';
import { take } from 'rxjs';
import { ButtonComponent, ToastComponent, ToastService } from '../../public-api';

@Component({
  selector: 'nj-toast-ex',
  template: `
    <nj-toast
      toastId="toast-1"
      [hasCloseIcon]="true"
      [shouldDismiss]="true"
      iconName="check"
      (closed)="closed.emit($event)"
      (dismissed)="dismissed.emit()"
    >
      <span>Toast Component ex Title</span>
      <ng-container njToastBody> Toast body</ng-container>
    </nj-toast>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
  standalone: true,
  imports: [ToastComponent]
})
export class ToastExComponent {
  // Either use ViewChild to gain access to toast events
  @ViewChild(ToastComponent, { read: ToastComponent }) toast: ToastComponent;

  // Or Mirror toast events to be able to listen to them
  @Output() closed = new EventEmitter<Event>();

  @Output() dismissed = new EventEmitter<void>();
}

@Component({
  selector: 'nj-toast-service-example',
  styles: [':host {display: flex; gap: 16px}'],
  template: `
    <nj-button (buttonClick)="openToast(toastToOpen)">Open Toast</nj-button>
    <ng-template #toastToOpen>
      <nj-toast
        [toastId]="toastId"
        [hasCloseIcon]="hasCloseIcon"
        [shouldDismiss]="shouldDismiss"
        [iconName]="iconName"
        (closed)="onToastClose($event)"
        (dismissed)="onToastDismiss()"
      >
        Toast Title
        <ng-container njToastBody> Toast body</ng-container>
      </nj-toast>
    </ng-template>

    <nj-button emphasis="subtle" (buttonClick)="openComponentToast()">Open Component toast </nj-button>

    <nj-button variant="secondary" (buttonClick)="toggleFullWidth()">Toggle Full Width </nj-button>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
  standalone: true,
  imports: [ToastComponent, ButtonComponent, ToastExComponent]
})
export class ToastServiceStoryComponent extends ToastComponent {
  isFullWidth = false;

  private viewContainerRef = inject(ViewContainerRef);
  private toastService = inject(ToastService);

  openToast(toast: TemplateRef<any>) {
    this.toastService.open(toast, { viewContainerRef: this.viewContainerRef });
  }

  openComponentToast() {
    const toastRef: ComponentRef<ToastExComponent> = this.toastService.open(ToastExComponent, {
      viewContainerRef: this.viewContainerRef
    });

    // If mirroring events in component
    toastRef.instance.closed.pipe(take(1)).subscribe((ev) => {
      this.onToastClose(ev);
    });

    toastRef.instance.dismissed.pipe(take(1)).subscribe(() => {
      this.onToastDismiss();
    });

    // If using viewChild, we need to wrap in setTimeout to make sure Custom component is already rendered,
    // and we have access to child ToastComponent
    setTimeout(() => {
      const toastComponent = toastRef.instance.toast;
      if (toastComponent) {
        toastComponent.closed.pipe(take(1)).subscribe((ev) => {
          this.onToastClose(ev);
        });

        toastComponent.dismissed.pipe(take(1)).subscribe(() => {
          this.onToastDismiss();
        });
      }
    });
  }

  onToastClose(event: Event) {
    console.warn('Do Action on toast close');
  }

  onToastDismiss() {
    console.warn('Do Action on toast dismiss');
  }

  toggleFullWidth() {
    this.isFullWidth = !this.isFullWidth;
    this.toastService.setConfig({ isContainerFullWidth: this.isFullWidth });
  }
}
