/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import {
  forwardRef,
  AfterViewInit,
  ChangeDetectionStrategy,
  Component,
  ElementRef,
  EventEmitter,
  HostBinding,
  Input,
  NgZone,
  OnDestroy,
  Output,
  TemplateRef,
  ViewEncapsulation
} from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { combineLatest, fromEvent, BehaviorSubject, Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged, filter, map, takeUntil } from 'rxjs/operators';

import { warn } from 'ng-zorro-antd/core/logger';
import { InputBoolean } from 'ng-zorro-antd/core/util';
import { editor } from 'monaco-editor';

import { CodeEditorService } from './code-editor.service';
import { DiffEditorOptions, EditorOptions, JoinedEditorOptions, NzEditorMode } from './nz-code-editor.definitions';

// Import types from monaco editor.
import IEditor = editor.IEditor;
import IDiffEditor = editor.IDiffEditor;
import ITextModel = editor.ITextModel;

@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  selector: 'zeppelin-code-editor',
  exportAs: 'CodeEditor',
  templateUrl: './code-editor.component.html',
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => CodeEditorComponent),
      multi: true
    }
  ]
})
export class CodeEditorComponent implements OnDestroy, AfterViewInit {
  @HostBinding('class.ant-code-editor') antCodeEditor = true;
  @Input() nzEditorMode: NzEditorMode = 'normal';
  @Input() nzOriginalText = '';
  @Input() @InputBoolean() nzLoading = false;
  @Input() @InputBoolean() nzFullControl = false;
  @Input() nzToolkit?: TemplateRef<void>;

  @Input() set nzEditorOption(value: JoinedEditorOptions) {
    this.editorOption$.next(value);
  }

  @Output() readonly nzEditorInitialized = new EventEmitter<IEditor | IDiffEditor>();

  editorOptionCached: JoinedEditorOptions = {};

  private readonly el: HTMLElement;
  private destroy$ = new Subject<void>();
  private resize$ = new Subject<void>();
  private editorOption$ = new BehaviorSubject<JoinedEditorOptions>({});
  private editorInstance?: IEditor | IDiffEditor;
  private value = '';
  private modelSet = false;

  constructor(
    private nzCodeEditorService: CodeEditorService,
    private ngZone: NgZone,
    elementRef: ElementRef
  ) {
    this.el = elementRef.nativeElement;
  }

  /**
   * Initialize a monaco editor instance.
   */
  ngAfterViewInit(): void {
    this.nzCodeEditorService.requestToInit().subscribe(option => this.setup(option));
  }

  ngOnDestroy(): void {
    if (this.editorInstance) {
      this.editorInstance.dispose();
    }

    this.destroy$.next();
    this.destroy$.complete();
  }

  writeValue(value: string): void {
    this.value = value;
    this.setValue();
  }

  // eslint-disable-next-line  @typescript-eslint/no-explicit-any
  registerOnChange(fn: (value: string) => void): any {
    this.onChange = fn;
  }

  // eslint-disable-next-line  @typescript-eslint/no-explicit-any
  registerOnTouched(fn: any): void {
    this.onTouch = fn;
  }

  onChange(_value: string): void {}

  onTouch(): void {}

  layout(): void {
    this.resize$.next();
  }

  private setup(option: JoinedEditorOptions): void {
    this.editorOptionCached = option;
    this.registerOptionChanges();
    this.initMonacoEditorInstance();
    this.registerResizeChange();
    this.setValue();

    if (!this.nzFullControl) {
      this.setValueEmitter();
    }
    this.nzEditorInitialized.emit(this.editorInstance);
  }

  private registerOptionChanges(): void {
    combineLatest([this.editorOption$, this.nzCodeEditorService.option$])
      .pipe(takeUntil(this.destroy$))
      .subscribe(([selfOpt, defaultOpt]) => {
        this.editorOptionCached = {
          ...this.editorOptionCached,
          ...defaultOpt,
          ...selfOpt
        };
        this.updateOptionToMonaco();
      });
  }

  private initMonacoEditorInstance(): void {
    this.ngZone.runOutsideAngular(() => {
      this.editorInstance =
        this.nzEditorMode === 'normal'
          ? editor.create(this.el, { ...this.editorOptionCached })
          : editor.createDiffEditor(this.el, {
              ...(this.editorOptionCached as DiffEditorOptions)
            });
    });
  }

  private registerResizeChange(): void {
    this.ngZone.runOutsideAngular(() => {
      fromEvent(window, 'resize')
        .pipe(debounceTime(300), takeUntil(this.destroy$))
        .subscribe(() => {
          this.layout();
        });

      this.resize$
        .pipe(
          takeUntil(this.destroy$),
          filter(() => !!this.editorInstance),
          map(() => ({
            width: this.el.clientWidth,
            height: this.el.clientHeight
          })),
          distinctUntilChanged((a, b) => a.width === b.width && a.height === b.height),
          debounceTime(50)
        )
        .subscribe(() => {
          this.editorInstance?.layout();
        });
    });
  }

  private setValue(): void {
    if (!this.editorInstance) {
      return;
    }

    if (this.nzFullControl && this.value) {
      warn(`should not set value when you are using full control mode! It would result in ambiguous data flow!`);
      return;
    }

    if (this.nzEditorMode === 'normal') {
      if (this.modelSet) {
        (this.editorInstance.getModel() as ITextModel).setValue(this.value);
      } else {
        (this.editorInstance as IEditor).setModel(
          editor.createModel(this.value, (this.editorOptionCached as EditorOptions).language)
        );
        this.modelSet = true;
      }
    } else {
      if (this.modelSet) {
        const model = (this.editorInstance as IDiffEditor).getModel()!;
        model.modified.setValue(this.value);
        model.original.setValue(this.nzOriginalText);
      } else {
        const language = (this.editorOptionCached as EditorOptions).language;
        (this.editorInstance as IDiffEditor).setModel({
          original: editor.createModel(this.value, language),
          modified: editor.createModel(this.nzOriginalText, language)
        });
      }
    }
  }

  private setValueEmitter(): void {
    const model = (
      this.nzEditorMode === 'normal'
        ? (this.editorInstance as IEditor).getModel()
        : (this.editorInstance as IDiffEditor).getModel()!.modified
    ) as ITextModel;

    model.onDidChangeContent(() => {
      this.emitValue(model.getValue());
    });
  }

  private emitValue(value: string): void {
    this.value = value;
    this.onChange(value);
  }

  private updateOptionToMonaco(): void {
    if (this.editorInstance) {
      this.editorInstance.updateOptions({ ...this.editorOptionCached });
    }
  }
}
