import {
  ChangeDetectionStrategy,
  Component,
  inject,
  output,
  computed,
  ViewEncapsulation,
  input,
} from '@angular/core';
import { ButtonComponent } from '@isa/ui/buttons';
import { FilterService } from '../core';

/**
 * A standalone component that manages filter action buttons (apply/reset)
 *
 * This component provides UI controls to apply or reset filter values
 * within the filtering system. It communicates with the FilterService
 * to perform filter operations.
 *
 * @example
 * <filter-actions
 *   [inputKey]="'myFilterKey'"
 *   [canApply]="true"
 *   (applied)="handleFilterApplied()"
 *   (reseted)="handleFilterReset()">
 * </filter-actions>
 */
@Component({
  selector: 'filter-actions',
  templateUrl: './filter-actions.component.html',
  styleUrls: ['./filter-actions.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  standalone: true,
  imports: [ButtonComponent],
  host: {
    '[class]': "['filter-actions']",
  },
})
export class FilterActionsComponent {
  /** The filter service used to interact with the filter system */
  readonly filterService = inject(FilterService);

  /**
   * Optional key specifying which filter input to apply/reset
   * If not provided, all filter inputs will be affected
   */
  inputKey = input<string>();

  /**
   * Controls whether the Apply button should be displayed
   * @default true
   */
  canApply = input<boolean>(true);

  /**
   * Computed signal that filters inputs to only include those with target 'filter'
   */
  filterInputs = computed(() =>
    this.filterService.inputs().filter((input) => input.target === 'filter'),
  );

  /**
   * Event emitted when filters are applied
   */
  applied = output<void>();

  /**
   * Event emitted when filters are reset
   */
  reseted = output<void>();

  /**
   * Applies the current filter values
   *
   * If inputKey is provided, only that specific filter input is committed.
   * Otherwise, all filter inputs are committed.
   */
  onApply() {
    this.filterService.commit();
    this.applied.emit();
  }

  /**
   * Resets filter values to their defaults
   *
   * If inputKey is provided, only that specific filter input is reset.
   * Otherwise, all filter inputs with target 'filter' are reset.
   * After resetting, all changes are committed.
   */
  onReset() {
    const inputKey = this.inputKey();

    if (!inputKey) {
      this.filterService.resetInput(
        this.filterInputs().map((input) => input.key),
      );
    } else {
      this.filterService.resetInput([inputKey]);
    }

    this.filterService.commit();
    this.reseted.emit();
  }
}
