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

import "@openzeppelin-contracts/token/ERC20/ERC20.sol";
import "@openzeppelin-contracts/token/ERC20/extensions/ERC20Permit.sol";
import "@openzeppelin-contracts/token/ERC20/extensions/ERC20Votes.sol";

import "./interfaces/ISTNK.sol";
import "./interfaces/IGHST.sol";

contract Ghost is IGHST, ERC20, ERC20Permit, ERC20Votes {
    address public override staking;
    address public override stnk;
    address private _initializer;

    constructor(address _stnk, string memory name, string memory symbol)
        ERC20(name, symbol)
        ERC20Permit(name)
    {
        stnk = _stnk;
        _initializer = msg.sender;
    }

    function initialize(address _staking) external {
        if (msg.sender != _initializer) revert NotStakingContract();
        staking = _staking;
        _initializer = address(0);
    }

    function mint(address _to, uint256 _amount) external override {
        if (msg.sender != staking) revert NotStakingContract();
        _mint(_to, _amount);
    }

    function burn(address _from, uint256 _amount) external override {
        if (msg.sender != staking) revert NotStakingContract();
        _burn(_from, _amount);
    }

    function index() public view override returns (uint256) {
        return ISTNK(stnk).index();
    }

    function balanceFrom(uint256 _amount) public view override returns (uint256) {
        return _amount * index() / 1e18;
    }

    function balanceTo(uint256 _amount) public view override returns (uint256) {
        return _amount * 1e18 / index();
    }

    function _update(address from, address to, uint256 amount) internal override(ERC20, ERC20Votes) {
        super._update(from, to, amount);
    }

    function nonces(address owner) public view virtual override(ERC20Permit, Nonces) returns (uint256) {
        return super.nonces(owner);
    }
}
