import { ChangeDetectionStrategy, Component, computed, inject, input, output } from '@angular/core';
import { TextButtonComponent } from '@isa/ui/buttons';
import { ToolbarComponent } from '@isa/ui/toolbar';
import { FilterService, OrderByDirection, OrderByOption } from '../core';
import { NgIconComponent, provideIcons } from '@ng-icons/core';
import { isaSortByDownMedium, isaSortByUpMedium } from '@isa/icons';

type OrderBy = {
  by: string;
  label: string;
  currentDir: OrderByDirection | undefined;
  nextDir: OrderByDirection | undefined;
};

@Component({
  selector: 'filter-order-by-toolbar',
  templateUrl: './order-by-toolbar.component.html',
  styleUrls: ['./order-by-toolbar.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [ToolbarComponent, TextButtonComponent, NgIconComponent],
  providers: [provideIcons({ desc: isaSortByDownMedium, asc: isaSortByUpMedium })],
})
export class OrderByToolbarComponent {
  #filter = inject(FilterService);

  commitOnToggle = input<boolean>(true);

  toggled = output<void>();

  orderByOptions = computed<OrderBy[]>(() => {
    const orderByOptions = this.#filter.orderBy();
    const selectedOrderBy = orderByOptions.find((o) => o.selected);

    const orderByOptionsWithoutDuplicates = orderByOptions.reduce<OrderByOption[]>((acc, curr) => {
      const existing = acc.find((o) => o.by === curr.by);
      if (!existing) {
        return [...acc, curr];
      }
      return acc;
    }, []);

    return orderByOptionsWithoutDuplicates.map((o) => {
      if (!selectedOrderBy) {
        return { by: o.by, label: o.label, currentDir: undefined, nextDir: 'asc' };
      }

      if (o.by === selectedOrderBy.by) {
        return {
          by: o.by,
          label: o.label,
          currentDir: selectedOrderBy.dir,
          nextDir: selectedOrderBy.dir === 'asc' ? 'desc' : undefined,
        };
      }

      return { by: o.by, label: o.label, currentDir: undefined, nextDir: 'asc' };
    });
  });

  selectedOrderBy = computed(() => {
    const orderByOptions = this.#filter.orderBy();
    return orderByOptions.find((o) => o.selected);
  });

  toggleOrderBy(orderBy: OrderBy) {
    this.#filter.setOrderBy(orderBy.by, orderBy.nextDir, {
      commit: this.commitOnToggle(),
    });

    this.toggled.emit();
  }
}
