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

type <%= classify(name) %>Orientation = 'horizontal' | 'vertical';
type <%= classify(name) %>SelectionMode = 'none' | 'single' | 'multiple';

export interface <%= classify(name) %>Item {
  id: string;
  label: string;
  disabled?: boolean;
  pressed?: boolean;
}

const DEFAULT_ITEMS: readonly <%= classify(name) %>Item[] = [
  { id: 'day', label: 'Dia', pressed: true },
  { id: 'week', label: 'Semana' },
  { id: 'month', label: 'Mês' },
];
const DEFAULT_SELECTED_IDS = DEFAULT_ITEMS.filter((item) => item.pressed).map((item) => item.id);

let nextId = 0;

@Directive({
  selector: 'ng-template[<%= camelize(name) %>Item]',
})
export class <%= classify(name) %>ItemTemplate {
  readonly templateRef = inject<TemplateRef<{ $implicit: <%= classify(name) %>Item; pressed: boolean | null }>>(TemplateRef);
}

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

  readonly label = input('Opções de visualização');
  readonly orientation = input<<%= classify(name) %>Orientation>('horizontal');
  readonly selectionMode = input<<%= classify(name) %>SelectionMode>('single');
  readonly size = input<string>('md');
  readonly disabled = input(false, { transform: booleanAttribute });
  readonly items = input<readonly <%= classify(name) %>Item[]>(DEFAULT_ITEMS);
  readonly selectedIds = model<readonly string[]>(DEFAULT_SELECTED_IDS);

  protected readonly selectedIdSet = computed<ReadonlySet<string>>(() => new Set(this.selectedIds()));

  protected readonly groupClasses = computed(() => [
    '<%= dasherize(name) %>',
    `<%= dasherize(name) %>--${this.orientation()}`,
    `<%= dasherize(name) %>--${this.size()}`,
  ].join(' '));

  protected isPressed(item: <%= classify(name) %>Item): boolean | null {
    if (this.selectionMode() === 'none') {
      return item.pressed ?? null;
    }

    return this.selectedIdSet().has(item.id);
  }

  protected ariaPressed(item: <%= classify(name) %>Item): string | null {
    const pressed = this.isPressed(item);
    return pressed === null ? null : String(pressed);
  }

  protected activate(item: <%= classify(name) %>Item): void {
    if (this.disabled() || item.disabled) {
      return;
    }

    if (this.selectionMode() === 'none') {
      return;
    }

    if (this.selectionMode() === 'single') {
      this.selectedIds.set([item.id]);
      return;
    }

    this.selectedIds.update((selectedIds) => {
      const next = new Set(selectedIds);
      if (next.has(item.id)) {
        next.delete(item.id);
      } else {
        next.add(item.id);
      }
      return Array.from(next);
    });
  }
}
