import * as util from '../utils/util';
import { AfterViewInit, ChangeDetectionStrategy, Component, computed, input, output, ViewChild } from "@angular/core";
import { FAST_KENDO_COMMON } from "../../app.config";
import { ChunkSettings, ErrorEvent, FileRestrictions, SuccessEvent, UploadEvent, SelectEvent } from "@progress/kendo-angular-upload";
import { SVGIconComponent } from '@progress/kendo-angular-icons';

@Component({
  selector: 'fast-upload',
  changeDetection: ChangeDetectionStrategy.OnPush,
  standalone: true,
  imports: [FAST_KENDO_COMMON],
  template: `
  <kendo-upload
    [chunkable]="chunkable()"
    [saveUrl]="saveUrl()"
    [saveField]="saveField()"
    [autoUpload]="autoUpload()"
    [multiple]="multiple()"
    [restrictions]="restrictions()"
    [showFileList]="showFileList()"
    (upload)="upload.emit($event)"
    (success)="success.emit($event)"
    (complete)="complete.emit($event)"
    (error)="errorEvent.emit($event)"
    (select)="selectEvent.emit($event)"
    [class]="conditionalClasses()"
    >
  <kendo-upload-messages [select]="importText()">
    <kendo-svg-icon #excelIconElem [icon]="icons.fileExcelIcon"></kendo-svg-icon>
  </kendo-upload-messages>
  <ng-content></ng-content>
  </kendo-upload>
  `
})

export class FastUploadComponent implements AfterViewInit {
  util = util;
  icons = util.icons;

  @ViewChild('excelIconElem') excelIconElem: SVGIconComponent;

  showDropZone = input<boolean>(true);
  chunkable = input<boolean | ChunkSettings>(false);
  saveUrl = input<string>("");
  saveField = input<string>();
  autoUpload = input<boolean>(true);
  multiple = input<boolean>(true);
  restrictions = input<FileRestrictions>();
  showFileList = input<boolean>(false);
  upload = output<UploadEvent>();
  errorEvent = output<ErrorEvent>();
  selectEvent = output<SelectEvent>();
  importText = input<string>('Import');
  success = output<SuccessEvent>();
  complete = output<unknown>();

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

    classes.push(...this.getCommonClasses());
    classes.push(...this.getLightBaseClasses());
    classes.push(...this.getDarkBaseClasses());
    classes.push(...this.getLightActiveClasses());
    classes.push(...this.getDarkActiveClasses());

    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;
  }

  // make sure to put classes totally separately, otherwise it will not work (i.e. "flex flex-col h-full" will not work, but "flex" "flex-col" "h-full" will work)
  getCommonClasses() {
    const classes: string[] = [];
    classes.push(
      "items-center",
      "[&_.k-widget.k-upload.k-header]:bg-none",
      "[&_.k-widget.k-upload.k-header]:border-none",
      "[&_button]:flex",
      "[&_button]:flex-grow",
      "[&_button]:m-0",
      "[&_button]:h-7.5",
      "[&_button]:w-28",
      "[&_button]:text-sm",
      "[&_button]:leading-0",
      "[&_button]:border-solid",
      "[&_button]:border-1",
      "[&_button]:rounded-sm",
      "[&_button]:px-2",
      "[&_button]:pb-1",
      "[&_button]:gap-1",
      "[&_button]:items-center",
      "[&_button]:justify-center",
      "[&_button]:cursor-pointer",
    );
    if (!this.showDropZone()) {
      classes.push(
        "[&_.k-dropzone]:p-0",
        "[&_.k-dropzone-hint]:hidden",
        "[&_.ng-star-inserted]:hidden",
        "[&_.k-upload-files]:hidden",
        "[&_.k-upload-status]:hidden",
      );
    }
    return classes;
  }
  getLightBaseClasses() {
    return [
      "[&_button]:text-base-black-1000",
      "[&_button]:bg-gradient-to-b",
      "[&_button]:from-base-white-250",
      "[&_button]:via-base-blue-250",
      "[&_button]:to-base-blue-250",
      "[&_button]:border-base-gray-1000",
      "[&_button]:hover:text-alt-blue-250",
      "[&_button]:hover:border-alt-blue-250",
    ];
  }

  getDarkBaseClasses() {
    return [
      "dark:[&_button]:text-base-white-500",
      "dark:[&_button]:bg-gradient-to-b",
      "dark:[&_button]:from-alt-blue-250",
      "dark:[&_button]:via-alt-gray-1000",
      "dark:[&_button]:to-alt-blue-750",
      "dark:[&_button]:border-alt-white-1000",
      "dark:[&_button]:hover:text-base-blue-250",
      "dark:[&_button]:hover:border-base-blue-250",
    ];
  }

  getLightActiveClasses() {
    return [
      "[&_button]:active:bg-gradient-to-b",
      "[&_button]:active:from-base-blue-250",
      "[&_button]:active:via-base-blue-250",
      "[&_button]:active:to-base-white-250"
    ];
  }

  getDarkActiveClasses() {
    return [
      "dark:[&_button]:active:bg-gradient-to-b",
      "dark:[&_button]:active:from-alt-blue-750",
      "dark:[&_button]:active:via-alt-gray-1000",
      "dark:[&_button]:active:to-alt-blue-250"
    ];
  }

  ngAfterViewInit(): void {
    this.setImportIcon();
  }

  setImportIcon() {
    setTimeout(() => {
      const originalSpan = document.querySelector('.k-upload-button span');
      const newElem = this.excelIconElem.element.nativeElement as HTMLElement;
      newElem.hidden = false;
      originalSpan.replaceWith(newElem);
      newElem.after(this.importText());
    }, 100);
  }
}
