import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { NbDialogService } from '@nebular/theme';
import { first } from 'rxjs/operators';
import { DropDownOption } from '../../../entity/dropDownOption';
import { FileService } from '../../../services/file.service';
import { MD2MobService } from '../../../services/MD2/md2-mob.service';
import { MD2Service } from '../../../services/MD2/md2.service';
import { MsgBoxService } from '../../../services/msg-box.service';
import { StateService } from '../../../services/state.service';
import { ADButtons, ADIcon } from '../../../ui/alert-dlg/alert-dlg.model';
import { NumberUtils } from '../../../utilities/number-utils';
import { StringUtils } from '../../../utilities/string-utils';
import { DrawingBag, DrawingItem, MD2Icon, MobDlgType, MobInfo, TreasureType } from '../massive-darkness2.model';
import { MD2Base, MD2ComponentBase } from '../MD2Base';
import { SpawnMobDlgComponent } from './spawn-mob-dlg/spawn-mob-dlg.component';

@Component({
  selector: 'md2-mobs',
  templateUrl: './mobs.component.html',
  styleUrls: ['./mobs.component.scss']
})
export class MobsComponent extends MD2ComponentBase implements OnInit {
  MobDlgType = MobDlgType;
  isRoamingMonster: boolean = false;

  attacking: boolean = false;
  attackingAllExp: number = 0;
  attackingAttackerExp: number = 0;
  attackingAttackerReward: string = '';
  showRoundMessage: boolean = false;
  @Input("isRoamingMonster")
  public set input_isRoamingMonster(value) {
    this.isRoamingMonster = typeof value !== "undefined" && value !== false;
  }
  constructor(
    private fileService: FileService,
    private msgBoxService: MsgBoxService,
    private dlgService: NbDialogService,
    private mobService: MD2MobService,
    public md2Service: MD2Service,
    protected stateService: StateService,
    protected route: ActivatedRoute,
    protected cdRef: ChangeDetectorRef,
  ) {
    super(md2Service, stateService, route, cdRef);
  }

  ngOnInit(): void {
    this.initMobDecks();
    super.ngOnInit();
  }



  public get mobs(): MobInfo[] {
    return this.isRoamingMonster ? this.md2Service.roamingMonsters : this.md2Service.mobs;
  }
  public set mobs(v: MobInfo[]) {
    if (this.isRoamingMonster) {
      this.md2Service.info.roamingMonsters = v;
    } else {
      this.md2Service.info.mobs = v;
    }
  }


  initMobDecks() {
    this.mobs = [];
    this.cdRef.detectChanges();
    let spawn$ = this.isRoamingMonster ? this.md2Service.darknessPhaseRule.spawnRoamingMonster : this.md2Service.darknessPhaseRule.spawnMob;
    spawn$.subscribe(result => {
      this.showRoundMessage = true;
      this.spawnMob();
    });
  }
  spawnMob() {
    let result = this.md2Service.spawnMob(this.isRoamingMonster);
    let titleText = result.exitingMob == null ? `${result.mob.description} Shows Up` : `${result.mob.description} Activate One Action Now!`;
    let actType = result.exitingMob == null ? MobDlgType.Spawn : MobDlgType.Activating;
    let mob = result.exitingMob == null ? result.mob : result.exitingMob;

    this.dlgService.open(SpawnMobDlgComponent, { context: { title: titleText, mode: actType, mob: mob } })
      .onClose.pipe(first()).subscribe(result => {
        this.afterSpawn();
      });
    this.cdRef.detectChanges();
  }

  spawnSpecificMob() {
    let mobOptions = this.isRoamingMonster ? this.md2Service.allRoamingMonsterInfos.map(f => new DropDownOption(f.name, f.name)) : this.md2Service.allMobInfos.map(f => new DropDownOption(f.name, f.name));
    this.msgBoxService.showInputbox('Spawn', '',
      {
        inputType: 'dropdown', dropDownOptions: mobOptions,
        buttons: ADButtons.YesNoCancel,
        confirmButtonText: 'Spawn',
        cancelButtonText: 'Random'
      }).pipe(first()).subscribe(mobName => {


        if (mobName || mobName === false) {

          if (!mobName) { mobName = null; }
          let result = this.md2Service.spawnMob(this.isRoamingMonster, mobName);
          let titleText = result.exitingMob == null ? `${result.mob.description} Shows Up` : `${result.mob.description} Activate One Action Now!`;
          let actType = result.exitingMob == null ? MobDlgType.Spawn : MobDlgType.Activating;
          let mob = result.exitingMob == null ? result.mob : result.exitingMob;

          this.dlgService.open(SpawnMobDlgComponent, { context: { title: titleText, mode: actType, mob: mob } })
            .onClose.pipe(first()).subscribe(result => {
              this.afterSpawn();
            });
          this.cdRef.detectChanges();
        }
      });


  }

  afterSpawn() {
    this.cdRef.detectChanges();
    this.md2Service.broadcastMobsInfo();
    if (this.showRoundMessage) {
      this.msgBoxService.show(`${NumberUtils.Ordinal(this.md2Service.info.round)} Hero Phase`, { icon: ADIcon.INFO });
    }
    this.showRoundMessage = false;
  }
  adjustUnitHp(mob: MobInfo, adding: boolean) {

    if (adding) {
      if (mob.unitRemainHp < mob.hp) {
        mob.unitRemainHp++;
      }
    } else {
      if (mob.unitRemainHp > 1) {
        mob.unitRemainHp--;
      }
    }
    this.cdRef.detectChanges();
  }
  killOneUnit(mob: MobInfo) {
    let attacker = this.md2Service.currentActivateHero;
    if (mob.mobAmount > 1) {
      mob.mobAmount--;
      mob.unitRemainHp = mob.hp;
      if (this.attacking) {
        this.attackingAttackerExp += 1;
      } else {

        if (attacker) {
          attacker.exp += 1;
          this.msgBoxService.show(`${attacker.heroFullName} Gain 1 Exp`, { icon: ADIcon.INFO }).pipe(first()).subscribe(result => {
            this.md2Service.broadcastHeroInfoToOwner(attacker);
          });
        }

      }

    } else {
      this.mobs.splice(this.mobs.indexOf(mob), 1);
      mob.mobAmount = 0;

      if (this.attacking) {
        this.attackingAllExp += mob.leaderExp;
        this.attackingAttackerExp += 1;
        this.attackingAttackerReward = `<br> and gains ${mob.carriedTreasureHtml}`;
      } else {
        let messageText = '';
        if (attacker) {
          messageText = `<b>${attacker.heroFullName}</b> Gain 1 Extra Exp.<br> and gains ${mob.carriedTreasureHtml}`;
        }
        this.msgBoxService.show(`All Hero Gain ${mob.leaderExp} Exp`, { text: messageText, icon: ADIcon.INFO }).pipe(first()).subscribe(result => {

        });
      }
      this.md2Service.mobBeenKilledSubject.next(mob);

    }
    this.cdRef.detectChanges();
  }
  addOneUnit(mob: MobInfo) {
    if (!this.isRoamingMonster) {
      mob.mobAmount++;
      mob.unitRemainHp = 1;
      this.cdRef.detectChanges();
    }
  }
  attackMob(mob: MobInfo) {

    this.attacking = true;
    this.attackingAllExp = 0;
    this.attackingAttackerExp = 0;
    this.attackingAttackerReward = '';
    this.dlgService.open(SpawnMobDlgComponent, { context: { title: `Attack ${mob.description}`, mode: MobDlgType.BeenAttacked, mob: mob } })
      .onClose.pipe(first()).subscribe(mobResult => {
        if (mobResult) {
          let attackDamage = mobResult.uiWounds;
          this.mobService.attackMob(mobResult, attackDamage);
        }

      });

  }
  mobHpChanged(mob: MobInfo, newHp: number) {
    console.log(newHp);
    mob.unitRemainHp = newHp;
    this.cdRef.detectChanges();

  }


  public getMobImageUrl(mob: MobInfo): string {
    if (StringUtils.isNullOrWhitespace(mob.leaderImgUrl)) {
      return mob.imageUrl;
    } else {
      return mob.leaderImgUrl;
    }
  }


  showMobImage(mob: MobInfo) {
    this.dlgService.open(SpawnMobDlgComponent, { context: { title: `${mob.description}`, mode: MobDlgType.PreView, mob: mob } })
      .onClose.pipe(first()).subscribe(result => {

      });
  }
  weaponHtml(mob: MobInfo) {
    let html = '<br>';
    mob.attackInfos.forEach(attackInfo => {
      html += this.iconHtml((attackInfo.type), 'mr-2');
      if (attackInfo.yellow > 0) {
        html += this.iconHtml(MD2Icon.YellowDice) + `<span class='MD2text g-font-size-18'> x ${attackInfo.yellow}</span>`
      }
      if (attackInfo.orange > 0) {
        html += this.iconHtml(MD2Icon.OrangeDice) + `<span class='MD2text g-font-size-18'> x ${attackInfo.orange}</span>`
      }
      html += "<br>";
    });
    return html;
  }
}
