import {
  ChangeDetectionStrategy,
  Component,
  computed,
  inject,
} from '@angular/core';
import { isaOtherInfo } from '@isa/icons';
import {
  calculateCapacity,
  calculateMaxCapacity,
} from '@isa/remission/data-access';
import {
  FilterInputMenuButtonComponent,
  FilterService,
  InputType,
} from '@isa/shared/filter';
import { ToolbarComponent } from '@isa/ui/toolbar';
import { TooltipDirective } from '@isa/ui/tooltip';
import { NgIconComponent, provideIcons } from '@ng-icons/core';
import { createRemissionCapacityResource } from '../resources';
import { SkeletonLoaderDirective } from '@isa/ui/skeleton-loader';

@Component({
  selector: 'remi-feature-remission-list-department-elements',
  templateUrl: './remission-list-department-elements.component.html',
  styleUrl: './remission-list-department-elements.component.scss',
  changeDetection: ChangeDetectionStrategy.OnPush,
  providers: [provideIcons({ isaOtherInfo })],
  imports: [
    FilterInputMenuButtonComponent,
    ToolbarComponent,
    TooltipDirective,
    NgIconComponent,
    SkeletonLoaderDirective,
  ],
})
export class RemissionListDepartmentElementsComponent {
  /**
   * FilterService instance for managing filter state and queries.
   * @private
   */
  #filterService = inject(FilterService);

  /**
   * Filter input for departments, used to filter remission items by department.
   */
  filterDepartmentInput = computed(() => {
    const inputs = this.#filterService
      .inputs()
      .filter((input) => input.group === 'filter');
    return inputs?.find((input) => input.key === 'abteilungen');
  });

  /**
   * Computed signal to get the selected department from the filter input.
   * Returns the committed value if department is selected, otherwise a default label.
   * @returns {string} The selected departments or a default label.
   */
  selectedDepartment = computed(() => {
    const input = this.filterDepartmentInput();
    if (input && input.type === InputType.Checkbox) {
      const committedValue = this.#filterService.queryParams()[input.key];
      if (input.selected.length > 0 && committedValue) {
        return committedValue;
      }
    }
    return 'Abteilung auswählen';
  });

  /**
   * Resource signal for fetching remission capacity based on selected departments.
   * Updates when the selected departments change.
   * @returns Remission capacity resource state.
   */
  capacityResource = createRemissionCapacityResource(() => {
    return {
      departments: [this.selectedDepartment()],
    };
  });

  /**
   * Computed signal to get the current value of the capacity resource.
   * @returns {Array} The current capacity values or an empty array if not available.
   */
  capacityResourceValue = computed(() => this.capacityResource.value());

  /**
   * Computed signal to check if the capacity resource is currently fetching data.
   * @returns {boolean} True if the resource is loading, false otherwise.
   */
  capacityFetching = computed(
    () => this.capacityResource.status() === 'loading',
  );

  leistungValues = computed(() => {
    const value = this.capacityResourceValue();
    return value?.find((cap) => cap.item1 === 'Leistung');
  });

  stapelValues = computed(() => {
    const value = this.capacityResourceValue();
    return value?.find((cap) => cap.item1 === 'Stapel');
  });

  leistung = computed(() => {
    const values = this.leistungValues();
    return values
      ? calculateCapacity({
          capacityValue2: values.item2,
          capacityValue3: values.item3,
        })
      : 0;
  });

  maxLeistung = computed(() => {
    const values = this.leistungValues();
    return values
      ? calculateMaxCapacity({
          capacityValue2: values.item2,
          capacityValue3: values.item3,
          capacityValue4: values.item4,
          comparer: this.leistung(),
        })
      : 0;
  });

  stapel = computed(() => {
    const values = this.stapelValues();
    return values
      ? calculateCapacity({
          capacityValue2: values.item2,
          capacityValue3: values.item3,
        })
      : 0;
  });

  maxStapel = computed(() => {
    const values = this.stapelValues();
    return values
      ? calculateMaxCapacity({
          capacityValue2: values.item2,
          capacityValue3: values.item3,
          capacityValue4: values.item4,
          comparer: this.stapel(),
        })
      : 0;
  });

  rollbackFilterInput() {
    const inputKey = this.filterDepartmentInput()?.key;
    this.#filterService.rollbackInput([inputKey!]);
  }
}
