import { ChangeDetectorRef } from "@angular/core";
import { AvalonStage, Player, PlayerAction, QuestInfo, Role, RoleInfo } from "../../entity/Avalon";
import { AvalonService } from "../../services/avalon.service";
import { StringUtils } from "../../utilities/string-utils";

export abstract class AvalonBase {


    public get id(): string {
        return this.avalonService.id;
    }

    public get isHost(): boolean {
        return this.avalonService.isHost;
    }

    constructor(
        protected cdRef: ChangeDetectorRef,
        protected avalonService: AvalonService
    ) {

    }

    public get me(): Player {
        //let player = this.avalonService.data.players.find(p => p.id == this.avalonService.id);
        let player = this.avalonService.data.players.find(p => p.connectionId == this.avalonService.connectionId);
        return player;
    }

    public get stage(): AvalonStage {
        return this.avalonService.data.stage;
    }
    public get players(): Player[] {
        return this.avalonService.data.players;
    }

    public get isLoading(): boolean {
        return !this.avalonService.data;
    }
    public get currentQuest(): QuestInfo {
        return this.avalonService.data.questInfos.find(q => !q.success && !q.failed);
    }

    protected broadcastMe(action: PlayerAction) {

        console.log('broadcastMe', this.me.username);
        this.detectMoveToNextStage(action);
        this.avalonService.broadcastPlayer(action, this.me);
        this.cdRef.detectChanges();
    }

    protected detectMoveToNextStage(action: PlayerAction): boolean {
        if (
            ('PickRole' == action && this.players.filter(p => !p.role).length == 0) ||
            ('VoteTeamMate' == action && this.unVoteTeamPlayerList.length == 0) ||
            ('VoteQuest' == action && this.unVoteQuestPlayerList.length == 0)
        ) {
            let quest = this.currentQuest;
            if ('VoteTeamMate' == action) {
                quest.teamMembers = this.players.filter(p => p.goingToQuest == true);
                quest.approve = this.players.filter(p => p.teamVote == true).length;
                quest.reject = this.players.filter(p => p.teamVote == false).length;
            } else if ('VoteQuest' == action) {
                quest.success = this.players.filter(p => p.goingToQuest == true && p.questVote == true).length;
                quest.failed = this.players.filter(p => p.goingToQuest == true && p.questVote == false).length;
            }

            this.avalonService.data.stage = this.avalonService.data.stage + 1;
            this.clearVoteStatus();
            return true;
        }
        return false;
    }

    public refreshStage() {
        //this.stage = stage;

        setTimeout(() => {
            this.avalonService.broadcast("RefreshStage", this.stage);
        }, 200);
        this.cdRef.detectChanges();
        //this.hubConnection.invoke("Broadcast", "RefreshStage");
    }

    public refreshAllInfo() {
        //this.stage = stage;

        this.avalonService.broadcast("RefreshAll", this.avalonService.data);
        this.cdRef.detectChanges();
        //this.hubConnection.invoke("Broadcast", "RefreshStage");
    }

    public broadcastAll() {
        //this.stage = stage;
        this.avalonService.broadcast("RefreshAll", this.avalonService.data);
        this.cdRef.detectChanges();
        //this.hubConnection.invoke("Broadcast", "RefreshStage");
    }

    clearVoteStatus() {
        for (let i = 0; i < this.players.length; i++) {
            const player = this.players[i];
            player.questVote = this.stage == AvalonStage.QuestVoteResult ? player.questVote : null;
            player.teamVote = this.stage == AvalonStage.TeamVoteResult ? player.teamVote : null;
            //player.goingToQuest = (this.data.stage == AvalonStage.TeamVote || this.data.stage == AvalonStage.QuestVote) ? player.goingToQuest : null;
            player.role = this.stage != AvalonStage.NewGame ? player.role : null;
        }
        this.cdRef.detectChanges();
    }

    public get allGoodRoles(): RoleInfo[] {
        return this.avalonService.data.roles.filter(r => r.isGood);
    }
    public get allEvilRoles(): RoleInfo[] {
        return this.avalonService.data.roles.filter(r => !r.isGood);
    }
    public get playerList(): string {
        return StringUtils.getHtmlBadges(this.players.map(p => p.username), 'primary');
    }
    public get unpickPlayerList(): string {
        return StringUtils.getHtmlBadges(this.players.filter(p => !p.role).map(p => p.username), 'warning');
    }
    public get unVoteTeamPlayerList(): string {
        return StringUtils.getHtmlBadges(this.players.filter(p => p.teamVote == null).map(p => p.username), 'warning');
    }
    public get questPlayerList(): string {
        return StringUtils.getHtmlBadges(this.players.filter(p => p.goingToQuest).map(p => p.username), 'info');
    }
    public get unVoteQuestPlayerList(): string {
        return StringUtils.getHtmlBadges(this.players.filter(p => p.goingToQuest && p.questVote == null).map(p => p.username), 'warning');
    }

    public get leader(): Player {
        return this.players.find(p => p.isLeader);
    }


}