// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {UpgradeableBeacon} from  "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol";
import {BeaconProxy} from  "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol";
import {Ownable} from  "@openzeppelin/contracts/access/Ownable.sol";
import {IHotpot} from "./interface/IHotpot.sol";


contract HotpotFactory is Ownable {
    // Hotpot proxies
    address[] public hotpots;
    UpgradeableBeacon public beacon;

    constructor(address _implementation) {
        beacon = new UpgradeableBeacon(_implementation); // the Factory is the _owner of the beacon
    }

    function deployHotpot(IHotpot.InitializeParams calldata params) external onlyOwner returns(address) {
        bytes memory _data = abi.encodeWithSelector(IHotpot.initialize.selector, msg.sender, params);
        BeaconProxy _hotpot = new BeaconProxy(address(beacon), _data);
        hotpots.push(address(_hotpot));
        return address(_hotpot);
    }

    function upgradeImplementation(address _newImplementation) external onlyOwner {
        beacon.upgradeTo(_newImplementation);
    }

}
[{"inputs":[{"internalType":"address","name":"_implementation","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"beacon","outputs":[{"internalType":"contract UpgradeableBeacon","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"potLimit","type":"uint256"},{"internalType":"uint256","name":"raffleTicketCost","type":"uint256"},{"internalType":"uint128","name":"claimWindow","type":"uint128"},{"internalType":"uint16","name":"numberOfWinners","type":"uint16"},{"internalType":"uint16","name":"fee","type":"uint16"},{"internalType":"uint16","name":"tradeFee","type":"uint16"},{"internalType":"address","name":"marketplace","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"internalType":"struct IHotpot.InitializeParams","name":"params","type":"tuple"}],"name":"deployHotpot","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"hotpots","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newImplementation","type":"address"}],"name":"upgradeImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"}]