import { AsyncPipe } from '@angular/common';
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { DialogService } from '@ngneat/dialog';
import {
  debounceTime,
  distinctUntilChanged,
  filter,
  switchMap,
  tap,
} from 'rxjs';
import {
  Ticket,
  Tour,
} from '../../../core/data-access/graphql/generated/generated';
import { TicketViewComponent } from '../ticket-view/ticket-view.component';
import { TicketsService } from '../tickets.service';
import { format, isAfter } from 'date-fns';

@Component({
  template: `<div class="flex flex-col items-center justify-start p-4">
    <div class="text-lg font-bold pb-2">Ticket suchen</div>
    <hr />
    <mat-form-field class="w-full">
      <mat-label>Einsatznummer oder Patient</mat-label>
      <input class="w-full" matInput [formControl]="searchCtrl" name="search" />
    </mat-form-field>
    <hr />
    <div class="w-full">
      @for (ticket of tickets$ | async; track ticket) {
      <div
        class="flex flex-col justify-between items-center py-2 border-b border-gray-200 cursor-pointer"
        (click)="showTicketView(ticket)"
      >
        <div class="w-full flex justify-between">
          <span>
            {{ ticket.tours.at(0)?.ordinanceType }}
            @if (ticket.tours.at(0)?.category) {
            <span class="text-sm text-gray-600">
              ({{ ticket.tours.at(0)?.category }})
            </span>
            }
          </span>
          <!-- <span class="text-sm text-gray-600">{{ getNextStart(ticket.tours) }}</span> -->
        </div>
        <div class="w-full flex justify-between">
          <span>
            {{ ticket.tours.at(0)?.patientName }}
            {{ ticket.tours.at(0)?.patientSurname }}
          </span>
          <span>
            {{ getToursLength(ticket) }} Tour{{
              getToursLength(ticket) > 1 ? 'en' : ''
            }}
          </span>
        </div>
      </div>
      }
    </div>
  </div>`,
  imports: [MatFormFieldModule, MatInputModule, ReactiveFormsModule, AsyncPipe],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TicketsSearchDialogComponent {
  private ticketsService = inject(TicketsService);
  private dialog = inject(DialogService);

  searchCtrl = new FormControl('');
  tickets$ = this.searchCtrl.valueChanges.pipe(
    debounceTime(200),
    distinctUntilChanged(),
    filter((val) => !!val && val?.length > 2),
    switchMap((query) => this.ticketsService.searchTickets(query as string))
  );

  showTicketView(ticket: unknown): void {
    const dialogRef = this.dialog.open(TicketViewComponent, {
      data: ticket as Ticket & { tours: Tour[] },
      width: '40vw',
      minHeight: '400px',
    });

    dialogRef.afterClosed$
      .pipe(tap((result) => result && this.showTicketView(result)))
      .subscribe();
  }

  getToursLength(ticket: unknown) {
    return (ticket as Ticket & { tours: Tour[] }).tours.filter(
      ({ check }) => check === 0
    ).length;
  }

  getNextStart(tours: Partial<Tour>[]) {
    const sortedStartDates = [...tours.map(({startDate}) => new Date(startDate))].sort((a, b) => a.getTime() - b.getTime())
    for(let i = 0; i < sortedStartDates.length; i++) {
      const currentDate = sortedStartDates.at(i)
      if(currentDate && isAfter(currentDate, new Date())) {
        return format(currentDate, 'HH:mm | dd.MM.yy')
      }
    }
    const latestDate = sortedStartDates.at(-1);
    return latestDate ? format(latestDate, 'HH:mm | dd.MM.yy') : 'No Tours'
  }
}
