import { ChangeDetectorRef, Component, ElementRef, Input, Renderer2, ViewChild, forwardRef, OnDestroy, AfterViewInit } from '@angular/core';
import { DomSanitizer, SafeUrl, SafeResourceUrl } from '@angular/platform-browser';

// import { EventTarget } from '../../../../../node_modules/typescript/lib/lib.dom.d.ts';

import { ControlValueAccessor, FormControl, NG_VALIDATORS, NG_VALUE_ACCESSOR, ValidationErrors } from '@angular/forms';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';

// interface IUploadFile extends EventTarget {
//     files: Blob[];
//     result: string;
// }

@Component({
    selector: 'knk-upload-graph',
    templateUrl: './uploadgraph.component.html',
    styleUrls: ['./uploadgraph.component.scss'],
    providers: [
        {
          provide: NG_VALUE_ACCESSOR,
          useExisting: forwardRef(() => UploadGraphComponent), // forwardRef(() => UploadGraphComponent),
          multi: true
        }
        // {
        //   provide: NG_VALIDATORS,
        //   useExisting: UploadGraphComponent, // forwardRef(() => UploadGraphComponent),
        //   multi: true
        // }
      ]
})

export class UploadGraphComponent implements ControlValueAccessor, OnDestroy, AfterViewInit {
  imgGraph: string = null;
  onChange: (param: string) => void;

  // todo: is redo?!
  @Input('redo') redo: boolean = false;
  @ViewChild('imgUrl') imgUrlCtrl: ElementRef;
  @ViewChild('fileInput') fileInputCtrl: ElementRef;

  get imageExists(): boolean {
    return this.imgGraph !== null && this.imgGraph !== undefined && (typeof this.imgGraph === 'string' && this.imgGraph.length > 1);
  }

  get safeUrlImage(): SafeUrl | SafeResourceUrl | string {
    return this.sanitization.bypassSecurityTrustResourceUrl(this.imgGraph);
  }

  private ngUnsubscribe: Subject<void> = new Subject<void>();

  constructor(private changeDetector: ChangeDetectorRef,
              private renderer: Renderer2,
              private sanitization: DomSanitizer) {
  }

  ngOnDestroy(): void {
    this.ngUnsubscribe.next();
    this.ngUnsubscribe.complete();
  }

  ngAfterViewInit(): void {
    let onUrlInput: Observable<InputEvent> = Observable.fromEvent(this.imgUrlCtrl.nativeElement, 'input');
    onUrlInput.takeUntil(this.ngUnsubscribe).debounceTime(500).subscribe((event: InputEvent) => {
      if (this.onChange) {
        this.onChange(this.imgUrlCtrl.nativeElement.value);
      }
    });
  }

    writeValue(value: string): void {
        this.changeDetector.detectChanges();

        if (value) {
            this.imgGraph = value;
        }

        if (this.imgGraph && (this.imgGraph.startsWith('http://') || this.imgGraph.startsWith('https://'))) {
            this.renderer.setProperty(this.imgUrlCtrl.nativeElement, 'value', this.imgGraph);
        }
    }

    registerOnChange( fn: () => void ): void {
        this.onChange = fn;
    }

    registerOnTouched( fn: () => void ): void {
        console.log('registerOnTouched');
    }

    readUrl(event: Event): void {
        const filesProp: string = 'files';
        const resultProp: string = 'result';
        let target: {files: FileList} = Object.assign({files: event.target[filesProp]}, event.target); // as FileReader; //IUploadFile;
        if (target.files && target.files[0]) {
          let reader: FileReader = new FileReader();

          reader.onload = (evt: Event) => {
            let target2: {result: string} = Object.assign({result: evt.target[resultProp]}, evt.target); // IUploadFile = evt.target as IUploadFile;
            // fetch(target2.result).then((value: Response): void => {
            //     this.imgGraph = value.text();
            //     if (this.onChange) {
            //         this.onChange(this.imgGraph);
            //     }
            // });
            // data:image/png;
            if (target2.result && (target2.result.substr(0, 11) === 'data:image/')) {
                this.imgGraph = target2.result;
                if (this.onChange) {
                  this.onChange(this.imgGraph);
                }
            }
          };

          reader.readAsDataURL(target.files[0]);
        }
    }

    importUrl(value: string): void {
        this.imgGraph = value;
        if (this.onChange) {
            this.onChange(this.imgGraph);
        }
    }

    uploadImage(): void {
      this.imgGraph = '';
      if (!this.imgUrlCtrl.nativeElement.value) {
        this.fileInputCtrl.nativeElement.click();
        const timeout: any = setTimeout((): void => {
          this.imgUrlCtrl.nativeElement.value = '';
          clearTimeout(timeout);
        }, 10);
      } else {
        this.importUrl(this.imgUrlCtrl.nativeElement.value);
        const timeout: any = setTimeout((): void => {
          this.fileInputCtrl.nativeElement.value = '';
          clearTimeout(timeout);
        }, 10);
      }
    }

    clear(): void {
      this.imgGraph = '';
      this.imgUrlCtrl.nativeElement.value = '';
      this.fileInputCtrl.nativeElement.value = '';

      if (this.onChange) {
        this.onChange('');
      }
    }
}
