import { ChangeDetectorRef, ApplicationRef, Component, ElementRef, ViewChild, OnInit, Input, OnDestroy, HostListener, AfterViewInit } from '@angular/core';

import {
  Label,
  MySprite, tweenChange,

} from './Unit';
import {res, resAudio} from './resources';

import {Subject} from 'rxjs';
import {debounceTime} from 'rxjs/operators';

import TWEEN from '@tweenjs/tween.js';




@Component({
  selector: 'app-play',
  templateUrl: './play.component.html',
  styleUrls: ['./play.component.scss']
})
export class PlayComponent implements OnInit, AfterViewInit, OnDestroy {

  @ViewChild('indexNumBox', {static: true})
  indexNumBox: ElementRef;
  @ViewChild('boxContainer', {static: true})
  boxContainer: ElementRef;
  currentSeqIndex = 0;
  bbFlying = false;
  col: number;
  randPics: Array<any>;
  rightAudio = new Audio();
  wrongAudio = new Audio();
  animIng = false;
  _itemsArr = [];
  data;
  saveKey = 'ww_sequence';

  @HostListener('window:resize', ['$event'])
  onResize(event) {
    this.resetContainerItems();
  }
  constructor(private appRef: ApplicationRef, private changeDetectorRef: ChangeDetectorRef) {
    this.rightAudio.src = 'assets/right.mp3';
    this.rightAudio.load();
    this.wrongAudio.src = 'assets/wrong.mp3';
    this.wrongAudio.load();
  }
  ngAfterViewInit(): void {
    this.resetContainerItems();
  }

  ngOnDestroy(){

  }
  shuffle(arr) {
    const a = [].concat(arr);
    for (let i = a.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [a[i], a[j]] = [a[j], a[i]];
    }
    return a;
  }
  ngOnInit() {

    this.data = {
      contentObj: {
        pics: ["http://staging-teach.cdn.ireadabc.com/5502addf299f5f34dc181f993f81e311.png",
          "http://staging-teach.cdn.ireadabc.com/dae252625e5fc37e992c8e1d4c8f0ad6.png",
          "http://staging-teach.cdn.ireadabc.com/de72d34b60a2ca72b2688859d6f1d5e2.jpg"]
      }
    };

    // 获取数据
    const getData = (window as any).courseware.getData;
    getData((data) => {
      console.log('getdata', data)
      if (data && typeof data === 'object') {
        this.data = data;
      }
      this.currentSeqIndex = 0;
      if (!Array.isArray(this.data.contentObj.pics)) {
        this.data.contentObj.pics = [];
      }

      this.randPics = this.shuffle(this.data.contentObj.pics.map((res_id, idx) => {
        return {res_id, idx };
      }));
      const pl = this.randPics.length;
      this._itemsArr = Array(pl).fill(null).map((_, i) => i + 1);
      if ( pl <= 4) {
        this.col = 12;
      } else if (pl > 4 ) {
        this.col = 8;
      }
      this.changeDetectorRef.markForCheck();
      this.changeDetectorRef.detectChanges();
      this.refresh();
      this.resetContainerItems();


      if (window['air']) {
        window['air'].hideAirClassLoading(this.saveKey, this.data);
      }
    }, this.saveKey);

  }
  refresh() {
    setTimeout(() => {
      this.appRef.tick();
    }, 1);
  }
  move(el, to_x, to_y, cb?: () => void) {
    // el.style.position = 'absolute';
    const x = parseInt(el.offsetLeft, 10);
    const y = parseInt(el.offsetTop, 10);
    const delta_x = (to_x - x) / 60;
    const delta_y = (to_y - y) / 60;
    let anim_timer = null;
    let c = 0;
    anim_timer = setInterval(() => {
      if (c >= 60) {
        clearInterval(anim_timer);
        anim_timer = null;
        c = 0;
        if (cb) {
          cb();
        }
        return;
      }
      c++;
      el.style.left = x + c * delta_x + 'px';
      el.style.top = y + c * delta_y + 'px';
      // console.log(c, el.style.left, el.style.top);
    }, 16);
  }

  checkSelectedIndex(evt, idx) {
    if (this.animIng) {
      return;
    }
    this.animIng = true;
    const imgs = this.indexNumBox.nativeElement.querySelectorAll('img');
    const img = imgs[this.currentSeqIndex];
    if (!img) {
      return;
    }
    img.classList.remove('right');
    img.classList.remove('wrong');
    // img.offsetWidth;
    const newone = img.cloneNode(true);
    img.parentNode.replaceChild(newone, img);
    if ( this.currentSeqIndex === idx ) {
      this.rightAudio.pause();
      this.rightAudio.currentTime = 0;
      this.rightAudio.play();
      newone.classList.add('right');
      newone.addEventListener('animationend', () => {
        // console.log('aaaa');
        newone.style.display = 'none';
        this.currentSeqIndex++ ;
        this.animIng = false;
        this.randPics.find(item => item.idx === idx).isRight = true;
        this.changeDetectorRef.markForCheck();
        this.changeDetectorRef.detectChanges();
        this.refresh();
      });
    } else {
      this.wrongAudio.pause();
      this.wrongAudio.currentTime = 0;
      this.wrongAudio.play();
      newone.classList.add('wrong');
      this.animIng = false;
    }
    this.changeDetectorRef.markForCheck();
    this.changeDetectorRef.detectChanges();
    this.refresh();
  }
  showRightAnswer() {
    const boxs = this.boxContainer.nativeElement.children; // .querySelectorAll('.gutter-row');

    const els = [];
    for (const box of boxs) {
      els.push(box);
      // els.push(box.cloneNode(true));
      // box.remove();
    }
    els.sort((a, b) => {
      const one = parseInt(a.dataset.idx, 10);
      const two = parseInt(b.dataset.idx, 10);
      return one - two;
    });
    for (const el of els) {
      this.boxContainer.nativeElement.appendChild(el);
    }
    this.changeDetectorRef.markForCheck();
    this.changeDetectorRef.detectChanges();
    this.refresh();
  }

 //
  // Get the best item bounds to fit in the container. Param object must have
// width, height, itemCount, aspectRatio, maxRows, and minGap. The itemCount
// must be greater than 0. Result is single object with rowCount, colCount,
// itemWidth, and itemHeight.
  getBestItemBounds(config) {
    const actualRatio = config.width / config.height
    // Just make up theoretical sizes, we just care about ratio
    const theoreticalHeight = 100
    const theoreticalWidth = theoreticalHeight * config.aspectRatio
    // Go over each row count find the row and col count with the closest
    // ratio.
    let best
    for (let rowCount = 1; rowCount <= config.maxRows; rowCount++) {
      // Row count can't be higher than item count
      if (rowCount > config.itemCount) continue
      const colCount = Math.ceil(config.itemCount / rowCount)
      // Get the width/height ratio
      const ratio = (theoreticalWidth * colCount) / (theoreticalHeight * rowCount)
      if (!best || Math.abs(ratio - actualRatio) < Math.abs(best.ratio - actualRatio)) {
        best = { rowCount, colCount, ratio };
      }
    }
    // Build item height and width. If the best ratio is less than the actual ratio,
    // it's the height that determines the width, otherwise vice versa.
    const result = {itemHeight: 0, itemWidth: 0,  rowCount: best.rowCount, colCount: best.colCount };
    if (best.ratio < actualRatio) {
      result.itemHeight = (config.height - (config.minGap * best.rowCount)) / best.rowCount;
      result.itemWidth = result.itemHeight * config.aspectRatio;
    } else {
      result.itemWidth = (config.width - (config.minGap * best.colCount)) / best.colCount;
      result.itemHeight = result.itemWidth / config.aspectRatio;
    }
    return result;
  }

// Change the item size via CSS property
  resetContainerItems() {
    const itemCount = document.querySelectorAll('.item').length
    if (!itemCount) return
    const container = this.boxContainer.nativeElement;
    const rect = container.getBoundingClientRect()
    // Get best item bounds and apply property
    const { itemWidth, itemHeight } = this.getBestItemBounds({
      width: rect.width,
      height: rect.height,
      itemCount,
      aspectRatio: 16 / 12,
      maxRows: 5,
      minGap: 5
    })
    console.log('Item cchangehanges', itemWidth, itemHeight)
    container.style.setProperty('--item-width', itemWidth + 'px')
    container.style.setProperty('--item-height', itemHeight + 'px')
    this.changeDetectorRef.markForCheck();
    this.changeDetectorRef.detectChanges();
    this.refresh();
  }

// Element resize support
//   const resObs = new ResizeObserver(() => resetContainerItems())
//   resObs.observe(document.getElementById('container'))

// Add item support
//   let counter = 0
//   document.getElementById('add').onclick = () => {
//     const elem = document.createElement('div')
//     elem.className = 'item'
//     const button = document.createElement('button')
//     button.innerText = 'Delete Item #' + (++counter)
//     button.onclick = () => {
//       document.getElementById('container').removeChild(elem)
//       resetContainerItems()
//     }
//     elem.appendChild(button)
//     document.getElementById('container').appendChild(elem)
//     resetContainerItems()
//   }
}
