import {
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  DestroyRef,
  EventEmitter,
  inject,
  OnInit,
  Output,
  QueryList,
  ViewChildren
} from '@angular/core';
import {CommonModule} from '@angular/common';
import {FormControl, FormGroup, ReactiveFormsModule} from "@angular/forms";
import {compare, SortableHeader, SortEvent} from "../../_single-module/table/_directives/sortable-header.directive";
import {KavitaMediaError} from "../_models/media-error";
import {EVENTS, MessageHubService} from "../../_services/message-hub.service";
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
import {BehaviorSubject, filter, Observable, shareReplay} from "rxjs";
import {ScrobblingService} from "../../_services/scrobbling.service";
import {ScrobbleError} from "../../_models/scrobbling/scrobble-error";

import {SeriesService} from "../../_services/series.service";
import {EditSeriesModalComponent} from "../../cards/_modals/edit-series-modal/edit-series-modal.component";
import {NgbModal} from "@ng-bootstrap/ng-bootstrap";
import {FilterPipe} from "../../pipe/filter.pipe";
import {LoadingComponent} from "../../shared/loading/loading.component";
import {TranslocoModule} from "@ngneat/transloco";
import {DefaultDatePipe} from "../../pipe/default-date.pipe";
import {DefaultValuePipe} from "../../pipe/default-value.pipe";
import {TranslocoLocaleModule} from "@ngneat/transloco-locale";

@Component({
  selector: 'app-manage-scrobble-errors',
  standalone: true,
  imports: [CommonModule, ReactiveFormsModule, FilterPipe, LoadingComponent, SortableHeader, TranslocoModule, DefaultDatePipe, DefaultValuePipe, TranslocoLocaleModule],
  templateUrl: './manage-scrobble-errors.component.html',
  styleUrls: ['./manage-scrobble-errors.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ManageScrobbleErrorsComponent implements OnInit {
  @Output() scrobbleCount = new EventEmitter<number>();
  @ViewChildren(SortableHeader<KavitaMediaError>) headers!: QueryList<SortableHeader<KavitaMediaError>>;
  private readonly scrobbleService = inject(ScrobblingService);
  private readonly messageHub = inject(MessageHubService);
  private readonly cdRef = inject(ChangeDetectorRef);
  private readonly destroyRef = inject(DestroyRef);
  private readonly seriesService = inject(SeriesService);
  private readonly modalService = inject(NgbModal);

  messageHubUpdate$ = this.messageHub.messages$.pipe(takeUntilDestroyed(this.destroyRef), filter(m => m.event === EVENTS.ScanSeries), shareReplay());
  currentSort = new BehaviorSubject<SortEvent<ScrobbleError>>({column: 'created', direction: 'asc'});
  currentSort$: Observable<SortEvent<ScrobbleError>> = this.currentSort.asObservable();

  data: Array<ScrobbleError> = [];
  isLoading = true;
  formGroup = new FormGroup({
    filter: new FormControl('', [])
  });


  constructor() {}

  ngOnInit() {

    this.loadData();

    this.messageHubUpdate$.subscribe(_ => this.loadData());

    this.currentSort$.subscribe(sortConfig => {
      this.data = (sortConfig.column) ? this.data.sort((a: ScrobbleError, b: ScrobbleError) => {
        if (sortConfig.column === '') return 0;
        const res = compare(a[sortConfig.column], b[sortConfig.column]);
        return sortConfig.direction === 'asc' ? res : -res;
      }) : this.data;
      this.cdRef.markForCheck();
    });
  }

  onSort(evt: any) {
    //SortEvent<KavitaMediaError>
    this.currentSort.next(evt);

    // Must clear out headers here
    this.headers.forEach((header) => {
      if (header.sortable !== evt.column) {
        header.direction = '';
      }
    });
  }

  loadData() {
    this.isLoading = true;
    this.cdRef.markForCheck();
    this.scrobbleService.getScrobbleErrors().subscribe(d => {
      this.data = d;
      this.isLoading = false;
      this.scrobbleCount.emit(d.length);
      this.cdRef.detectChanges();
    });
  }

  clear() {
    this.scrobbleService.clearScrobbleErrors().subscribe(_ => this.loadData());
  }

  filterList = (listItem: ScrobbleError) => {
    const query = (this.formGroup.get('filter')?.value || '').toLowerCase();
    return listItem.comment.toLowerCase().indexOf(query) >= 0 || listItem.details.toLowerCase().indexOf(query) >= 0;
  }

  editSeries(seriesId: number) {
    this.seriesService.getSeries(seriesId).subscribe(series => {
      const modalRef = this.modalService.open(EditSeriesModalComponent, {  size: 'xl' });
      modalRef.componentInstance.series = series;
    });
  }
}
