class Party {


    constructor() {
        this.reset();
    }

    reset() {
        this.players = [];
        this.startTime = false;
        this.finishTime = false;
        this.winCondition = {};
    }

    contain(key) {
        for (const player of this.players) {
            if (player.key === key) {
                return player;
            }
        }

        return false;
    }

    start() {
        if(!this.startTime) {
            this.startTime = Date.now();
        }
    }

    getTimePlayed() {
        if(this.finishTime) {
            return this.finishTime - this.startTime
        } else if(this.startTime) {
            return Date.now() - this.startTime;
        }
        return 0;
    }

    isFinish() {
        if (this.winCondition === {}) return;
        this.parseWinCondition();
    }


    setup(option) {
        if(option.teams) {
            for (const player of this.players) {
                if(option.teams.includes(player.key)) {
                    player.team = "A";
                } else {
                    player.team = "B";
                }
            }
        }
        if(option.winCondition) {
            this.writeWinCondition(option.winCondition);
        }
    }

    writeWinCondition(condition) {
        if(condition.max) {
            this.winCondition.max = condition.max
        } 
        if(condition.time) {
            this.winCondition.time = condition.time
        }
    }

    parseWinCondition() {
        if(this.winCondition.max) {
            const points = this.countTeamPoint();
            for ( const p in points) {
                if(points[p] >= this.winCondition.max) {
                    this.finish();
                }
            }
        } 
        if(this.winCondition.time) {
            if(this.getTimePlayed() >= this.winCondition.time) {
                this.finish();
                this.finishTime = this.startTime + this.winCondition.time;
            }
        }
    }

    countTeamPoint() {
        let points = {};
        for (const player of this.players) {
            if (player.team) {
                if (!points[player.team]) {
                    points[player.team] = 0;
                }
                points[player.team] += player.count;
            } else {
                points[player.key] = player.count;
            }
        }

        return points
    }

    finish() {
        if(!this.finishTime) {
            this.finishTime = Date.now();
        }
    }


    addPlayer(key) {
        if (!this.contain(key) && !this.startTime) {
            this.players.push(
                {
                    key : key,
                    count : 0,
                    name : key,
                    team : false
                }
            )
        }
    }

    updatePlayer(key, option) {
        if (this.contain(key) && !this.startTime) {
            for (const [k, player] of this.players.entries()) {
                if (player.key === key) {
                    if(option.name !== undefined) {
                        if(option.name === "") {
                            this.players[k].name = key;
                        } else {
                            this.players[k].name = option.name;
                        }
                    }
                    if(option.team && Number.isInteger(option.team)) {
                        this.players[k].team = option.team;
                    }
                }
            }
        }
    }

    addEvent(key) {
        this.isFinish();
        if (this.startTime && !this.finishTime) {
            for (const [k, player] of this.players.entries()) {
                if (player.key === key) {
                    this.players[k].count += 1;
                }
            }
        }
    }

    context() {
        return {
            start : this.startTime,
            finish : this.finishTime,
            playTime : this.getTimePlayed(),
            players : this.players,
            winCondition : this.winCondition
        }
    }
}

let currentGame = new Party();

function resetGame() {
    currentGame.reset();
}

module.exports = { Party, currentGame, resetGame };