// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

/**
 * @title Storage
 * @dev Store & retrieve value in a variable
 * @custom:dev-run-script ./scripts/deploy_with_ethers.ts
 */
contract inheritance {

    uint id;
    mapping(uint => WILL) public wills;
    mapping(address => uint[]) public wills_testator;
    mapping(address => uint[]) public wills_beneficiary;

    enum Status {
        INITIATED_BY_TESTATOR,
        WITHDRAWN_BY_BENEFICIARY,
        AMOUNT_CHANGED,
        DATE_CHANGED
    }
    
    struct WILL {
        uint withdrawDate;
        uint amount;
        address testator;
        address beneficiary;
        Status status;
    }


    constructor() { 
        id = 0;
    }

    function deposit(address _beneficiary, uint _withdrawDate) public payable{
        wills[id] = WILL({
            beneficiary: _beneficiary, 
            amount: msg.value,
            withdrawDate: _withdrawDate,
            testator: msg.sender,
            status: Status.INITIATED_BY_TESTATOR
        });
        wills_testator[msg.sender].push(id);
        wills_beneficiary[_beneficiary].push(id);
        id++;
    }

    function currentDate() public view returns (uint) {
        return block.timestamp;
    }

    function withdrawBeneficiary(uint _id) public {
        require(msg.sender == wills[_id].beneficiary, "You are not the beneficiary!");
        require(wills[_id].amount > 0, "No founds available");
        require(wills[_id].withdrawDate<block.timestamp, "Withdraw date is not reached.");
        payable(msg.sender).transfer(wills[_id].amount);
        wills[_id].amount = 0;
        wills[_id].status = Status.WITHDRAWN_BY_BENEFICIARY;
    }

    function depositmore(uint _id) public payable{
        require(msg.sender == wills[_id].testator, "You are not the testator");
        wills[_id].amount = wills[_id].amount + uint256(msg.value);
        wills[_id].status = Status.AMOUNT_CHANGED;
    }

    function withdrawTestator(uint _id) public payable{
        require(msg.sender == wills[_id].testator, "You are not the testator");
        wills[_id].amount = wills[_id].amount - uint256(msg.value);
        payable(msg.sender).transfer(wills[_id].amount);
        wills[_id].status = Status.AMOUNT_CHANGED;
    }

    function changeWithdrawDate(uint _id, uint _newWithdrawDate) public{
        require(msg.sender == wills[_id].testator, "You are not the testator");
        wills[_id].withdrawDate = _newWithdrawDate;
        wills[_id].status = Status.DATE_CHANGED;
    }

    function get_amount(uint _id) public view returns (uint) {
        return wills[_id].amount;
    }

    function get_wills_testator(address testatorAddress) public view returns (uint[] memory) {
        return wills_testator[testatorAddress) ];
    }

    function get_wills_beneficiary(address beneficiaryAddress) public view returns (uint[] memory){
        return wills_beneficiary[beneficiaryAddress) ];
    }

    



}