import { AfterViewInit, Component, ElementRef, forwardRef, Input, OnDestroy, ViewChild } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import Editor from '@toast-ui/editor';
@Component({
  selector: 'rbj-md-editor',
  standalone: true,
  imports: [],
  templateUrl: './rbj-md-editor.component.html',
  styleUrl: './rbj-md-editor.component.scss',
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => RbjMdEditorComponent),
      multi: true,
    },
  ],
})
export class RbjMdEditorComponent implements AfterViewInit, OnDestroy {
  @ViewChild('host', { static: true }) host!: ElementRef<HTMLDivElement>;

  /** Choose the starting mode (user can still toggle with UI if you add your own buttons) */
  @Input() initialEditType: 'wysiwyg' | 'markdown' = 'wysiwyg';
  @Input() height = '400px';

  private editor?: Editor;
  private _value = '';
  private _disabled = false;

  private onChange: (val: string) => void = () => { };
  private onTouched: () => void = () => { };

  ngAfterViewInit(): void {
    this.editor = new Editor({
      el: this.host.nativeElement,
      height: this.height,
      initialEditType: this.initialEditType,
      previewStyle: 'vertical',
      initialValue: this._value ?? '',
      usageStatistics: false,
    });

    // Toast UI emits "change"
    this.editor.on('change', () => {
      const md = this.editor?.getMarkdown() ?? '';
      this._value = md;
      this.onChange(md);
      this.onTouched();
    });

    this.applyDisabled();
  }

  ngOnDestroy(): void {
    this.editor?.destroy();
  }

  // ---- ControlValueAccessor ----
  writeValue(value: string | null): void {
    this._value = value ?? '';
    if (this.editor) {
      // Avoid resetting cursor unless value really changed
      const current = this.editor.getMarkdown();
      if (current !== this._value) {
        this.editor.setMarkdown(this._value, false);
      }
    }
  }

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

  registerOnTouched(fn: () => void): void {
    this.onTouched = fn;
  }

  setDisabledState(isDisabled: boolean): void {
    this._disabled = isDisabled;
    this.applyDisabled();
  }

  private applyDisabled(): void {
    if (!this.editor) return;

    // Toast UI doesn't have a perfect universal "disable" API across all versions;
    // simplest is to toggle contenteditable.
    const root = this.host.nativeElement;
    root.querySelectorAll('[contenteditable]').forEach((el) => {
      (el as HTMLElement).setAttribute('contenteditable', (!this._disabled).toString());
    });

    // Also block pointer events for toolbar etc.
    root.style.pointerEvents = this._disabled ? 'none' : 'auto';
    root.style.opacity = this._disabled ? '0.7' : '1';
  }
}