/*
 * last modified---
 * 	03-12-25 new
 *
 * purpose---
 * 	display UI to restore wallet eNFTs from a backup file
 */

import React, { useState } from 'react';
import Container from 'react-bootstrap/Container';
import Toast from 'react-bootstrap/Toast';
import useEth from './EthContext/useEth';
import LoadingButton from './LoadingButton.jsx';
import NoticeWrongNetwork, { NoticeNoArtifact } from './Notices.jsx';


/* render the page to support display and copy/paste of eNFT JSON + keys
 * @param props.parseRestoreMethod method to process eNFTs after parsing
 * @param props.onSelect method to switch to other pages
 */
function RestoreWallet(props) {
	const { state: { contracts, artifacts } } = useEth();

	// local state for filename to restore from
	const [jsonData, setJsonData] = useState("");

	// local state for file contents display
	const [displayData, setDisplayData] = useState(true);
	const toggleDisplayData = () => setDisplayData(!displayData);

	// restore JSON file and go to Spend screen
	async function restoreJsonFileSpend(resolve, reject) {
		var jsonObj = undefined;
		// make sure we have valid data
		if (jsonData === '') {
			let missing = new Error("No JSON data available; empty file?");
			alert(missing.message);
			reject(missing);
			return false;
		}
		try {
			jsonObj = JSON.parse(jsonData);
		}
		catch (SyntaxError) {
			let badJson = new Error("File text does not parse as JSON");
			console.error("parse error");
			alert(badJson.message);
			reject(badJson);
			return false;
		}
		if (!(jsonObj instanceof Array)) {
			let notEnfts = new Error("Array of eNFTs not found");
			alert(notEnfts.message);
			reject(notEnfts);
			return false;
		}

		// invoke caller's parser which loads eNFTs after parsing
		props.parseRestoreMethod(jsonObj);
		props.onSelect('spendENFTs');
		resolve(true);
		return true;
	}

	// restore JSON file and go to Burn screen
	async function restoreJsonFileBurn(resolve, reject) {
		var jsonObj = undefined;
		// make sure we have valid data
		if (jsonData === '') {
			let missing = new Error("No JSON data available; empty file?");
			alert(missing.message);
			reject(missing);
			return false;
		}
		try {
			jsonObj = JSON.parse(jsonData);
		}
		catch (SyntaxError) {
			let badJson = new Error("File text does not parse as JSON");
			console.error("parse error");
			alert(badJson.message);
			reject(badJson);
			return false;
		}
		if (!(jsonObj instanceof Array)) {
			let notEnfts = new Error("Array of eNFTs not found");
			alert(notEnfts.message);
			reject(notEnfts);
			return false;
		}

		// invoke caller's parser which loads eNFTs after parsing
		props.parseRestoreMethod(jsonObj);
		props.onSelect('burnENFTs');
		resolve(true);
		return true;
	}

	// build the page
	const restorePage =
	<div className="container">
		<Container fluid align="left">
			<h2>Restoring Wallet eNFTs</h2>
			<br/>
			<div className="mb-3">
				<h5>Procedure for Restoring the eNFTs in your Wallet:</h5>
				<ol>
					<li>
						Select a file containing eNFT JSON data, which you
						previously saved in a wallet backup.  (See the 
						"Backup Wallet" page in the Full Navigation Menu to
						make such a backup of your wallet eNFTs.)  The contents
						of this file will be displayed at the bottom of the
						page.  Review this data; it should be an array of
						JSON objects.
					</li>
					<li>
						Use the "Upload to Spend" button to upload these eNFTs
						into the Spend page, so that you can use them to fund
						spends.
					</li>
					<li>
						If you prefer to withdraw some or all of the value of
						these eNFTs from the Enshroud system, use the
						"Upload to Burn" button.
					</li>
					<li>
						After using one of these buttons, you will go to the
						relevant page (Spend or Burn) with your restored eNFTs
						available.  Note that restoration will not work on any
						eNFT which has already been burned previously.
					</li>
					<li>
						<b>Note:</b> normally you will not need to use this
						function.  Instead, simply use the "Refresh" button
						on the Spend or Burn screens to populate the table with
						a list of your existing eNFTs.  This restoration
						mechanism is provided solely for a situation in which
						the Enshroud key servers have suffered a loss of the
						keys necessary to decrypt your eNFTs from the
						blockchain.<br/>
						<i>("Not your keys, not your coins.")</i>
					</li>
				</ol>
			</div>
		</Container>
		<br/>
		<Container fluid align="center">
			{ /* restore eNFTs from local file */ }
			<div className="row mb-3">
				<label className="col-sm-2" htmlFor="jsonInput">
					Import eNFTs from local file:
				</label>
				<div className="col-sm-10">
					<input className="form-control" type="file" id="jsonInput"
						onChange={handleFileChange}
					/>
				</div>
			</div>
			<br/>
			<h4>
				<LoadingButton
					variant="primary"
					buttonStyle="m-3"
					netMethod={(resolve, reject) => restoreJsonFileSpend(resolve, reject)}
					buttonTitle="This parses your saved eNFT JSON data and directs it to the Spend screen"
					buttonText="Upload to Spend"
					buttonIcon="images/file-arrow-up.svg"
				/>
				<br/><br/>
				<LoadingButton
					variant="secondary"
					buttonStyle="m-3"
					netMethod={(resolve, reject) => restoreJsonFileBurn(resolve, reject)}
					buttonTitle="This parses your saved eNFT JSON data and directs it to the Burn screen"
 					buttonText="Upload to Burn"
					buttonIcon="images/file-arrow-up.svg"
				/>
			</h4>
			<br/><br/>
			<Toast show={displayData} className="d-inline-block m-1" bg="info"
				onClose={toggleDisplayData} style={{ minWidth: "768px" }}
			>
				<Toast.Header>
					<strong className="me-auto">
						File contents preview -- if OK click an Upload button
					</strong>
					<small>Click to dismiss</small>
				</Toast.Header>
				<Toast.Body>
					{jsonData}
				</Toast.Body>
			</Toast>
			<br/>
		</Container>
		<br/>
	</div>

	// process file selection
	function handleFileChange(e) {
		const file = e.target.files[0];

		// ensure valid selection
		if (!file) {
			alert("No file selected. Please choose a file.");
			return;
		}
		if (!file.type.startsWith("text") && file.type !== "application/json")
		{
			alert("Unsupported file type.  Please select a text or json file.");
			return;
		}

		// read file
		const reader = new FileReader();
		reader.onload = () => {
			const contents = reader.result;
			if (contents !== jsonData) {
				setJsonData(contents);
			}
		};
		reader.onerror = () => {
			alert("Error reading the file. Please try again.");
		};
		reader.readAsText(file);
		setDisplayData(true);
	}

	// render the page
	return (
		<div id="Restore">
		{
			!artifacts.EnshroudProtocol ? <NoticeNoArtifact /> :
			contracts == null ||
					!contracts["EnshroudProtocol"] ? <NoticeWrongNetwork /> :
				restorePage
		}
		</div>
	);
}

export default RestoreWallet;
