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

import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "../interfaces/IeMoneyJoin.sol";
import "../../emoney/interfaces/IeMoneyToken.sol";

/**
 * @title eMoneyJoin
 * @notice Adapter for minting and burning eMoney tokens
 * @dev Mint/burn restricted to this adapter, transfer restricted via Compliance Registry
 */
contract eMoneyJoin is IeMoneyJoin, AccessControl, ReentrancyGuard {
    bytes32 public constant VAULT_ROLE = keccak256("VAULT_ROLE");

    mapping(address => bool) public approvedCurrencies;

    constructor(address admin) {
        _grantRole(DEFAULT_ADMIN_ROLE, admin);
    }

    /**
     * @notice Mint eMoney to a borrower
     * @param currency eMoney currency address
     * @param to Recipient address
     * @param amount Amount to mint
     */
    function mint(address currency, address to, uint256 amount) external override nonReentrant onlyRole(VAULT_ROLE) {
        require(approvedCurrencies[currency], "eMoneyJoin: currency not approved");
        require(to != address(0), "eMoneyJoin: zero address");
        require(amount > 0, "eMoneyJoin: zero amount");

        IeMoneyToken token = IeMoneyToken(currency);
        token.mint(to, amount, keccak256("VAULT_BORROW"));

        emit eMoneyMinted(currency, to, amount);
    }

    /**
     * @notice Burn eMoney from a repayer
     * @param currency eMoney currency address
     * @param from Source address
     * @param amount Amount to burn
     */
    function burn(address currency, address from, uint256 amount) external override nonReentrant onlyRole(VAULT_ROLE) {
        require(approvedCurrencies[currency], "eMoneyJoin: currency not approved");
        require(amount > 0, "eMoneyJoin: zero amount");

        IeMoneyToken token = IeMoneyToken(currency);
        token.burn(from, amount, keccak256("VAULT_REPAY"));

        emit eMoneyBurned(currency, from, amount);
    }

    /**
     * @notice Approve a currency for eMoney operations
     * @param currency Currency address
     */
    function approveCurrency(address currency) external onlyRole(DEFAULT_ADMIN_ROLE) {
        approvedCurrencies[currency] = true;
    }

    /**
     * @notice Revoke currency approval
     * @param currency Currency address
     */
    function revokeCurrency(address currency) external onlyRole(DEFAULT_ADMIN_ROLE) {
        approvedCurrencies[currency] = false;
    }
}
