import {
  ChangeDetectionStrategy,
  Component,
  EventEmitter,
  Input,
  Output,
  computed,
  signal,
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSelectModule } from '@angular/material/select';
import { MatInputModule } from '@angular/material/input';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatIconModule } from '@angular/material/icon';
import { MatChipsModule } from '@angular/material/chips';
import { MatButtonModule } from '@angular/material/button';
import { MatTooltipModule } from '@angular/material/tooltip';
import {
  Filament,
  StockLevel,
  classifyStockLevel,
} from '../../models/filament.model';

/** Filter state emitted by the filament filter component */
export interface FilamentFilterState {
  /** Selected material base names — empty means all */
  materialBaseNames: string[];

  /** Color search text — empty string means all */
  colorSearch: string;

  /** Whether to show only low/critical stock */
  lowStockOnly: boolean;

  /** Whether to show only active spools */
  activeOnly: boolean;
}

/**
 * FilamentFilterComponent — Filter bar for the filament inventory list.
 *
 * Provides:
 * - Material type multi-select filter
 * - Color name text search
 * - Low stock toggle (shows only critical/low spools)
 * - Active-only toggle
 * - Clear all filters action
 */
@Component({
  selector: 'app-filament-filter',
  standalone: true,
  imports: [
    CommonModule,
    FormsModule,
    MatFormFieldModule,
    MatSelectModule,
    MatInputModule,
    MatCheckboxModule,
    MatIconModule,
    MatChipsModule,
    MatButtonModule,
    MatTooltipModule,
  ],
  templateUrl: './filament-filter.component.html',
  styleUrl: './filament-filter.component.scss',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class FilamentFilterComponent {
  /** Filament data input — used to derive material options */
  @Input() set filaments(value: Filament[]) {
    this._filaments.set(value);
    const materials = [...new Set(value.map((f) => f.materialBaseName))].sort();
    this.materialOptions.set(materials);
  }
  get filaments(): Filament[] {
    return this._filaments();
  }
  private readonly _filaments = signal<Filament[]>([]);

  /** Available material base names derived from filament data */
  readonly materialOptions = signal<string[]>([]);

  /** Selected material base names */
  readonly selectedMaterials = signal<string[]>([]);

  /** Color search text */
  readonly colorSearch = signal('');

  /** Low stock only toggle */
  readonly lowStockOnly = signal(false);

  /** Active only toggle */
  readonly activeOnly = signal(false);

  /** Computed: whether any filters are active */
  readonly hasActiveFilters = computed(
    () =>
      this.selectedMaterials().length > 0 ||
      this.colorSearch().trim().length > 0 ||
      this.lowStockOnly() ||
      this.activeOnly()
  );

  /** Emits the current filter state whenever filters change */
  @Output() readonly filterChange = new EventEmitter<FilamentFilterState>();

  /** Handle material selection change */
  onMaterialChange(selected: string[]): void {
    this.selectedMaterials.set(selected);
    this.emitFilterState();
  }

  /** Handle color search input */
  onColorSearchChange(value: string): void {
    this.colorSearch.set(value);
    this.emitFilterState();
  }

  /** Handle low stock toggle */
  onLowStockToggle(checked: boolean): void {
    this.lowStockOnly.set(checked);
    this.emitFilterState();
  }

  /** Handle active-only toggle */
  onActiveOnlyToggle(checked: boolean): void {
    this.activeOnly.set(checked);
    this.emitFilterState();
  }

  /** Remove a single material chip */
  removeMaterial(material: string): void {
    const updated = this.selectedMaterials().filter((m) => m !== material);
    this.selectedMaterials.set(updated);
    this.emitFilterState();
  }

  /** Clear all filters */
  clearAll(): void {
    this.selectedMaterials.set([]);
    this.colorSearch.set('');
    this.lowStockOnly.set(false);
    this.activeOnly.set(false);
    this.emitFilterState();
  }

  /** Emit the current filter state */
  private emitFilterState(): void {
    this.filterChange.emit({
      materialBaseNames: this.selectedMaterials(),
      colorSearch: this.colorSearch().trim().toLowerCase(),
      lowStockOnly: this.lowStockOnly(),
      activeOnly: this.activeOnly(),
    });
  }
}