import { ChangeDetectionStrategy, Component, ElementRef, HostBinding, ViewChild } from '@angular/core';
import { DomainTaskCalendarService } from '@domain/task-calendar';
import { DisplayInfoDTO } from '@swagger/eis';
import { DateAdapter } from '@ui/common';
import { UiMessageModalComponent, UiModalRef, UiModalService } from '@ui/modal';
import { isNullOrUndefined } from '@utils/common';
import { NativeContainerService } from 'native-container';
import { combineLatest, ReplaySubject } from 'rxjs';
import { map, shareReplay, switchMap } from 'rxjs/operators';
import { CameraCaptureModalComponent } from '../camera/camera-capture-modal.component';

@Component({
  selector: 'page-task-modal',
  templateUrl: 'task-modal.component.html',
  styleUrls: ['task-modal.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TaskModalComponent {
  @ViewChild('captureInput')
  captureInput: ElementRef<HTMLInputElement>;

  info: DisplayInfoDTO;
  isIpad = this.nativeContainer.isUiWebview()?.isNative;

  info$ = new ReplaySubject<DisplayInfoDTO>();

  processingStatus$ = this.info$.pipe(
    map((info) => this.domainTaskCalendarService.getProcessingStatusList(info)),
    shareReplay()
  );

  status$ = this.processingStatus$.pipe(
    map((processingStatus) => {
      if (processingStatus.includes('Uncompleted')) {
        return 'Unerledigt';
      }
      if (processingStatus.includes('InProcess')) {
        return 'In Bearbeitung';
      }
      if (processingStatus.includes('Completed')) {
        return 'Erledigt';
      }
      return 'Offen';
    })
  );

  @HostBinding('class')
  get statusClass() {
    return this.domainTaskCalendarService.getProcessingStatusList(this.info);
  }

  editDisabled$ = this.info$.pipe(
    map((info) => {
      if (info.publicationDate && info.taskDate && info.taskOverdueDate) {
        return this.dateAdapter.isLessThan({ first: this.dateAdapter.today(), second: new Date(info.taskDate), precision: 'day' });
      }
      return this.dateAdapter.isLessThan({
        first: this.dateAdapter.today(),
        second: new Date(info.publicationDate || info.taskDate),
        precision: 'day',
      });
    })
  );

  indicatorColor$ = this.info$.pipe(map((info) => this.domainTaskCalendarService.getProcessingStatusColorCode(info)));

  cameraPreview$ = this.info$.pipe(
    switchMap((info) =>
      this.domainTaskCalendarService.getConfirmationFiles({ infoId: info.id }).pipe(map((response) => response.result[0]))
    ),
    switchMap((file) => (!isNullOrUndefined(file?.id) ? this.domainTaskCalendarService.getFile({ fileId: file.id }) : [undefined]))
  );

  showStartEditCta$ = this.processingStatus$.pipe(
    map(
      (processingStatus) =>
        !processingStatus.includes('Uncompleted') &&
        !processingStatus.includes('InProcess') &&
        !processingStatus.includes('Completed') &&
        !processingStatus.includes('Removed')
    )
  );

  showCompleteEditCta$ = combineLatest([this.processingStatus$, this.info$]).pipe(
    map(
      ([processingStatus, info]) =>
        processingStatus.includes('InProcess') && !info.requiresImageOnConfirmation && !processingStatus.includes('Removed')
    )
  );

  showCameraCta$ = combineLatest([this.processingStatus$, this.info$]).pipe(
    map(
      ([processingStatus, info]) =>
        processingStatus.includes('InProcess') && info.requiresImageOnConfirmation && !processingStatus.includes('Removed')
    )
  );

  showUpdateIcon$ = combineLatest([this.processingStatus$, this.info$]).pipe(
    map(([processingStatus, info]) => (info.successor && processingStatus.includes('Removed')) || info.predecessor)
  );

  showResetEditCta$ = this.processingStatus$.pipe(
    map((processingStatus) => processingStatus.includes('Completed') && !processingStatus.includes('Removed'))
  );

  showOpenSuccessorCta$ = combineLatest([this.info$, this.processingStatus$]).pipe(
    map(([info, processingStatus]) => !!info.successor?.id && processingStatus.includes('Removed'))
  );

  constructor(
    private modalRef: UiModalRef<{ successorId: number }, DisplayInfoDTO>,
    private domainTaskCalendarService: DomainTaskCalendarService,
    private uiModal: UiModalService,
    private nativeContainer: NativeContainerService,
    private dateAdapter: DateAdapter
  ) {
    this.info = this.modalRef.data;
    this.info$.next(this.info);
  }

  close(successorId: number = undefined) {
    this.modalRef.close({ successorId });
  }

  async startEdit() {
    await this.domainTaskCalendarService.setToEdit({ infoId: this.info.id }).toPromise();
    this.reloadInfo();
  }

  async completeEdit() {
    await this.domainTaskCalendarService.complete({ infoId: this.info.id }).toPromise();
    this.close();
  }

  async edit() {
    await this.domainTaskCalendarService.setToEdit({ infoId: this.info.id }).toPromise();
    this.reloadInfo();
  }

  reloadInfo() {
    this.domainTaskCalendarService
      .getInfoById({ infoId: this.info.id })
      .pipe(map((response) => response.result))
      .subscribe((info) => {
        this.info$.next(info);
        this.info = info;
      });
  }

  cameraCapture(image: string) {
    const modalRef = this.uiModal.open({
      content: CameraCaptureModalComponent,
      data: {
        image,
        infoId: this.info.id,
      },
    });
    modalRef.afterClosed$.subscribe(async (result) => {
      if (result.data === '') {
        this.captureInput?.nativeElement?.click();
      } else if (result.data?.length > 0) {
        this.close();
      }
    });
  }

  openCamera(event: Event) {
    if (!this.isIpad) {
      event.preventDefault();
      event.stopImmediatePropagation();
      this.uiModal.open({
        content: UiMessageModalComponent,
        title: 'Fotonachweis - bitte wechseln Sie auf ein mobiles Gerät',
        data: {
          message: 'Wechseln Sie auf ein mobiles Gerät, um die Aufgabe mit Fotonachweis bearbeiten zu können.',
          closeAction: 'Ok',
        },
      });
    }
  }
}
