import { Component, ApplicationRef,ChangeDetectorRef,ElementRef, ViewChild, OnInit, Input, OnDestroy, HostListener, OnChanges, AfterViewInit } from '@angular/core';
import * as _ from 'lodash';
import {trigger, state, transition, style, animate, keyframes} from '@angular/animations';




@Component({
  selector: 'app-play',
  templateUrl: './play.component.html',
  styleUrls: ['./play.component.scss'],
  animations: [
    trigger('tip-border', [
      state('right', style({'border': '0.8rem solid #1da299', 'border-radius': '1rem', 'transform': 'scale(1)'})),
      state('none', style({'border': '0.8rem solid #fff', 'border-radius': '1rem', 'transform': 'scale(1)'})),
      state('wrong', style({'border': '0.8rem solid #ff3333', 'border-radius': '1rem', 'transform': 'scale(1)'})),
      transition('none => wrong', animate('.2s ease-in', keyframes([
        style({transform: 'scale(1)'}),
        style({transform: 'scale(0.6)'}),
        style({transform: 'scale(1)'}),
      ]))), // 第一个参数:动画时间, 第二个参数:动画延迟时间
      transition('none => right', animate('.2s ease-in', keyframes([
        style({transform: 'scale(1)'}),
        style({transform: 'scale(0.6)'}),
        style({transform: 'scale(1)'}),
      ]))),
      transition('wrong => none', animate('.2s ease-out'))
    ])
  ]
})
export class PlayComponent implements OnInit, OnDestroy, OnChanges {

  // 数据
  data;
  saveKey = 'listen-choose';

  isPlaying = false;
  audio = new Audio();
  rightAudio = new Audio();
  wrongAudio = new Audio();
  _lc_text = '';
  _data = [];
  hasUnlockedAudio = false;
  sfxActive = new Set<HTMLAudioElement>();

  constructor(private appRef: ApplicationRef,
    public changeDetectorRef: ChangeDetectorRef) {
    this.rightAudio.src = 'assets/right.mp3';
    this.rightAudio.load();
    this.wrongAudio.src = 'assets/wrong.mp3';
    this.wrongAudio.load();
  }

  ngOnInit() {
    this.data = {
      contentObj: {
        pics: [
          {pic_id: "assets/common/2.png",is_right: false},
          {pic_id: "assets/common/3.png",is_right: true},
          {pic_id: "assets/common/4.png",is_right: false}
        ],
        text: "banana",
        audio_id: "assets/right.mp3"
      }
    };

    // 获取数据
    const getData = ( window as any).courseware.getData;
    getData((data) => {
      if (data && typeof data === 'object') {
        this.data = data;
      }
      this._data = _.get(this.data.contentObj, 'pics', []).filter(item => item && item.pic_id);
      this._data.forEach(item => item.state = 'none');
      this._lc_text = '';
      if (this.data.contentObj && this.data.contentObj.audio_id) {
        this.audio.src = this.data.contentObj.audio_id;
        this.audio.load();
      }
      this.audio.pause();
      this.audio.currentTime = 0;
      this.isPlaying = false;
      this.changeDetectorRef.markForCheck();
      this.changeDetectorRef.detectChanges();
      this.refresh();
      window["air"] && window["air"].hideAirClassLoading(this.saveKey, this.data);


    }, this.saveKey);
  }

  ngOnDestroy() {
    this.audio.pause();
    this.audio = null;
  }

  ngOnChanges(data) {

  }

  playCount = 0;
  playAudio() {
    if (this.playCount == 0 && this.data.contentObj && this.data.contentObj.audio_id) {
      this.playCount = 1;
      this.audio = new Audio(this.data.contentObj.audio_id);
    }
    if (this.data.contentObj && this.data.contentObj.audio_id) {
      if (this.isPlaying) {
        this.audio.pause();
        this.isPlaying = false;
      } else {
        this.audio.play();
        this.isPlaying = true;
      }
    }
    this.changeDetectorRef.markForCheck();
    this.changeDetectorRef.detectChanges();
    this.refresh();
  }

  lcDisplayText() {
    this._lc_text = this.data.contentObj.text || '';
    this.changeDetectorRef.markForCheck();
    this.changeDetectorRef.detectChanges();
    this.refresh();
  }

  async ensureAudioUnlocked(): Promise<void> {
    if (this.hasUnlockedAudio) {
      return;
    }
    try {
      this.rightAudio.muted = true;
      this.rightAudio.currentTime = 0;
      await this.rightAudio.play();
      this.rightAudio.pause();
      this.rightAudio.muted = false;
      this.rightAudio.currentTime = 0;
      this.hasUnlockedAudio = true;
    } catch (e) {
      // 忽略，后续播放时再尝试
    }
  }

  async playSfx(base: HTMLAudioElement): Promise<void> {
    const clip = base.cloneNode(true) as HTMLAudioElement;
    clip.preload = 'auto';
    clip.currentTime = 0;
    this.sfxActive.add(clip);
    const cleanup = () => {
      this.sfxActive.delete(clip);
      clip.src = '';
    };
    clip.addEventListener('ended', cleanup, { once: true });
    clip.addEventListener('error', cleanup, { once: true });
    try {
      await clip.play();
    } catch (err) {
      if ((err as any)?.name === 'NotAllowedError' && !this.hasUnlockedAudio) {
        await this.ensureAudioUnlocked();
        try {
          await clip.play();
          return;
        } catch (_) {}
      }
      cleanup();
    }
  }

  async handleTap(ev, item) {
    if (item.is_right) {
      item.state = 'right';
      await this.playSfx(this.rightAudio);
    } else {
      item.state = 'wrong';
      await this.playSfx(this.wrongAudio);
      setTimeout(() => {
        item.state = '';
      }, 1500);
    }
    this.changeDetectorRef.markForCheck();
    this.changeDetectorRef.detectChanges();
    this.refresh();
  }

  refresh() {
    setTimeout(() => {
      this.appRef.tick();
    }, 1);
  }

}
