/*
 * last modified---
 * 	10-25-24 add state for timelocks
 * 	08-15-24 real version
 * 	07-26-24 new (stub)
 *
 * purpose---
 * 	provide stakings UI for user MVO staking management
 */

import 'bootstrap/dist/css/bootstrap.min.css';
import '../Enshroud.css';
import { useState } from 'react';
import useEth from '../EthContext/useEth';
import NoticeWrongNetwork, { NoticeNoArtifact } from '../Notices.jsx';
import { MVOStaking } from '../MVOs.js';
import MVOManagement from './MVOManagement.jsx';
const BigNumber = require("bignumber.js");


/* framework for holding state and displaying MVO staking-related UI
 * @param props dummy variable (cue to React)
 */
function MVOStakingUX(props) {
	// enable use of contracts and accounts
	const { state } = useEth();

	// state for the current user's balance in $ENSHROUD tokens
	const [userTokens, setUserTokens] = useState("0");

	// initialize a MVOStaking object that won't break rendering
	function initEmptyStaking() {
		const staking = new MVOStaking();
		// NB: constructor sets 0n, which web3.utils.fromWei() rejects
		staking.stakingQuantum = "0";
	}

	// state for the fetched MVO staking record
	const [mvoStaking, setMVOStaking] = useState(initEmptyStaking);

	// state for whether the fetching user owns the MVO staking record
	const [stakingAuth, setStakingAuth] = useState(false);

	// state for the Timelock user has in the MVOStaking contract (if any)
	const [userTimelock, setUserTimelock] = useState({
		totalAmount: "0",
		remainingAmount: "0",
		releaseStart: "0",
		releaseEnd: "0"
	});

	// state for the Timelock user has in the TimelockManager contract (if any)
	const [managerTimelock, setManagerTimelock] = useState({
		totalAmount: "0",
		remainingAmount: "0",
		releaseStart: "0",
		releaseEnd: "0"
	});

	// state for withdrawable unlocked amount from TimelockManager Timelock
	const [withdrawable, setWithdrawable] = useState(new BigNumber(0));

	// state for the MVOStaking.minStake value on this chain
	const [minStaking, setMinStaking] = useState(0);

	/* method to set user balance of $ENSHROUD tokens
	 * @param newBal the balance in wei
	 */
	function handleSetBalance(newBal) {
		if (newBal >= 0) {
			setUserTokens(newBal);
		}
	}

	/* method to set MVO staking record (a {MVOStaking} from ../MVOs.js)
	 * @param staking the MVOStaking record fetched from the contract
	 */
	function handleSetStaking(staking) {
		if (staking.signingAddress !== '') {
			setMVOStaking(staking);
		}
		else {
			console.error("Staking record appears invalid");
		}
	}

	/* method to set whether current user account is the owner of the record
	 * @param isAuth true or false depending on ownership
	 */
	function handleStakingAuth(isAuth) {
		setStakingAuth(isAuth);
	}

	/* method to set MVOStaking Timelock record
	 * @param timelock the timelock fetched (could be all empty values)
	 */
	function setMVOTimelock(timelock) {
		if (timelock !== undefined) {
			if (timelock.totalAmount > 0) {
				// looks like a valid record
				setUserTimelock(userTimelock => ({...userTimelock,
								totalAmount: timelock.totalAmount,
								remainingAmount: timelock.remainingAmount,
								releaseStart: timelock.releaseStart,
								releaseEnd: timelock.releaseEnd}));
			}
		}
	}

	/* method to set TimelockManager Timelock record
	 * @param timelock the timelock fetched (could be all empty values)
	 */
	function setTMTimelock(timelock) {
		if (timelock !== undefined) {
			// NB: this one can actually get deleted entirely
			if (timelock.totalAmount >= 0) {
				// looks like a valid record
				setManagerTimelock(managerTimelock => ({...managerTimelock,
									totalAmount: timelock.totalAmount,
									remainingAmount: timelock.remainingAmount,
									releaseStart: timelock.releaseStart,
									releaseEnd: timelock.releaseEnd}));
			}
		}
	}

	/* method to set withdrawable (unlocked) tokens in TimelockManager Timelock
	 * @param unlocked the number of $ENSHROUD tokens which can be withdrawn
	 */
	function setTMUnlocked(unlocked) {
		let uTokens = new BigNumber(unlocked);
		if (uTokens.gte(0)) {
			setWithdrawable(uTokens);
		}
	}

	// build output
	const mvoStakingUI =
		<>
			<div className="container">
				<MVOManagement
					userTokens={userTokens}
					setUserTokens={handleSetBalance}
					mvoStaking={mvoStaking}
					setStaking={handleSetStaking}
					isAuth={stakingAuth}
					setAuth={handleStakingAuth}
					minStaking={minStaking}
					setMinStaking={setMinStaking}
					timeLock={userTimelock}
					setMVOTimelock={setMVOTimelock}
					mgrTimelock={managerTimelock}
					setTMTimelock={setTMTimelock}
					withdrawable={withdrawable}
					setUnlocked={setTMUnlocked}
				/>
			</div>
		</>;

	// render output as appropriate
	return (
		<div id="MvoStakingConf">
		{
			!state.artifacts.EnshroudToken ? <NoticeNoArtifact /> :
			state.contracts == null
				|| !state.contracts["EnshroudToken"] ? <NoticeWrongNetwork /> :
				mvoStakingUI
		}
		</div>
	);
}

export default MVOStakingUX;
