import React, { useState, useMemo, useEffect } from "react";
import { useLocation, useNavigate } from "react-router-dom";
import { enqueueSnackbar } from "notistack";
import canonicalStringify from "canonical-json";

import {
  Select,
  MenuItem,
  Box,
  Typography,
} from "@mui/material";
import LoadingButton from '@mui/lab/LoadingButton';
import { utf8ToHex } from "@walletconnect/encoding";

import { useWalletConnectContext } from "../context/WalletConnectContext";
import { ENABLE_KYC, HASHED_SUBSCRIBER_ID_KEY } from "../constants";

const SignWithNitroKey = () => {

  const { session, signClient, isSessionLoading } =
    useWalletConnectContext();

  const navigate = useNavigate();
  const location = useLocation();

  useEffect(() => {
    if (isSessionLoading) {
      return;
    }

    if (!session) {
      navigate("/connect-wallet?redirectTo=sign-with-nitro-key", {
        state: location.state,
      });
    }
  }, [session, isSessionLoading, navigate, location.state]);

  const [ethAddress, setEthAddress] = useState("");
  const [ethSignature, setEthSignature] = useState("");

  const [cosmosAddress, setCosmosAddress] = useState("");

  const [isLoading, setIsLoading] = useState(false);

  const subscriberIdHash = useMemo(()=>{
    return localStorage.getItem(HASHED_SUBSCRIBER_ID_KEY);
  }, []);

  useEffect(() => {
    if (!subscriberIdHash) {
      setIsLoading(false);
      enqueueSnackbar("Subscriber ID not found. Please verify your email and try again", { variant: "error" });
    }
  }, [subscriberIdHash]);

  const message = useMemo(() => {
    return {
      msg: "Register my account as a participant on the Laconic network",
      address: ethAddress,
    };
  }, [ethAddress]);

  const signEth = async () => {
    if (session && signClient) {
      try {
        setIsLoading(true);

        enqueueSnackbar("View and sign the message from your Laconic Wallet", { variant: "info" });

        const jsonMessage = canonicalStringify(message);
        const hexMsg = utf8ToHex(jsonMessage, true);
        const receivedEthSig: string = await signClient!.request({
          topic: session!.topic,
          chainId: "eip155:1",
          request: {
            method: "personal_sign",
            params: [hexMsg, ethAddress],
          },
        });
        setIsLoading(false);
        setEthSignature(ethSignature);

        if (ENABLE_KYC) {
          navigate("/user-verification", {
            state: {
              message,
              cosmosAddress,
              receivedEthSig,
            },
          });
        } else {
          navigate("/sign-with-cosmos", {
            state: {
              message,
              cosmosAddress,
              receivedEthSig,
            },
          });
        }
      } catch (error) {
        console.log("err in signing ", error);
        setIsLoading(false);
        enqueueSnackbar("Error signing message", { variant: "error" });
      }
    }
  };

  return (
    <div>
      {session ? (
        <Box
          sx={{
            display: "flex",
            flexDirection: "column",
            marginTop: 6,
            gap: 1,
          }}
        >
          <Typography variant="h5">Sign with Nitro key</Typography>
          <Typography variant="body1">Select Laconic account:</Typography>
          <Select
            labelId="demo-simple-select-label"
            id="demo-simple-select"
            value={cosmosAddress}
            onChange={(e: any) => {
              setCosmosAddress(e.target.value);
            }}
            style={{ maxWidth: "600px", display: "block" }}
          >
            {session?.namespaces.cosmos.accounts.map((address, index) => (
              <MenuItem value={address.split(":")[2]} key={index}>
                {address.split(":")[2]}
              </MenuItem>
            ))}
          </Select>
          <Typography variant="body1">Select Nitro account: </Typography>
          <Select
            labelId="demo-simple-select-label"
            id="demo-simple-select"
            value={ethAddress}
            onChange={(e: any) => {
              setEthAddress(e.target.value);
            }}
            style={{ maxWidth: "600px", display: "block" }}
          >
            {session?.namespaces.eip155.accounts.map((address, index) => (
              <MenuItem value={address.split(":")[2]} key={index}>
                {address.split(":")[2]}
              </MenuItem>
            ))}
          </Select>

          {(Boolean(ethAddress) && Boolean(cosmosAddress)) && (<Box
            sx={{
              backgroundColor: "lightgray",
              padding: 3,
              wordWrap: "break-word",
            }}
          >
            <pre style={{ whiteSpace: "pre-wrap", margin: 0 }}>{canonicalStringify(message, null, 2)} </pre>
          </Box>)}
          <Box>
            <LoadingButton
              variant="contained"
              onClick={signEth}
              disabled={!Boolean(ethAddress) || !subscriberIdHash}
              sx={{ marginTop: 2 }}
              loading={isLoading}
            >
              Sign using Nitro key
            </LoadingButton>
          </Box>
        </Box>
      ) : (
        <>Loading...</>
      )}
    </div>
  );
};

export default SignWithNitroKey;
