// SPDX-License-Identifier: PROPRIETARY AND MIT
// Copyright (c) 2024-2026 Тарабанов Александр Викторович
// All rights reserved.
//
// This software is proprietary and confidential.
// Unauthorized copying, modification, or distribution is prohibited.
//
// For licensing inquiries: info@hb3-accelerator.com
// Website: https://hb3-accelerator.com
// GitHub: https://github.com/VC-HB3-Accelerator

pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

// ERC-4337 интерфейсы для тестирования
interface IPaymaster {
    function validatePaymasterUserOp(
        UserOperation calldata userOp,
        bytes32 userOpHash,
        uint256 maxCost
    ) external returns (bytes memory context, uint256 validationData);
    
    function postOp(
        PostOpMode mode,
        bytes calldata context,
        uint256 actualGasCost
    ) external;
}

struct UserOperation {
    address sender;
    uint256 nonce;
    bytes initCode;
    bytes callData;
    uint256 callGasLimit;
    uint256 verificationGasLimit;
    uint256 preVerificationGas;
    uint256 maxFeePerGas;
    uint256 maxPriorityFeePerGas;
    bytes paymasterAndData;
    bytes signature;
}

enum PostOpMode {
    opSucceeded,
    opReverted,
    postOpReverted
}

/**
 * @title MockPaymaster
 * @dev Mock контракт для тестирования ERC-4337 Paymaster функциональности
 */
contract MockPaymaster is IPaymaster {
    using SafeERC20 for IERC20;
    
    // События для тестирования
    event PaymasterValidated(address indexed sender, uint256 maxCost);
    event PostOpCalled(PostOpMode mode, uint256 actualGasCost);
    event TokenReceived(address indexed token, uint256 amount);
    
    // Статистика для тестирования
    uint256 public totalValidations;
    uint256 public totalPostOps;
    mapping(address => uint256) public tokenReceived;
    
    /**
     * @dev Валидация UserOperation (всегда успешна для тестов)
     */
    function validatePaymasterUserOp(
        UserOperation calldata userOp,
        bytes32 userOpHash,
        uint256 maxCost
    ) external override returns (bytes memory context, uint256 validationData) {
        // Используем userOpHash для избежания предупреждения
        userOpHash;
        totalValidations++;
        emit PaymasterValidated(userOp.sender, maxCost);
        
        // Возвращаем пустой контекст и 0 (успешная валидация)
        return (abi.encode(userOp.sender, maxCost), 0);
    }
    
    /**
     * @dev Post-operation обработка
     */
    function postOp(
        PostOpMode mode,
        bytes calldata context,
        uint256 actualGasCost
    ) external override {
        // Используем context для избежания предупреждения
        context;
        totalPostOps++;
        emit PostOpCalled(mode, actualGasCost);
    }
    
    /**
     * @dev Получить токены (для тестирования)
     */
    function receiveTokens(address tokenAddress, uint256 amount) external payable {
        if (tokenAddress == address(0)) {
            // Нативные токены
            require(msg.value == amount, "Incorrect native amount");
        } else {
            // ERC20 токены
            IERC20(tokenAddress).safeTransferFrom(msg.sender, address(this), amount);
        }
        
        tokenReceived[tokenAddress] += amount;
        emit TokenReceived(tokenAddress, amount);
    }
    
    /**
     * @dev Получить нативные токены
     */
    receive() external payable {
        tokenReceived[address(0)] += msg.value;
        emit TokenReceived(address(0), msg.value);
    }
    
    /**
     * @dev Получить статистику
     */
    function getStats() external view returns (
        uint256 validations,
        uint256 postOps,
        uint256 nativeReceived
    ) {
        return (
            totalValidations,
            totalPostOps,
            tokenReceived[address(0)]
        );
    }
}
