import {
  ComponentRef,
  Directive,
  Input,
  OnChanges,
  OnDestroy,
  TemplateRef,
  ViewContainerRef,
} from '@angular/core';
import { PlacementArray } from '@ng-bootstrap/ng-bootstrap/util/positioning';

import { ContextHelpService } from './context-help.service';
import { ContextHelpWrapperComponent } from './context-help-wrapper/context-help-wrapper.component';
import { PlacementDir } from './context-help-wrapper/placement-dir.model';
import { hasValue } from './empty.util';

export interface ContextHelpDirectiveInput {
  content: string;
  id: string;
  tooltipPlacement?: PlacementArray;
  iconPlacement?: PlacementDir;
}

/**
 * Directive to add a clickable tooltip icon to an element.
 * The tooltip icon's position is configurable ('left' or 'right')
 * and so is the position of the tooltip itself (PlacementArray).
 */
@Directive({
  selector: '[dsContextHelp]',
  standalone: true,
})
export class ContextHelpDirective implements OnChanges, OnDestroy {
  /**
   * Expects an object with the following fields:
   * - content: a string referring to an entry in the i18n files
   * - tooltipPlacement: a PlacementArray describing where the tooltip should expand, relative to the tooltip icon
   * - iconPlacement: a string 'left' or 'right', describing where the tooltip icon should be placed, relative to the element
   */
  @Input() dsContextHelp: ContextHelpDirectiveInput;
  mostRecentId: string | undefined = undefined;

  protected wrapper: ComponentRef<ContextHelpWrapperComponent>;

  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainerRef: ViewContainerRef,
    private contextHelpService: ContextHelpService,
  ) {}

  ngOnChanges() {
    this.clearMostRecentId();
    this.mostRecentId = this.dsContextHelp.id;
    this.contextHelpService.add({ id: this.dsContextHelp.id, isTooltipVisible: false });

    if (this.wrapper === undefined) {
      this.wrapper = this.viewContainerRef.createComponent(ContextHelpWrapperComponent);
    }
    this.wrapper.setInput('templateRef', this.templateRef);
    this.wrapper.setInput('content', this.dsContextHelp.content);
    this.wrapper.setInput('id', this.dsContextHelp.id);
    this.wrapper.setInput('tooltipPlacement', this.dsContextHelp.tooltipPlacement);
    this.wrapper.setInput('iconPlacement', this.dsContextHelp.iconPlacement);
  }

  ngOnDestroy() {
    this.clearMostRecentId();
    if (hasValue(this.wrapper)) {
      this.wrapper.destroy();
      this.wrapper = undefined;
    }
  }

  private clearMostRecentId(): void {
    if (this.mostRecentId !== undefined) {
      this.contextHelpService.remove(this.mostRecentId);
    }
  }
}