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

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./AIPowerRental.sol";
import "./AITBCPaymentProcessor.sol";

/**
 * @title Escrow Service
 * @dev Advanced escrow service with multi-signature, time-locks, and conditional releases
 * @notice Secure payment holding with automated release conditions and dispute protection
 */
contract EscrowService is Ownable, ReentrancyGuard, Pausable {
    
    // State variables
    IERC20 public aitbcToken;
    AIPowerRental public aiPowerRental;
    AITBCPaymentProcessor public paymentProcessor;
    
    uint256 public escrowCounter;
    uint256 public minEscrowAmount = 1e15; // 0.001 AITBC minimum
    uint256 public maxEscrowAmount = 1e22; // 10,000 AITBC maximum
    uint256 public minTimeLock = 300; // 5 minutes minimum
    uint256 public maxTimeLock = 86400 * 30; // 30 days maximum
    uint256 public defaultReleaseDelay = 3600; // 1 hour default
    uint256 public emergencyReleaseDelay = 86400; // 24 hours for emergency
    uint256 public platformFeePercentage = 50; // 0.5% in basis points
    
    // Structs
    struct EscrowAccount {
        uint256 escrowId;
        address depositor;
        address beneficiary;
        address arbiter;
        uint256 amount;
        uint256 platformFee;
        uint256 releaseTime;
        uint256 creationTime;
        bool isReleased;
        bool isRefunded;
        bool isFrozen;
        EscrowType escrowType;
        ReleaseCondition releaseCondition;
        bytes32 conditionHash;
        string conditionDescription;
        uint256 releaseAttempts;
        uint256 lastReleaseAttempt;
        address[] signatories;
        mapping(address => bool) hasSigned;
        uint256 requiredSignatures;
        uint256 currentSignatures;
    }
    
    struct ConditionalRelease {
        uint256 escrowId;
        bytes32 condition;
        bool conditionMet;
        address oracle;
        uint256 verificationTime;
        string conditionData;
        uint256 confidence;
    }
    
    struct MultiSigRelease {
        uint256 escrowId;
        address[] requiredSigners;
        uint256 signaturesRequired;
        mapping(address => bool) hasSigned;
        uint256 currentSignatures;
        uint256 deadline;
        bool isExecuted;
    }
    
    struct TimeLockRelease {
        uint256 escrowId;
        uint256 lockStartTime;
        uint256 lockDuration;
        uint256 releaseWindow;
        bool canEarlyRelease;
        uint256 earlyReleaseFee;
        bool isReleased;
    }
    
    struct EmergencyRelease {
        uint256 escrowId;
        address initiator;
        string reason;
        uint256 requestTime;
        uint256 votingDeadline;
        mapping(address => bool) hasVoted;
        uint256 votesFor;
        uint256 votesAgainst;
        uint256 totalVotes;
        bool isApproved;
        bool isExecuted;
    }
    
    // Enums
    enum EscrowType {
        Standard,
        MultiSignature,
        TimeLocked,
        Conditional,
        PerformanceBased,
        MilestoneBased,
        Emergency
    }
    
    enum ReleaseCondition {
        Manual,
        Automatic,
        OracleVerified,
        PerformanceMet,
        TimeBased,
        MultiSignature,
        Emergency
    }
    
    enum EscrowStatus {
        Created,
        Funded,
        Locked,
        ConditionPending,
        Approved,
        Released,
        Refunded,
        Disputed,
        Frozen,
        Expired
    }
    
    // Mappings
    mapping(uint256 => EscrowAccount) public escrowAccounts;
    mapping(uint256 => ConditionalRelease) public conditionalReleases;
    mapping(uint256 => MultiSigRelease) public multiSigReleases;
    mapping(uint256 => TimeLockRelease) public timeLockReleases;
    mapping(uint256 => EmergencyRelease) public emergencyReleases;
    mapping(address => uint256[]) public depositorEscrows;
    mapping(address => uint256[]) public beneficiaryEscrows;
    mapping(bytes32 => uint256) public conditionEscrows;
    mapping(address => bool) public authorizedOracles;
    mapping(address => bool) public authorizedArbiters;
    
    // Arrays for tracking
    uint256[] public activeEscrows;
    uint256[] public pendingReleases;
    
    // Events
    event EscrowCreated(
        uint256 indexed escrowId,
        address indexed depositor,
        address indexed beneficiary,
        uint256 amount,
        EscrowType escrowType,
        ReleaseCondition releaseCondition
    );
    
    event EscrowFunded(
        uint256 indexed escrowId,
        uint256 amount,
        uint256 platformFee
    );
    
    event EscrowReleased(
        uint256 indexed escrowId,
        address indexed beneficiary,
        uint256 amount,
        string reason
    );
    
    event EscrowRefunded(
        uint256 indexed escrowId,
        address indexed depositor,
        uint256 amount,
        string reason
    );
    
    event ConditionSet(
        uint256 indexed escrowId,
        bytes32 indexed condition,
        address indexed oracle,
        string conditionDescription
    );
    
    event ConditionMet(
        uint256 indexed escrowId,
        bytes32 indexed condition,
        bool conditionMet,
        uint256 verificationTime
    );
    
    event MultiSignatureRequired(
        uint256 indexed escrowId,
        address[] requiredSigners,
        uint256 signaturesRequired
    );
    
    event SignatureSubmitted(
        uint256 indexed escrowId,
        address indexed signer,
        uint256 currentSignatures,
        uint256 requiredSignatures
    );
    
    event TimeLockSet(
        uint256 indexed escrowId,
        uint256 lockDuration,
        uint256 releaseWindow,
        bool canEarlyRelease
    );
    
    event EmergencyReleaseRequested(
        uint256 indexed escrowId,
        address indexed initiator,
        string reason,
        uint256 votingDeadline
    );
    
    event EmergencyReleaseApproved(
        uint256 indexed escrowId,
        uint256 votesFor,
        uint256 votesAgainst,
        bool approved
    );
    
    event EscrowFrozen(
        uint256 indexed escrowId,
        address indexed freezer,
        string reason
    );
    
    event EscrowUnfrozen(
        uint256 indexed escrowId,
        address indexed unfreezer,
        string reason
    );
    
    event PlatformFeeCollected(
        uint256 indexed escrowId,
        uint256 feeAmount,
        address indexed collector
    );
    
    // Modifiers
    modifier onlyAuthorizedOracle() {
        require(authorizedOracles[msg.sender], "Not authorized oracle");
        _;
    }
    
    modifier onlyAuthorizedArbiter() {
        require(authorizedArbiters[msg.sender], "Not authorized arbiter");
        _;
    }
    
    modifier escrowExists(uint256 _escrowId) {
        require(_escrowId < escrowCounter, "Escrow does not exist");
        _;
    }
    
    modifier onlyParticipant(uint256 _escrowId) {
        require(
            msg.sender == escrowAccounts[_escrowId].depositor ||
            msg.sender == escrowAccounts[_escrowId].beneficiary ||
            msg.sender == escrowAccounts[_escrowId].arbiter,
            "Not escrow participant"
        );
        _;
    }
    
    modifier sufficientBalance(address _user, uint256 _amount) {
        require(aitbcToken.balanceOf(_user) >= _amount, "Insufficient balance");
        _;
    }
    
    modifier sufficientAllowance(address _user, uint256 _amount) {
        require(aitbcToken.allowance(_user, address(this)) >= _amount, "Insufficient allowance");
        _;
    }
    
    modifier escrowNotFrozen(uint256 _escrowId) {
        require(!escrowAccounts[_escrowId].isFrozen, "Escrow is frozen");
        _;
    }
    
    modifier escrowNotReleased(uint256 _escrowId) {
        require(!escrowAccounts[_escrowId].isReleased, "Escrow already released");
        _;
    }
    
    modifier escrowNotRefunded(uint256 _escrowId) {
        require(!escrowAccounts[_escrowId].isRefunded, "Escrow already refunded");
        _;
    }
    
    // Constructor
    constructor(
        address _aitbcToken,
        address _aiPowerRental,
        address _paymentProcessor
    ) {
        aitbcToken = IERC20(_aitbcToken);
        aiPowerRental = AIPowerRental(_aiPowerRental);
        paymentProcessor = AITBCPaymentProcessor(_paymentProcessor);
        escrowCounter = 0;
    }
    
    /**
     * @dev Creates a new escrow account
     * @param _beneficiary Beneficiary address
     * @param _arbiter Arbiter address (can be zero address for no arbiter)
     * @param _amount Amount to lock in escrow
     * @param _escrowType Type of escrow
     * @param _releaseCondition Release condition
     * @param _releaseTime Release time (0 for no time limit)
     * @param _conditionDescription Description of release conditions
     */
    function createEscrow(
        address _beneficiary,
        address _arbiter,
        uint256 _amount,
        EscrowType _escrowType,
        ReleaseCondition _releaseCondition,
        uint256 _releaseTime,
        string memory _conditionDescription
    ) external sufficientBalance(msg.sender, _amount) sufficientAllowance(msg.sender, _amount) nonReentrant whenNotPaused returns (uint256) {
        require(_beneficiary != address(0), "Invalid beneficiary");
        require(_beneficiary != msg.sender, "Cannot be own beneficiary");
        require(_amount >= minEscrowAmount && _amount <= maxEscrowAmount, "Invalid amount");
        require(_releaseTime == 0 || _releaseTime > block.timestamp, "Invalid release time");
        
        uint256 escrowId = escrowCounter++;
        uint256 platformFee = (_amount * platformFeePercentage) / 10000;
        uint256 totalAmount = _amount + platformFee;
        
        escrowAccounts[escrowId] = EscrowAccount({
            escrowId: escrowId,
            depositor: msg.sender,
            beneficiary: _beneficiary,
            arbiter: _arbiter,
            amount: _amount,
            platformFee: platformFee,
            releaseTime: _releaseTime,
            creationTime: block.timestamp,
            isReleased: false,
            isRefunded: false,
            isFrozen: false,
            escrowType: _escrowType,
            releaseCondition: _releaseCondition,
            conditionHash: bytes32(0),
            conditionDescription: _conditionDescription,
            releaseAttempts: 0,
            lastReleaseAttempt: 0,
            signatories: new address[](0),
            requiredSignatures: 0,
            currentSignatures: 0
        });
        
        depositorEscrows[msg.sender].push(escrowId);
        beneficiaryEscrows[_beneficiary].push(escrowId);
        activeEscrows.push(escrowId);
        
        // Transfer tokens to contract
        require(
            aitbcToken.transferFrom(msg.sender, address(this), totalAmount),
            "Escrow funding failed"
        );
        
        emit EscrowCreated(escrowId, msg.sender, _beneficiary, _amount, _escrowType, _releaseCondition);
        emit EscrowFunded(escrowId, _amount, platformFee);
        
        // Setup specific escrow type configurations
        if (_escrowType == EscrowType.TimeLocked) {
            _setupTimeLock(escrowId, _releaseTime - block.timestamp);
        } else if (_escrowType == EscrowType.MultiSignature) {
            _setupMultiSignature(escrowId);
        }
        
        return escrowId;
    }
    
    /**
     * @dev Sets release condition for escrow
     * @param _escrowId ID of the escrow
     * @param _condition Condition hash
     * @param _oracle Oracle address for verification
     * @param _conditionData Condition data
     */
    function setReleaseCondition(
        uint256 _escrowId,
        bytes32 _condition,
        address _oracle,
        string memory _conditionData
    ) external escrowExists(_escrowId) onlyParticipant(_escrowId) escrowNotFrozen(_escrowId) escrowNotReleased(_escrowId) {
        require(authorizedOracles[_oracle] || _oracle == address(0), "Invalid oracle");
        
        EscrowAccount storage escrow = escrowAccounts[_escrowId];
        escrow.conditionHash = _condition;
        
        conditionalReleases[_escrowId] = ConditionalRelease({
            escrowId: _escrowId,
            condition: _condition,
            conditionMet: false,
            oracle: _oracle,
            verificationTime: 0,
            conditionData: _conditionData,
            confidence: 0
        });
        
        conditionEscrows[_condition] = _escrowId;
        
        emit ConditionSet(_escrowId, _condition, _oracle, _conditionData);
    }
    
    /**
     * @dev Verifies and meets release condition
     * @param _escrowId ID of the escrow
     * @param _conditionMet Whether condition is met
     * @param _confidence Confidence level (0-100)
     */
    function verifyCondition(
        uint256 _escrowId,
        bool _conditionMet,
        uint256 _confidence
    ) external onlyAuthorizedOracle escrowExists(_escrowId) escrowNotFrozen(_escrowId) escrowNotReleased(_escrowId) {
        ConditionalRelease storage condRelease = conditionalReleases[_escrowId];
        require(condRelease.oracle == msg.sender, "Not assigned oracle");
        
        condRelease.conditionMet = _conditionMet;
        condRelease.verificationTime = block.timestamp;
        condRelease.confidence = _confidence;
        
        emit ConditionMet(_escrowId, condRelease.condition, _conditionMet, block.timestamp);
        
        if (_conditionMet) {
            _releaseEscrow(_escrowId, "Condition verified and met");
        }
    }
    
    /**
     * @dev Submits signature for multi-signature release
     * @param _escrowId ID of the escrow
     */
    function submitSignature(uint256 _escrowId) 
        external 
        escrowExists(_escrowId) 
        onlyParticipant(_escrowId) 
        escrowNotFrozen(_escrowId) 
        escrowNotReleased(_escrowId) 
    {
        EscrowAccount storage escrow = escrowAccounts[_escrowId];
        MultiSigRelease storage multiSig = multiSigReleases[_escrowId];
        
        require(!escrow.hasSigned[msg.sender], "Already signed");
        require(multiSig.requiredSigners > 0, "Multi-signature not setup");
        
        escrow.hasSigned[msg.sender] = true;
        escrow.currentSignatures++;
        multiSig.currentSignatures++;
        
        emit SignatureSubmitted(_escrowId, msg.sender, escrow.currentSignatures, multiSig.requiredSigners);
        
        if (escrow.currentSignatures >= multiSig.requiredSigners) {
            _releaseEscrow(_escrowId, "Multi-signature requirement met");
        }
    }
    
    /**
     * @dev Releases escrow to beneficiary
     * @param _escrowId ID of the escrow
     * @param _reason Reason for release
     */
    function releaseEscrow(uint256 _escrowId, string memory _reason) 
        external 
        escrowExists(_escrowId) 
        escrowNotFrozen(_escrowId) 
        escrowNotReleased(_escrowId) 
        escrowNotRefunded(_escrowId) 
        nonReentrant 
    {
        EscrowAccount storage escrow = escrowAccounts[_escrowId];
        
        require(
            msg.sender == escrow.depositor ||
            msg.sender == escrow.beneficiary ||
            msg.sender == escrow.arbiter ||
            msg.sender == owner(),
            "Not authorized to release"
        );
        
        // Check release conditions
        if (escrow.releaseCondition == ReleaseCondition.Manual) {
            require(msg.sender == escrow.depositor || msg.sender == escrow.arbiter, "Manual release requires depositor or arbiter");
        } else if (escrow.releaseCondition == ReleaseCondition.TimeBased) {
            require(block.timestamp >= escrow.releaseTime, "Release time not reached");
        } else if (escrow.releaseCondition == ReleaseCondition.OracleVerified) {
            require(conditionalReleases[_escrowId].conditionMet, "Condition not met");
        } else if (escrow.releaseCondition == ReleaseCondition.MultiSignature) {
            require(escrow.currentSignatures >= escrow.requiredSignatures, "Insufficient signatures");
        }
        
        _releaseEscrow(_escrowId, _reason);
    }
    
    /**
     * @dev Refunds escrow to depositor
     * @param _escrowId ID of the escrow
     * @param _reason Reason for refund
     */
    function refundEscrow(uint256 _escrowId, string memory _reason) 
        external 
        escrowExists(_escrowId) 
        escrowNotFrozen(_escrowId) 
        escrowNotReleased(_escrowId) 
        escrowNotRefunded(_escrowId) 
        nonReentrant 
    {
        EscrowAccount storage escrow = escrowAccounts[_escrowId];
        
        require(
            msg.sender == escrow.depositor ||
            msg.sender == escrow.arbiter ||
            msg.sender == owner(),
            "Not authorized to refund"
        );
        
        // Check refund conditions
        if (escrow.releaseCondition == ReleaseCondition.TimeBased) {
            require(block.timestamp < escrow.releaseTime, "Release time passed, cannot refund");
        } else if (escrow.releaseCondition == ReleaseCondition.OracleVerified) {
            require(!conditionalReleases[_escrowId].conditionMet, "Condition met, cannot refund");
        }
        
        escrow.isRefunded = true;
        
        require(
            aitbcToken.transfer(escrow.depositor, escrow.amount),
            "Refund transfer failed"
        );
        
        emit EscrowRefunded(_escrowId, escrow.depositor, escrow.amount, _reason);
    }
    
    /**
     * @dev Requests emergency release
     * @param _escrowId ID of the escrow
     * @param _reason Reason for emergency release
     */
    function requestEmergencyRelease(uint256 _escrowId, string memory _reason) 
        external 
        escrowExists(_escrowId) 
        onlyParticipant(_escrowId) 
        escrowNotFrozen(_escrowId) 
        escrowNotReleased(_escrowId) 
        escrowNotRefunded(_escrowId) 
    {
        EscrowAccount storage escrow = escrowAccounts[_escrowId];
        
        EmergencyRelease storage emergency = emergencyReleases[_escrowId];
        require(emergency.requestTime == 0, "Emergency release already requested");
        
        emergencyReleases[_escrowId] = EmergencyRelease({
            escrowId: _escrowId,
            initiator: msg.sender,
            reason: _reason,
            requestTime: block.timestamp,
            votingDeadline: block.timestamp + emergencyReleaseDelay,
            votesFor: 0,
            votesAgainst: 0,
            totalVotes: 0,
            isApproved: false,
            isExecuted: false
        });
        
        emit EmergencyReleaseRequested(_escrowId, msg.sender, _reason, block.timestamp + emergencyReleaseDelay);
    }
    
    /**
     * @dev Votes on emergency release
     * @param _escrowId ID of the escrow
     * @param _vote True to approve, false to reject
     */
    function voteEmergencyRelease(uint256 _escrowId, bool _vote) 
        external 
        escrowExists(_escrowId) 
        onlyAuthorizedArbiter 
    {
        EmergencyRelease storage emergency = emergencyReleases[_escrowId];
        
        require(emergency.requestTime > 0, "No emergency release requested");
        require(block.timestamp <= emergency.votingDeadline, "Voting deadline passed");
        require(!emergency.hasVoted[msg.sender], "Already voted");
        
        emergency.hasVoted[msg.sender] = true;
        emergency.totalVotes++;
        
        if (_vote) {
            emergency.votesFor++;
        } else {
            emergency.votesAgainst++;
        }
        
        // Check if voting is complete and approved
        if (emergency.totalVotes >= 3 && emergency.votesFor > emergency.votesAgainst) {
            emergency.isApproved = true;
            emit EmergencyReleaseApproved(_escrowId, emergency.votesFor, emergency.votesAgainst, true);
            _releaseEscrow(_escrowId, "Emergency release approved");
        }
    }
    
    /**
     * @dev Freezes an escrow account
     * @param _escrowId ID of the escrow
     * @param _reason Reason for freezing
     */
    function freezeEscrow(uint256 _escrowId, string memory _reason) 
        external 
        escrowExists(_escrowId) 
        escrowNotFrozen(_escrowId) 
    {
        require(
            msg.sender == escrowAccounts[_escrowId].arbiter ||
            msg.sender == owner(),
            "Not authorized to freeze"
        );
        
        escrowAccounts[_escrowId].isFrozen = true;
        
        emit EscrowFrozen(_escrowId, msg.sender, _reason);
    }
    
    /**
     * @dev Unfreezes an escrow account
     * @param _escrowId ID of the escrow
     * @param _reason Reason for unfreezing
     */
    function unfreezeEscrow(uint256 _escrowId, string memory _reason) 
        external 
        escrowExists(_escrowId) 
    {
        require(
            msg.sender == escrowAccounts[_escrowId].arbiter ||
            msg.sender == owner(),
            "Not authorized to unfreeze"
        );
        
        escrowAccounts[_escrowId].isFrozen = false;
        
        emit EscrowUnfrozen(_escrowId, msg.sender, _reason);
    }
    
    /**
     * @dev Authorizes an oracle
     * @param _oracle Address of the oracle
     */
    function authorizeOracle(address _oracle) external onlyOwner {
        require(_oracle != address(0), "Invalid oracle address");
        authorizedOracles[_oracle] = true;
    }
    
    /**
     * @dev Revokes oracle authorization
     * @param _oracle Address of the oracle
     */
    function revokeOracle(address _oracle) external onlyOwner {
        authorizedOracles[_oracle] = false;
    }
    
    /**
     * @dev Authorizes an arbiter
     * @param _arbiter Address of the arbiter
     */
    function authorizeArbiter(address _arbiter) external onlyOwner {
        require(_arbiter != address(0), "Invalid arbiter address");
        authorizedArbiters[_arbiter] = true;
    }
    
    /**
     * @dev Revokes arbiter authorization
     * @param _arbiter Address of the arbiter
     */
    function revokeArbiter(address _arbiter) external onlyOwner {
        authorizedArbiters[_arbiter] = false;
    }
    
    // Internal functions
    
    function _setupTimeLock(uint256 _escrowId, uint256 _duration) internal {
        require(_duration >= minTimeLock && _duration <= maxTimeLock, "Invalid duration");
        
        timeLockReleases[_escrowId] = TimeLockRelease({
            escrowId: _escrowId,
            lockStartTime: block.timestamp,
            lockDuration: _duration,
            releaseWindow: _duration / 10, // 10% of lock duration as release window
            canEarlyRelease: false,
            earlyReleaseFee: 1000, // 10% fee for early release
            isReleased: false
        });
        
        emit TimeLockSet(_escrowId, _duration, _duration / 10, false);
    }
    
    function _setupMultiSignature(uint256 _escrowId) internal {
        EscrowAccount storage escrow = escrowAccounts[_escrowId];
        
        // Default to requiring depositor + beneficiary signatures
        address[] memory requiredSigners = new address[](2);
        requiredSigners[0] = escrow.depositor;
        requiredSigners[1] = escrow.beneficiary;
        
        multiSigReleases[_escrowId] = MultiSigRelease({
            escrowId: _escrowId,
            requiredSigners: requiredSigners,
            signaturesRequired: 2,
            currentSignatures: 0,
            deadline: block.timestamp + 7 days,
            isExecuted: false
        });
        
        escrow.requiredSignatures = 2;
        
        emit MultiSignatureRequired(_escrowId, requiredSigners, 2);
    }
    
    function _releaseEscrow(uint256 _escrowId, string memory _reason) internal {
        EscrowAccount storage escrow = escrowAccounts[_escrowId];
        
        escrow.isReleased = true;
        escrow.lastReleaseAttempt = block.timestamp;
        
        // Transfer amount to beneficiary
        require(
            aitbcToken.transfer(escrow.beneficiary, escrow.amount),
            "Escrow release failed"
        );
        
        // Transfer platform fee to owner
        if (escrow.platformFee > 0) {
            require(
                aitbcToken.transfer(owner(), escrow.platformFee),
                "Platform fee transfer failed"
            );
            
            emit PlatformFeeCollected(_escrowId, escrow.platformFee, owner());
        }
        
        emit EscrowReleased(_escrowId, escrow.beneficiary, escrow.amount, _reason);
    }
    
    // View functions
    
    /**
     * @dev Gets escrow account details
     * @param _escrowId ID of the escrow
     */
    function getEscrowAccount(uint256 _escrowId) 
        external 
        view 
        escrowExists(_escrowId) 
        returns (EscrowAccount memory) 
    {
        return escrowAccounts[_escrowId];
    }
    
    /**
     * @dev Gets conditional release details
     * @param _escrowId ID of the escrow
     */
    function getConditionalRelease(uint256 _escrowId) 
        external 
        view 
        returns (ConditionalRelease memory) 
    {
        return conditionalReleases[_escrowId];
    }
    
    /**
     * @dev Gets multi-signature release details
     * @param _escrowId ID of the escrow
     */
    function getMultiSigRelease(uint256 _escrowId) 
        external 
        view 
        returns (MultiSigRelease memory) 
    {
        return multiSigReleases[_escrowId];
    }
    
    /**
     * @dev Gets time-lock release details
     * @param _escrowId ID of the escrow
     */
    function getTimeLockRelease(uint256 _escrowId) 
        external 
        view 
        returns (TimeLockRelease memory) 
    {
        return timeLockReleases[_escrowId];
    }
    
    /**
     * @dev Gets emergency release details
     * @param _escrowId ID of the escrow
     */
    function getEmergencyRelease(uint256 _escrowId) 
        external 
        view 
        returns (EmergencyRelease memory) 
    {
        return emergencyReleases[_escrowId];
    }
    
    /**
     * @dev Gets all escrows for a depositor
     * @param _depositor Address of the depositor
     */
    function getDepositorEscrows(address _depositor) 
        external 
        view 
        returns (uint256[] memory) 
    {
        return depositorEscrows[_depositor];
    }
    
    /**
     * @dev Gets all escrows for a beneficiary
     * @param _beneficiary Address of the beneficiary
     */
    function getBeneficiaryEscrows(address _beneficiary) 
        external 
        view 
        returns (uint256[] memory) 
    {
        return beneficiaryEscrows[_beneficiary];
    }
    
    /**
     * @dev Gets active escrows
     */
    function getActiveEscrows() 
        external 
        view 
        returns (uint256[] memory) 
    {
        uint256[] memory active = new uint256[](activeEscrows.length);
        uint256 activeCount = 0;
        
        for (uint256 i = 0; i < activeEscrows.length; i++) {
            EscrowAccount storage escrow = escrowAccounts[activeEscrows[i]];
            if (!escrow.isReleased && !escrow.isRefunded) {
                active[activeCount] = activeEscrows[i];
                activeCount++;
            }
        }
        
        // Resize array to active count
        assembly {
            mstore(active, activeCount)
        }
        
        return active;
    }
    
    /**
     * @dev Emergency pause function
     */
    function pause() external onlyOwner {
        _pause();
    }
    
    /**
     * @dev Unpause function
     */
    function unpause() external onlyOwner {
        _unpause();
    }
}
