import { AfterViewInit, ChangeDetectionStrategy, Component, computed, ElementRef, HostBinding, inject, input, output, signal, ViewChild } from '@angular/core';
import * as util from '../utils/util';
import { FAST_KENDO_COMMON } from '../../app.config';
import { FastOverlayComponent } from "./fast-overlay.component";
import { WinHeightPipe } from "../pipes/win-height.pipe";
import { WinWidthPipe } from "../pipes/win-width.pipe";
import { NotifyService } from '../services/notify.service';
import { FastButtonComponent } from "./fast-button.component";

type WindowType = 'basic' | 'error' | 'info';

@Component({
  selector: 'fast-window',
  imports: [FAST_KENDO_COMMON, FastOverlayComponent, WinHeightPipe, WinWidthPipe, FastButtonComponent],
  template: `
  <fast-overlay [layerLevel]="layerLevel()"></fast-overlay>
<kendo-window class="
  bg-base-white-500
  dark:bg-alt-gray-500
  text-base-black-1000
  dark:text-base-white-500

  [&_.k-window-content]:p-0
  [&_.k-window-content]:flex
  [&_.k-window-content]:flex-col
  " [minHeight]="minHeight()" [minWidth]="minWidth()" [height]="height() | winHeight"
  [width]="width() | winWidth" (close)="close.emit()" [style]="hostStyles">
  <kendo-window-titlebar class="m-0 p-0 text-lg items-center justify-center border-none h-8.5"
      [class]="conditionalClasses()">
    <div class="flex flex-row flex-grow basis-full pl-1">
      <div class="flex flex-grow-0 items-start justify-center mt-0 mr-0 mb-0 ml-2">
        {{ title() }}
        @if(type() === 'info' || type() === 'error'){
        <fast-button class="ml-3" type="basic-no-width" (click)="copyInfo()"><kendo-svg-icon [icon]="icons.copyIcon"></kendo-svg-icon></fast-button>
        }
      </div>
      @if(hasRefresh()) {
        <fast-button class="ml-3 mr-3 w-6" type="basic-no-width" (click)="refresh.emit()"><kendo-svg-icon [icon]="icons.arrowRotateCcwIcon"></kendo-svg-icon></fast-button>
      }
      @if(hasPrint()) {
        <fast-button class="ml-3 mr-3 w-6" type="basic-no-width" (click)="print.emit()"><kendo-svg-icon [icon]="icons.printIcon"></kendo-svg-icon></fast-button>
      }
      <div class="flex flex-grow items-stretch justify-center basis-3/10 flex-col"></div>
      <div class="k-window-titlebar-actions">
        @if(type() !== 'error' && type() !== 'info' ){
        <button kendoWindowMinimizeAction></button>
        <button kendoWindowMaximizeAction></button>
        <button kendoWindowRestoreAction></button>
        }
        <button kendoWindowCloseAction></button>
      </div>
    </div>
  </kendo-window-titlebar>

  <div class="flex flex-col flex-grow overflow-hidden" #content [hidden]="type() !== 'basic'">
    <ng-content class="flex flex-col flex-grow"></ng-content>
  </div>
  @if (type() === 'error' || type() === 'info') {
    <div class="flex flex-grow items-center justify-center m-3">
      <textarea class="flex flex-col flex-grow self-center border-1" #copyInfoElem readonly rows="12" [value]="textContent()">
      </textarea>
    </div>
    <fast-button type="basic-no-width" (click)="close.emit()">OK</fast-button>
  }
</kendo-window>
  `,
  styles: `:host
  {
    @apply
    absolute
    w-full
    h-full
  }`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class FastWindowComponent implements AfterViewInit {
  @ViewChild('content') content: ElementRef;
  @ViewChild("copyInfoElem") copyInfoElem: ElementRef;

  util = util;
  icons = util.icons;

  notify = inject(NotifyService);

  type = input<WindowType>('basic');
  layerLevel = input<number>(1);
  minHeight = input<number>(350);
  minWidth = input<number>(600);
  height = input<number>(0);
  width = input<number>(0);
  title = input<string>('');
  textContent = signal<string>('');
  refresh = output();
  print = output();
  hasRefresh = util.hasOutputListener(this.refresh);
  hasPrint = util.hasOutputListener(this.print);

  // eslint-disable-next-line @angular-eslint/no-output-native
  close = output();

  ngAfterViewInit(): void {
    this.textContent.set(this.content?.nativeElement?.textContent || '');
  }

  conditionalClasses = computed(() => {
    const classes = [] as string[];

    classes.push(...this.getLightBaseClasses(this.type()));
    classes.push(...this.getDarkBaseClasses(this.type()));

    const conditionalClasses = this.getConditionalClassesFromArrays(classes);
    return conditionalClasses;
  });



  getConditionalClassesFromArrays(classArray: string[]): { [key: string]: boolean } {
    const classes: { [key: string]: boolean } = {};
    classArray.forEach(className => {
      classes[className] = true;
    });
    return classes;
  }

  getLightBaseClasses(type: WindowType) {
    if (type == 'basic' || type == 'info')
      return ["bg-gradient-to-b", "from-base-white-1000", "via-base-white-1000", "to-base-white-250"];

    if (type == 'error')
      return ["bg-gradient-to-b", "from-base-red-1000", "via-base-red-250", "to-base-white-250"];

  }

  getDarkBaseClasses(type: WindowType) {
    if (type == 'basic' || type == 'info')
      return ["dark:bg-gradient-to-b", "dark:from-alt-gray-1000", "dark:via-alt-gray-1000", "dark:to-alt-gray-500"];

    if (type == 'error')
      return ["dark:bg-gradient-to-b", "dark:from-alt-red-1000", "dark:via-alt-red-250", "dark:to-alt-blue-750"];
  }

  async copyInfo() {
    this.copyInfoElem.nativeElement.select();
    const selection = window.getSelection()?.toString();
    if (selection)
      await navigator.clipboard.writeText(selection);
    this.notify.show('copied', 'success', false, 'top');
  }

  @HostBinding('style') get hostStyles() {
    let zIndex: number;
    switch (this.layerLevel()) {
      case 1: zIndex = 10002; break;
      case 2: zIndex = 11002; break;
      default: zIndex = 11002 + (2 * (this.layerLevel() - 2)); break;
      // default case results in the following pattern:
      // case 3 = 11002 + (2 * (3-2)) = 11004
      // case 4 = 11002 + (2 * (4-2)) = 11006
      // case 5 = 11002 + (2 * (5-2)) = 11008
    };

    return {
      'z-index': zIndex
    };
  }
}
