import { Directive, TemplateRef, ViewContainerRef, effect, inject, input } from '@angular/core';
import { Breakpoint, breakpoint } from './breakpoint';

/**
 * Structural directive that conditionally includes a template based on the viewport's breakpoint.
 *
 * @example
 * ```html
 * <ng-container *uiBreakpoint="'tablet'">
 *   This content is visible only on tablet viewports.
 * </ng-container>
 * ```
 */
@Directive({
  selector: '[uiBreakpoint]',
})
export class BreakpointDirective {
  private readonly viewContainer = inject(ViewContainerRef);
  private readonly templateRef = inject(TemplateRef);

  /**
   * Input property to specify the breakpoint(s) for the directive.
   * Accepts a single Breakpoint or an array of Breakpoints.
   */
  uiBreakpoint = input.required<Breakpoint | Breakpoint[]>();

  /**
   * Signal that evaluates to `true` if the current viewport matches the specified breakpoint(s).
   */
  matches = breakpoint(this.uiBreakpoint);

  constructor() {
    effect(() => {
      this.updateView(this.matches());
    });
  }

  /**
   * Updates the view based on whether the viewport matches the specified breakpoint(s).
   *
   * @param matches - Boolean indicating if the viewport matches the breakpoint(s).
   */
  private updateView(matches: boolean | undefined): void {
    if (matches) {
      this.viewContainer.createEmbeddedView(this.templateRef);
    } else {
      this.viewContainer.clear();
    }
  }
}
