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

/**
 * @title IGenericStateChannelManager
 * @notice State channels with committed stateHash: same as payment channels but settlement attests to an arbitrary stateHash (e.g. game result, attestation).
 */
interface IGenericStateChannelManager {
    enum ChannelStatus {
        None,
        Open,
        Dispute,
        Closed
    }

    struct Channel {
        address participantA;
        address participantB;
        uint256 depositA;
        uint256 depositB;
        ChannelStatus status;
        uint256 disputeNonce;
        bytes32 disputeStateHash;
        uint256 disputeBalanceA;
        uint256 disputeBalanceB;
        uint256 disputeDeadline;
    }

    event ChannelOpened(
        uint256 indexed channelId,
        address indexed participantA,
        address indexed participantB,
        uint256 depositA,
        uint256 depositB
    );

    event ChannelClosed(
        uint256 indexed channelId,
        bytes32 stateHash,
        uint256 balanceA,
        uint256 balanceB,
        bool cooperative
    );

    event ChallengeSubmitted(
        uint256 indexed channelId,
        uint256 nonce,
        bytes32 stateHash,
        uint256 balanceA,
        uint256 balanceB,
        uint256 newDeadline
    );

    event AdminChanged(address indexed newAdmin);
    event Paused();
    event Unpaused();
    event ChallengeWindowUpdated(uint256 oldWindow, uint256 newWindow);

    function openChannel(address participantB) external payable returns (uint256 channelId);
    function fundChannel(uint256 channelId) external payable;

    function closeChannelCooperative(
        uint256 channelId,
        bytes32 stateHash,
        uint256 nonce,
        uint256 balanceA,
        uint256 balanceB,
        uint8 vA,
        bytes32 rA,
        bytes32 sA,
        uint8 vB,
        bytes32 rB,
        bytes32 sB
    ) external;

    function submitClose(
        uint256 channelId,
        bytes32 stateHash,
        uint256 nonce,
        uint256 balanceA,
        uint256 balanceB,
        uint8 vA,
        bytes32 rA,
        bytes32 sA,
        uint8 vB,
        bytes32 rB,
        bytes32 sB
    ) external;

    function challengeClose(
        uint256 channelId,
        bytes32 stateHash,
        uint256 nonce,
        uint256 balanceA,
        uint256 balanceB,
        uint8 vA,
        bytes32 rA,
        bytes32 sA,
        uint8 vB,
        bytes32 rB,
        bytes32 sB
    ) external;

    function finalizeClose(uint256 channelId) external;

    function getChannel(uint256 channelId) external view returns (Channel memory);
    function getChannelCount() external view returns (uint256);
    function getChannelId(address participantA, address participantB) external view returns (uint256);
}
