import { trigger, state, style, transition, animate } from '@angular/animations';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { first } from 'rxjs/operators';
import { DropDownOption } from '../../../entity/dropDownOption';
import { GameRoomService } from '../../../services/game-room.service';
import { MD2Service } from '../../../services/MD2/md2.service';
import { MsgBoxService } from '../../../services/msg-box.service';
import { StateService } from '../../../services/state.service';
import { ADButtonColor, ADButtons } from '../../../ui/alert-dlg/alert-dlg.model';
import { ArrayUtils } from '../../../utilities/array-utils';
import { StringUtils } from '../../../utilities/string-utils';
import { DebounceTimer } from '../../../utilities/timer-utils';
import { HeroClass, MD2HeroInfo, MD2HeroProfile, MD2Icon } from '../massive-darkness2.model';
import { MD2Base } from '../MD2Base';
import { MD2HeroProfileService } from '../service/massive-darkness2.service';
import { SignalRService } from '../../../services/signal-r.service';

@Component({
  selector: 'ngx-hero-dashboard',
  templateUrl: './hero-dashboard.component.html',
  styleUrls: ['./hero-dashboard.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  animations: [
    trigger('flipState', [
      state('active', style({
        transform: 'rotateY(179deg)'
      })),
      state('inactive', style({
        transform: 'rotateY(0)'
      })),
      transition('active => inactive', animate('500ms ease-out')),
      transition('inactive => active', animate('500ms ease-in'))
    ])
  ]
})
export class HeroDashboardComponent extends MD2Base implements OnInit {
  MD2Icon = MD2Icon;
  heroAction(hero: MD2HeroInfo, action: string) {
    throw new Error('Method not implemented.');
  }
  showMoveAction: boolean = false;
  HeroClass = HeroClass;
  refreshUI() {
    console.log('HeroDashboard RefreshUI');

  }

  heroUpdateDebounceTimer = new DebounceTimer(1000, () => { this.broadcastHeroInfo(); })

  classOptions: DropDownOption[] = [
    new DropDownOption(HeroClass.Berserker, 'Berserker'),
    new DropDownOption(HeroClass.Paladin, 'Paladin'),
    new DropDownOption(HeroClass.Ranger, 'Ranger'),
    new DropDownOption(HeroClass.Rogue, 'Rogue'),
    new DropDownOption(HeroClass.Wizard, 'Wizard'),
    new DropDownOption(HeroClass.Shaman, 'Shaman'),
    new DropDownOption(HeroClass.Druid, 'Druid'),
    new DropDownOption(HeroClass.Necromancer, 'Necromancer'),
    new DropDownOption(HeroClass.Monk, 'Monk'),
    new DropDownOption(HeroClass.Thinker, 'Thinker'),
    new DropDownOption(HeroClass.Bard, 'Bard'),
  ];
  heros = [] as MD2HeroInfo[];
  heroProfiles: MD2HeroProfile[] = [];
  currentHeroIndex: number = 0;
  isSelectingHero: boolean = false;
  selectedHeroClass: HeroClass;

  public get hero() {
    return this.md2Service.playerHero;
  }

  public get className() {
    if (this.md2Service.playerHero) {
      return HeroClass[this.md2Service.playerHero.class];
    }
    if (this.selectedHeroClass) {
      return HeroClass[this.selectedHeroClass];
    }
    return '';
  }
  public get currentSelectingHero(): MD2HeroInfo {
    return this.heros[this.currentHeroIndex];
  }

  constructor(
    private gameRoomService: GameRoomService,
    public md2Service: MD2Service,
    private heroProfileService: MD2HeroProfileService,
    protected stateService: StateService,
    protected route: ActivatedRoute,
    protected cdRef: ChangeDetectorRef,
    private msgBoxService: MsgBoxService,
    private signalRService: SignalRService
  ) {
    super(md2Service, stateService, route, cdRef);
    this.isHeroDashboard = true;
  }

  public get allowAttack(): boolean {
    return this.hero.uiBossFight || this.md2Service.mobs?.length > 0 || this.md2Service.roamingMonsters?.length > 0;
  }

  ngOnInit(): void {
    super.ngOnInit();

    this.gameRoomService.gameRoomId = this.roomId;
    this.gameRoomService.joinGameRoom(this.roomId);
    //this.fetchGameInfo();
    this.signalRService.signalRMessageConnSubject.subscribe(state => {
      if (state.status == 'connected') {
        this.fetchGameInfo();
      }
    });
  }

  override signalRInitialized() {
    // this.gameRoomService.joinGameRoom(this.roomId);
    // if (this.md2Service.initialized == false) {
    //   this.gameRoomService.createGameRoom('MD2');
    //   this.md2Service.initialized = true;
    // }
  }
  initHero() {
    if (!this.md2Service.heros.some(h => h.playerInfo.signalRClientId == this.stateService.loginUserService.userAccess.signalRConnectionId)) {

      this.msgBoxService.showInputbox('Select Hero Class', '', { dropDownOptions: this.classOptions, inputType: 'dropdown' })
        .pipe(first()).subscribe(heroClass => {
          if (heroClass != null) {
            // switch (heroClass) {
            //   case HeroClass.Berserker: break;
            //   case HeroClass.Wizard:
            //     this.heros = this.wizards;
            //     break;
            //   case HeroClass.Rogue: break;
            //   case HeroClass.Ranger: break;
            //   case HeroClass.Shaman: break;
            //   case HeroClass.Paladin: break;
            //   default: break;
            // }
            // this.showHeroList(heroClass, 0);
            this.initClassHeroList(heroClass);
          }
        });
    }
  }



  initClassHeroList(heroClass: HeroClass) {
    this.heros = [];
    this.selectedHeroClass = heroClass;
    this.heroProfileService.getAll().pipe(first()).subscribe(result => {

      this.heroProfiles = result.filter(h => h.heroClass == heroClass);
      for (let i = 0; i < this.heroProfiles.length; i++) {
        const heroProfile = this.heroProfiles[i];
        const heroInfo = new MD2HeroInfo({
          name: heroProfile.title,
          mpMaximum: heroProfile.mana,
          hpMaximum: heroProfile.hp,
          hp: heroProfile.hp,
          mp: heroProfile.mana,
          skillHtml: heroProfile.skillHtml,
          shadowSkillHtml: heroProfile.shadowSkillHtml.replace("<p>", '<p>' + this.iconHtml(MD2Icon.Shadow) + ' : '),
          class: heroClass
        });
        heroInfo.imgUrl = this.imgUrl('Heros/' + HeroClass[heroClass] + '.jpg');
        this.heros.push(heroInfo);
      }
      this.heros = ArrayUtils.Shuffle(this.heros);//.sort((a, b) => StringUtils.compareSemVer(a.name, b.name));
      this.currentHeroIndex = 0;
      this.isSelectingHero = true;
      this.detectChanges();
    });

  }

  selectCurrentHero() {
    if (this.currentSelectingHero) {
      this.md2Service.playerJoin(this.currentSelectingHero);
      this.md2Service.broadcastMyHeroInfo();
      this.isSelectingHero = false;
      this.detectChanges();
    }
  }
  showSkills(type: string) {
    if (type == 'abilities') {
      this.msgBoxService.show('Abilities', { text: this.currentSelectingHero.skillHtml });
    } else {
      this.msgBoxService.show('Shadow Abilities', { text: this.currentSelectingHero.shadowSkillHtml });
    }
  }
  nextHero() {
    this.currentHeroIndex++;
    if (this.currentHeroIndex >= this.heros.length) {
      this.currentHeroIndex = 0;
    }
    this.detectChanges();
  }

  previousHero() {
    this.currentHeroIndex--;
    if (this.currentHeroIndex < 0) {
      this.currentHeroIndex = this.heros.length - 1;
    }
    this.detectChanges();
  }

  fetchGameInfo() {
    this.md2Service.broadcastFetchGameInfo();
  }

  broadcastHeroInfo() {
    this.md2Service.broadcastMyHeroInfo();
    this.heroUpdateDebounceTimer.clearOut();
  }
  increaseRage() {
    if (this.hero.rage < 7) {
      this.hero.rage++;
    }
  }
  openDoor() {
    this.md2Service.broadcastHeroAction('openDoor');
    //this.showMoveAction = false;
    this.detectChanges();
  }
  moveAction() {
    this.showMoveAction = true;
    this.detectChanges();
  }
  moveActionEnd() {
    this.showMoveAction = false;
    this.reduceAction();
    this.detectChanges();
  }
  action(action: string) {
    this.showMoveAction = false;
    switch (action) {
      case 'recoveryAction':
        this.msgBoxService.show('Recovery', { text: 'takes the Recover action may gain up to 2 Health or Mana in any combination (either 2 Health, 2 Mana, or 1 of each).' });
        break;
      case 'attackAction':
        this.msgBoxService.show('Attacking', { text: 'Please process attacking action in Dashboard.' });
        break;
      default:
        break;
    }
    this.md2Service.broadcastHeroAction(action);
    this.reduceAction();
  }
  reduceAction() {
    this.hero.remainActions -= 1;
    this.detectChanges();
    this.broadcastHeroInfo();
  }
  flip: string = 'inactive';

  toggleFlip() {
    this.flip = (this.flip == 'inactive') ? 'active' : 'inactive';
  }

  get allowStartAction() {
    return !this.md2Service.heros.some(h => h.uiActivating) && !this.hero.uiActivating && this.hero.remainActions > 0;
  }
  startActivation() {
    this.hero.uiActivating = true;
    //this.hero.remainActions = 3;
    if (this.hero.fireToken > 0) {
      this.msgBoxService.show(`You Are On ${this.iconHtml(MD2Icon.Fire)}!`, {
        text: `Roll ${this.iconHtml(MD2Icon.YellowDice)} ${this.hero.fireToken} times.`
      });
    }
    if (this.hero.frozenToken > 0) {
      let loseActions = Math.min(this.hero.frozenToken, this.hero.remainActions);
      this.hero.remainActions -= loseActions;
      this.hero.frozenToken -= loseActions;
      this.msgBoxService.show(`It's So Cold ${this.iconHtml(MD2Icon.Frost)}!`, {
        text: `Lose ${loseActions} actions.`
      });
    }
    if (this.hero.remainActions == 0) {
      this.hero.uiActivating = false;
    }
    this.broadcastHeroInfo();

  }
  endActivation() {
    if (this.hero.remainActions > 0) {
      this.msgBoxService.show('Are you sure?', { text: `End Activation will lose ${this.hero.remainActions} remaining actions.`, buttons: ADButtons.YesNo }).pipe(first()).subscribe(result => {
        if (result) {
          this.hero.remainActions = 0;
          this.endActivation();
        }
      });
    } else {
      this.hero.uiActivating = false;
      this.broadcastHeroInfo();
      this.detectChanges();
    }
  }
}
