import {ChangeDetectionStrategy, Component, ElementRef, HostListener, OnDestroy, computed, effect,
  input, output } from '@angular/core';
import { Button, ButtonAction } from "../button/button";

export type ModalSize = 'sm' | 'md' | 'lg' | 'xl' | 'full';

@Component({
  selector: 'modal',
  standalone: true,
  templateUrl: './modal.html',
  styleUrl: './modal.scss',
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [Button]
})
export class Modal implements OnDestroy {
  readonly open = input(false);

  readonly title = input('');
  readonly subtitle = input<string | null>(null);
  readonly submitAction = input<ButtonAction>('save');

  readonly size = input<ModalSize>('md');

  readonly showHeader = input(true);
  readonly showFooter = input(true);
  readonly showCloseButton = input(true);
  readonly showCancelButton = input(true);
  readonly showSubmitButton = input(true);

  readonly closeOnBackdrop = input(true);
  readonly closeOnEscape = input(true);

  readonly loading = input(false);
  readonly submitDisabled = input(false);

  readonly submitLabel = input('Save');
  readonly loadingLabel = input('Saving...');
  readonly cancelLabel = input('Cancel');

  readonly closed = output<void>();
  readonly submitted = output<void>();

  readonly modalSizeClass = computed(() => {
    const sizes: Record<ModalSize, string> = {
      sm: 'max-w-md',
      md: 'max-w-2xl',
      lg: 'max-w-4xl',
      xl: 'max-w-6xl',
      full: 'max-w-[96vw]'
    };

    return sizes[this.size()];
  });

  readonly modalBoxClass = computed(() => {
    return [
      'hs-overlay-open:mt-7',
      'ti-modal-box',
      'mt-0',
      'ease-out',
      'relative',
      'z-[1]',
      'pointer-events-auto',
      this.modalSizeClass()
    ].join(' ');
  });

  constructor(private readonly elementRef: ElementRef<HTMLElement>) {
    effect(() => {
      if (this.open()) {
        document.body.classList.add('overflow-hidden');

        queueMicrotask(() => {
          const dialog =
            this.elementRef.nativeElement.querySelector<HTMLElement>(
              '[role="dialog"]'
            );

          dialog?.focus();
        });
      } else {
        document.body.classList.remove('overflow-hidden');
      }
    });
  }

  @HostListener('document:keydown.escape')
  onEscape(): void {
    if (
      this.open() &&
      this.closeOnEscape() &&
      !this.loading()
    ) {
      this.close();
    }
  }

  onBackdropClick(event: MouseEvent): void {
    if (
      event.target === event.currentTarget &&
      this.closeOnBackdrop() &&
      !this.loading()
    ) {
      this.close();
    }
  }

  close(): void {
    if (this.loading()) {
      return;
    }

    this.closed.emit();
  }

  submit(): void {
    if (this.loading() || this.submitDisabled()) {
      return;
    }

    this.submitted.emit();
  }

  ngOnDestroy(): void {
    document.body.classList.remove('overflow-hidden');
  }
}
