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

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

/**
 * @title CWProtocolTreasury
 * @notice Holds protocol-owned liquidity proceeds and fee routing targets for POL flywheel.
 */
contract CWProtocolTreasury is AccessControl {
    using SafeERC20 for IERC20;

    bytes32 public constant FEE_ROUTER_ROLE = keccak256("FEE_ROUTER_ROLE");
    bytes32 public constant POL_OPERATOR_ROLE = keccak256("POL_OPERATOR_ROLE");

    address public buybackExecutor;

    event BuybackExecutorUpdated(address indexed executor);
    event FeeRouted(address indexed token, uint256 amount, address indexed destination);
    event PolPositionRegistered(bytes32 indexed positionId, address indexed venue, address pair, uint256 lpBalance);

    error ZeroAddress();

    mapping(bytes32 => bool) public polPositionRegistered;

    constructor(address admin, address buybackExecutor_) {
        if (admin == address(0)) {
            revert ZeroAddress();
        }
        _grantRole(DEFAULT_ADMIN_ROLE, admin);
        _grantRole(FEE_ROUTER_ROLE, admin);
        _grantRole(POL_OPERATOR_ROLE, admin);
        buybackExecutor = buybackExecutor_;
    }

    function setBuybackExecutor(address executor_) external onlyRole(DEFAULT_ADMIN_ROLE) {
        buybackExecutor = executor_;
        emit BuybackExecutorUpdated(executor_);
    }

    function routeFees(address token, uint256 amount, address destination) external onlyRole(FEE_ROUTER_ROLE) {
        IERC20(token).safeTransfer(destination, amount);
        emit FeeRouted(token, amount, destination);
    }

    function registerPolPosition(
        bytes32 positionId,
        address venue,
        address pair,
        uint256 lpBalance
    ) external onlyRole(POL_OPERATOR_ROLE) {
        polPositionRegistered[positionId] = true;
        emit PolPositionRegistered(positionId, venue, pair, lpBalance);
    }
}
