import {
  ChangeDetectionStrategy,
  Component,
  computed,
  inject,
  input,
  linkedSignal,
  output,
  signal,
  ViewEncapsulation,
} from '@angular/core';
import { FilterMenuButtonComponent } from '../menus/filter-menu';
import { provideIcons } from '@ng-icons/core';
import { isaActionFilter, isaActionSort } from '@isa/icons';
import { IconButtonComponent } from '@isa/ui/buttons';
import { OrderByToolbarComponent } from '../order-by';
import { Breakpoint, breakpoint } from '@isa/ui/layout';
import { InputType, SearchTrigger } from '../types';
import { FilterService, TextFilterInput, FilterInput } from '../core';
import { SearchBarInputComponent } from '../inputs';
import { SwitchMenuButtonComponent } from '../menus/switch-menu';

/**
 * Filter controls panel component that provides a unified interface for search and filtering operations.
 *
 * This component combines search input, filter menu, and sorting controls into a responsive panel.
 * It adapts its layout based on screen size, showing/hiding controls appropriately for mobile and desktop views.
 *
 * @example
 * ```html
 * <filter-controls-panel
 *   (triggerSearch)="handleSearch($event)">
 * </filter-controls-panel>
 * ```
 *
 * Features:
 * - Responsive design that adapts to mobile/desktop layouts
 * - Integrated search bar with scanner support
 * - Filter menu with rollback functionality
 * - Sortable order-by controls
 * - Emits typed search trigger events
 */
@Component({
  selector: 'filter-controls-panel',
  templateUrl: './controls-panel.component.html',
  styleUrls: ['./controls-panel.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  standalone: true,
  imports: [
    SearchBarInputComponent,
    FilterMenuButtonComponent,
    IconButtonComponent,
    OrderByToolbarComponent,
    SwitchMenuButtonComponent,
  ],
  host: {
    '[class]': "['filter-controls-panel']",
  },
  providers: [provideIcons({ isaActionSort, isaActionFilter })],
})
export class FilterControlsPanelComponent {
  /**
   * Service for managing filter state and operations.
   */
  #filterService = inject(FilterService);

  /**
   * The unique key identifier for this input in the filter system.
   * @default 'qs'
   */
  inputKey = signal('qs');

  /**
   * Optional array of switch filter configurations to display as toggle switches.
   * Each item should be a filter input with an associated icon.
   * Switch filters are rendered to the left of the filter menu button.
   *
   * @example
   * ```typescript
   * switchFilters = [
   *   {
   *     filter: availabilityFilter,
   *     icon: 'isaActionCheck'
   *   }
   * ]
   * ```
   */
  switchFilters = input<Array<{ filter: FilterInput; icon: string }>>([]);

  /**
   * Output event that emits when any search action is triggered.
   * Provides the specific SearchTrigger type to indicate how the search was initiated:
   * - 'input': Text input or search button
   * - 'filter': Filter menu changes
   * - 'order-by': Sort order changes
   * - 'scan': Barcode scan
   */
  triggerSearch = output<SearchTrigger>();

  /**
   * Signal tracking whether the viewport is at tablet size or above.
   * Used to determine responsive layout behavior for mobile vs desktop.
   */
  mobileBreakpoint = breakpoint([Breakpoint.Tablet, Breakpoint.Desktop]);

  forceMobileLayout = input(false);

  mobileLayout = computed(
    () => this.forceMobileLayout() || this.mobileBreakpoint(),
  );

  /**
   * Signal controlling the visibility of the order-by toolbar on mobile devices.
   * Initially shows toolbar when NOT on mobile, can be toggled by user on mobile.
   * Linked to mobileBreakpoint to automatically adjust when screen size changes.
   */
  showOrderByToolbarMobile = linkedSignal(() => !this.mobileLayout());

  /**
   * Computed signal that determines if the search input is present in the filter inputs.
   * This checks if there is a TextFilterInput with the specified inputKey.
   * Used to conditionally render the search input in the template.
   */
  hasInput = computed(() => {
    const inputs = this.#filterService.inputs();
    const input = inputs.find(
      (input) => input.key === this.inputKey() && input.type === InputType.Text,
    ) as TextFilterInput;
    return !!input;
  });

  /**
   * Computed signal that checks if there are any active filters applied.
   * This is determined by checking if there are any inputs of types other than Text.
   */
  hasFilter = computed(() => {
    const inputs = this.#filterService.inputs();
    return inputs.some((input) => input.type !== InputType.Text);
  });
}
