// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

contract SimplePresaleContract {
    address payable public owner;
    uint8 public currentStage = 1; // Initialize with Stage 1
    uint256[] public stagePrices; // Store the stage prices in wei

    event BuyWithETH(address indexed buyer, uint256 ethAmount, uint256 tokensReceived);

    // Mapping to track the tokens bought by each buyer in each stage
    mapping(address => mapping(uint8 => uint256)) public tokensBoughtByStage;

    constructor() {
        owner = payable(msg.sender);

        // Define the stage prices in wei (you can convert from USD to wei)
        stagePrices = [
            7000000000000000,  // Stage 1: $0.00700
            7700000000000000,  // Stage 2: $0.00770
            8470000000000000,  // Stage 3: $0.00847
            9320000000000000,  // Stage 4: $0.00932
            10250000000000000, // Stage 5: $0.01025
            11280000000000000, // Stage 6: $0.01128
            12410000000000000, // Stage 7: $0.01241
            13650000000000000  // Stage 8: $0.01365
        ];
    }

    // Function to set the current stage by the owner
    function setCurrentStage(uint8 _stage) public onlyOwner {
        require(_stage >= 1 && _stage <= 8, "Invalid stage");
        currentStage = _stage;
    }

    // Fallback function to handle receiving Ether
    receive() external payable {
        uint256 ethAmount = msg.value;
        uint256 tokensToReceive = calculateTokens(ethAmount);
        tokensBoughtByStage[msg.sender][currentStage] += tokensToReceive;
        emit BuyWithETH(msg.sender, ethAmount, tokensToReceive);
        forwardFunds();
    }

    function forwardFunds() internal {
        (bool sent, ) = owner.call{value: msg.value}("");
        require(sent, "Failed to send Ether");
    }

    function calculateTokens(uint256 ethAmount) internal view returns (uint256) {
        require(currentStage >= 1 && currentStage <= 8, "Invalid stage");
        require(ethAmount > 0, "Invalid ether amount");

        // Convert stage price to wei
        uint256 stagePrice = stagePrices[currentStage - 1];

        // Calculate the number of tokens based on ether amount and stage price
        uint256 tokensToReceive = (ethAmount * 1e18) / stagePrice;
        return tokensToReceive;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner can call this function");
        _;
    }
}