// SPDX-License-Identifier: MIT
pragma solidity ^0.5.16;

contract Betting {
    struct Bet {
        address payable user;
        string predictedPhrase;
        uint amount;
    }
    
    Bet[] private bets;
    string private parrotPhrase;
    address public owner;
    uint public minimumBetAmount;
    bool public bettingOpen;
    uint public totalPot;

    event BetPlaced(address indexed bettor, string predictedPhrase, uint amount);
    event PhraseSet(string newPhrase);
    event WinnersPaid(uint totalPayout);

    constructor(uint _minimumBetAmount) public {
        owner = msg.sender;
        minimumBetAmount = _minimumBetAmount;
        bettingOpen = true;
    }

    function placeBet(string memory _predictedPhrase) public payable {
        require(bettingOpen, "Betting is currently closed");
        require(msg.value >= minimumBetAmount, "Bet amount must meet the minimum requirement");
        
        bets.push(Bet(msg.sender, _predictedPhrase, msg.value));
        totalPot += msg.value;

        emit BetPlaced(msg.sender, _predictedPhrase, msg.value);
    }

    function setParrotPhrase(string memory _parrotPhrase) public {
        require(msg.sender == owner, "Only owner can set the parrot phrase");
        require(!bettingOpen, "Betting should be closed before setting a new phrase");

        parrotPhrase = _parrotPhrase;
        emit PhraseSet(_parrotPhrase);
    }

    function closeBetting() public {
        require(msg.sender == owner, "Only owner can close the betting");
        bettingOpen = false;
    }

    function openBetting() public {
        require(msg.sender == owner, "Only owner can open the betting");
        bettingOpen = true;
    }
    
    function payWinners() public {
        require(msg.sender == owner, "Only owner can pay the winners");
        require(!bettingOpen, "Betting should be closed before paying winners");

        uint totalPayout = 0;

        for(uint i = 0; i < bets.length; i++) {
            if(keccak256(abi.encodePacked(bets[i].predictedPhrase)) == keccak256(abi.encodePacked(parrotPhrase))) {
                uint payout = bets[i].amount * 2;
                require(payout <= address(this).balance, "Contract balance too low to make payout");
                bets[i].user.transfer(payout);
                totalPayout += payout;
            }
        }

        emit WinnersPaid(totalPayout);

        resetGame();
    }

    function resetGame() private {
        delete bets;
        parrotPhrase = "";
        totalPot = 0;
        bettingOpen = true;
    }
}