// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 <0.9.0;

contract SupplyChain {
    enum Role { Unassigned, Manufacturer, Distributor, Retailer }

    struct Stakeholder {
        Role role;
        bool approved;
    }

    struct EventLog {
        address actor;
        string details;
        uint256 timestamp;
    }

    mapping(address => Stakeholder) public stakeholders;
    EventLog[] public events;

    address public admin;

    event StakeholderRegistered(address indexed user, Role role);
    event StakeholderApproved(address indexed user);
    event SupplyChainEventLogged(address indexed actor, string details, uint256 timestamp);

    modifier onlyAdmin() {
        require(msg.sender == admin, "Only admin");
        _;
    }

    modifier onlyApproved() {
        require(stakeholders[msg.sender].approved, "Not approved");
        _;
    }

    constructor() {
        admin = msg.sender;
    }

    function registerStakeholder(Role role) external {
        require(role != Role.Unassigned, "Invalid role");
        stakeholders[msg.sender] = Stakeholder(role, false);
        emit StakeholderRegistered(msg.sender, role);
    }

    function approveStakeholder(address user) external onlyAdmin {
        stakeholders[user].approved = true;
        emit StakeholderApproved(user);
    }

    function logEvent(string calldata details) external onlyApproved {
        EventLog memory newEvent = EventLog(msg.sender, details, block.timestamp);
        events.push(newEvent);
        emit SupplyChainEventLogged(msg.sender, details, block.timestamp);
    }

    function getAllEvents() external view returns (EventLog[] memory) {
        return events;
    }
}