import { Component, Input, OnInit } from '@angular/core';
import { EventGameQueue, QueueTypes } from "../../../types/server-event";
import { Participant } from "../../../types/participant";
import { ApiService } from "../../services/api.service";
import { Subject } from "rxjs";
import {map, takeUntil} from "rxjs/operators";
import { Question } from "../../../types/question";
import { getAudioPath } from "../../helper/tts.helper";
import { PrizeDto } from "../../../types/prize.dto";


class ResultEntity {
  valid: {
    user: number;
    time: Date;
    valid: boolean;
  }[];
  invalid: {
    user: number;
    time: Date;
    valid: boolean;
  }[];
}
@Component({
  selector: 'app-game-queue',
  templateUrl: './game-queue.component.html',
  styleUrls: ['./game-queue.component.scss']
})

export class GameQueueComponent implements OnInit {
  @Input() action: EventGameQueue;
  readonly gameQueueTypes = QueueTypes
  participant: Participant | null;
  participants: Participant[] = [];
  destroyed$ = new Subject<void>();
  results: ResultEntity;
  penalty = '';
  countdown: number;
  showCountdown: boolean;
  question: Question = new Question();
  showQuestion = false;
  showPrize = false;
  prize: PrizeDto;
  countdownCompleted$: Subject<void> = new Subject<void>();
  prizeAudioSrc: string;
  screpaText: string;
  constructor(private apiService: ApiService) { }

  ngOnInit(): void {
    if(this.action.target) {
      this.apiService.getParticipant(this.action.target).pipe(
        takeUntil(this.destroyed$)
      ).subscribe(e => {
        this.participant = e;
      });
    }

    if(this.action.type === this.gameQueueTypes.penalty) {
      this.getPenalty();
    }
    if(this.action.type === this.gameQueueTypes.additionalQuestion) {
      this.getAdditionalQuestion()
    }

    if(this.action.type === this.gameQueueTypes.playExtraCard) {
      this.playExtraCards();
    }

    if(this.action.type === this.gameQueueTypes.giveOutAPrize) {
      this.countdown = 10;
      this.showCountdown = true;
      this.countdownCompleted$.pipe(takeUntil(this.destroyed$)).subscribe(() => {
        this.getPrize();
      });
    }

    if(this.action.type == this.gameQueueTypes.screpa) {
      this.screpaText = this.action.text ?? '';

    }

    if(this.action.type == this.gameQueueTypes.showresults) {
      this.getResults();
    }
    console.log(this.action);

  }

  getPenalty() {
    this.apiService.getPenalty().pipe(
        takeUntil(this.destroyed$),
    ).subscribe((penalty) => {
      this.penalty = penalty.text;
      this.countdown = 10;
      this.showCountdown = true;
    });
  }

  playExtraCards() {
    this.apiService.playExtraCards()
      .pipe(
        takeUntil(this.destroyed$),
      ).subscribe(() => {
        console.log(`triggered`);
    })
  }

  countdownCompleted() {
    this.showCountdown = false;
    this.countdownCompleted$.next();
  }

  private getAdditionalQuestion() {
    this.apiService.getAdditionalQuestion(this.action.target).subscribe(e => {
      this.question = e;
      this.showQuestion = true;
    })
  }

    getAudio(penalty: string, voice = 1) {
        return getAudioPath(penalty, voice);
    }

  private getPrize() {
    if(!this.participant === null) {
      return;
    }
    this.apiService.getPrize().pipe(takeUntil(this.destroyed$)).subscribe((r) => {
      this.prize = r;
      this.showPrize = true;
      this.prizeAudioSrc = getAudioPath(`Поздравляю, ${this.participant?.name} получает ${this.prize.name}`);
    });
  }

  private getResults() {
    this.apiService.getQuestionResults().pipe(takeUntil(this.destroyed$), map(result => {
      result.map(r => {
        this.apiService.getParticipant(r.user).pipe(takeUntil(this.destroyed$)).subscribe((particip) => {
          if(!this.participants[r.user]) {
            this.participants[r.user] = particip;
          }
        })
      })
      return result;
      })
    ).subscribe((results) => {
      this.results = {
        valid: [],
        invalid: [],
      }
      let sortedByTime = results.sort((a,b) => a.time.getTime() - b.time.getTime());
      this.results.valid = sortedByTime.filter((r) => r.valid);
      this.results.invalid = sortedByTime.filter((r) =>  !r.valid);
      console.log(this.results)
    })
  }
}
