// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.19;

import { Kraiken } from "../../src/Kraiken.sol";
import { Stake } from "../../src/Stake.sol";

import { Initializable } from "@openzeppelin/proxy/utils/Initializable.sol";
import { UUPSUpgradeable } from "@openzeppelin/proxy/utils/UUPSUpgradeable.sol";

contract MockOptimizer is Initializable, UUPSUpgradeable {
    Kraiken internal kraiken;
    Stake internal stake;

    // Configurable parameters for sentiment analysis (V1 fallback values)
    uint256 internal _capitalInefficiency = 5 * 10 ** 17; // 50%
    uint256 internal _anchorShare = 5 * 10 ** 17; // 50%
    uint24 internal _anchorWidth = 50; // 50 (V1 used 5 * 10, but that's the same as 50)
    uint256 internal _discoveryDepth = 5 * 10 ** 17; // 50%

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error UnauthorizedAccount(address account);

    function initialize(address _kraiken, address _stake) public virtual initializer {
        _changeAdmin(msg.sender);
        kraiken = Kraiken(_kraiken);
        stake = Stake(_stake);
    }
    /**
     * @dev Throws if called by any account other than the admin.
     */

    modifier onlyAdmin() {
        _checkAdmin();
        _;
    }

    /**
     * @dev Throws if the sender is not the admin.
     */
    function _checkAdmin() internal view virtual {
        if (_getAdmin() != msg.sender) {
            revert UnauthorizedAccount(msg.sender);
        }
    }

    function _authorizeUpgrade(address newImplementation) internal override onlyAdmin { }

    /// @notice Set liquidity parameters for sentiment analysis testing
    /// @param capitalInefficiency Capital inefficiency parameter (0-1e18)
    /// @param anchorShare Anchor share parameter (0-1e18)
    /// @param anchorWidth Anchor width parameter
    /// @param discoveryDepth Discovery depth parameter (0-1e18)
    function setLiquidityParams(uint256 capitalInefficiency, uint256 anchorShare, uint24 anchorWidth, uint256 discoveryDepth) external {
        _capitalInefficiency = capitalInefficiency;
        _anchorShare = anchorShare;
        _anchorWidth = anchorWidth;
        _discoveryDepth = discoveryDepth;
    }

    function calculateSentiment(uint256, uint256) public pure returns (uint256 sentimentValue) {
        return 0;
    }

    /// @notice Computes the staker sentiment based on the proportion of the authorized stake that is currently staked.
    /// @return sentiment A number between 0 and 200 indicating the market sentiment.
    function getSentiment() external view returns (uint256 sentiment) {
        uint256 percentageStaked = stake.getPercentageStaked();
        uint256 averageTaxRate = stake.getAverageTaxRate();
        sentiment = calculateSentiment(averageTaxRate, percentageStaked);
    }

    /// @notice Returns configurable liquidity parameters for testing
    /// @return capitalInefficiency Configurable capital inefficiency
    /// @return anchorShare Configurable anchor share
    /// @return anchorWidth Configurable anchor width
    /// @return discoveryDepth Configurable discovery depth
    function getLiquidityParams() external view returns (uint256 capitalInefficiency, uint256 anchorShare, uint24 anchorWidth, uint256 discoveryDepth) {
        capitalInefficiency = _capitalInefficiency;
        anchorShare = _anchorShare;
        anchorWidth = _anchorWidth;
        discoveryDepth = _discoveryDepth;
    }
}
