import {
  ChangeDetectionStrategy,
  Component,
  computed,
  effect,
  inject,
  input,
  linkedSignal,
} from '@angular/core';
import { FilterService, NumberRangeFilterInput } from '../../core';
import { InputType } from '../../types';
import {
  InputControlDirective,
  InlineInputComponent,
} from '@isa/ui/input-controls';
import { logger } from '@isa/core/logging';
import { FormsModule } from '@angular/forms';

@Component({
  selector: 'filter-number-range-input',
  templateUrl: './number-range-input.component.html',
  styleUrls: ['./number-range-input.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [InlineInputComponent, InputControlDirective, FormsModule],
  host: { '[class]': "['filter-number-range-input']" },
})
export class NumberRangeInputComponent {
  #logger = logger(() => ({ component: 'NumberRangeInputComponent' }));

  #filterService = inject(FilterService);
  inputKey = input.required<string>();

  input = computed<NumberRangeFilterInput>(() => {
    const inputs = this.#filterService.inputs();
    const input = inputs.find(
      (input) =>
        input.key === this.inputKey() && input.type === InputType.NumberRange,
    ) as NumberRangeFilterInput;

    if (!input) {
      const err = new Error(`Input not found for key: ${this.inputKey()}`);
      this.#logger.error('Input not found', { error: err });
    }

    return input;
  });

  minValue = linkedSignal(() => this.input().min);

  // Overall domain bounds coming from the filter input definition
  overallMinLimit = computed(() => this.input().minValue ?? 0);
  overallMaxLimit = computed(() => this.input().maxValue ?? Infinity);

  // Allowed bounds for the minimum value input
  minInputLowerLimit = computed(() => this.overallMinLimit());
  minInputUpperLimit = computed(() =>
    Math.min(this.maxValue() ?? Infinity, this.overallMaxLimit()),
  );

  maxValue = linkedSignal(() => this.input().max);

  // Allowed bounds for the maximum value input
  maxInputLowerLimit = computed(() =>
    Math.max(this.minValue() ?? 0, this.overallMinLimit()),
  );
  maxInputUpperLimit = computed(() => this.overallMaxLimit());

  constructor() {
    effect(() => {
      const minValue = this.minValue();
      const maxValue = this.maxValue();

      const currentMin = this.input().min;
      const currentMax = this.input().max;

      if (minValue === currentMin && maxValue === currentMax) {
        return;
      }

      this.#filterService.setInputNumberRangeValue(
        this.inputKey(),
        minValue,
        maxValue,
      );
    });
  }
}
