import { NgTemplateOutlet } from '@angular/common';
import { Component, Directive, TemplateRef, booleanAttribute, computed, contentChild, inject, input, model, output } from '@angular/core';

type <%= classify(name) %>InputType = 'text' | 'email' | 'search' | 'tel' | 'url';

let nextId = 0;

@Directive({
  selector: 'ng-template[<%= camelize(name) %>Prefix]',
})
export class <%= classify(name) %>Prefix {
  readonly templateRef = inject<TemplateRef<unknown>>(TemplateRef);
}

@Directive({
  selector: 'ng-template[<%= camelize(name) %>Suffix]',
})
export class <%= classify(name) %>Suffix {
  readonly templateRef = inject<TemplateRef<unknown>>(TemplateRef);
}

@Component({
  selector: '<%= selector %>',
  imports: [NgTemplateOutlet],
  templateUrl: './<%= dasherize(name) %>.html',
  styleUrl: './<%= dasherize(name) %>.css',
})
export class <%= classify(name) %> {
  protected readonly prefix = contentChild(<%= classify(name) %>Prefix);
  protected readonly suffix = contentChild(<%= classify(name) %>Suffix);
  protected readonly instanceId = `<%= dasherize(name) %>-${nextId++}`;

  readonly label = input('Website');
  readonly type = input<<%= classify(name) %>InputType>('url');
  readonly placeholder = input('example');
  readonly buttonLabel = input('Apply');
  readonly hint = input('Use a short, memorable address.');
  readonly errorMessage = input('');
  readonly required = input(false, { transform: booleanAttribute });
  readonly disabled = input(false, { transform: booleanAttribute });
  readonly value = model('');
  readonly buttonClick = output<MouseEvent>();

  protected readonly hasPrefix = computed(() => Boolean(this.prefix()));
  protected readonly hasSuffix = computed(() => Boolean(this.suffix()));
  protected readonly hasAction = computed(() => this.buttonLabel().trim().length > 0);
  protected readonly hasError = computed(() => this.errorMessage().trim().length > 0);

  protected readonly describedBy = computed(() => {
    const ids: string[] = [];
    if (this.hasPrefix()) {
      ids.push(`${this.instanceId}-prefix`);
    }
    if (this.hasSuffix()) {
      ids.push(`${this.instanceId}-suffix`);
    }
    if (this.hint().trim().length > 0) {
      ids.push(`${this.instanceId}-hint`);
    }
    if (this.hasError()) {
      ids.push(`${this.instanceId}-error`);
    }
    return ids.length > 0 ? ids.join(' ') : null;
  });

  protected handleInput(event: Event): void {
    this.value.set((event.target as HTMLInputElement).value);
  }

  protected handleButtonClick(event: MouseEvent): void {
    if (this.disabled()) {
      event.preventDefault();
      event.stopPropagation();
      return;
    }

    this.buttonClick.emit(event);
  }
}
