import * as React from 'react';
import { useEffect, useState } from 'react';
import { useStatePersist } from 'use-state-persist';

import * as ReactDOM from 'react-dom';
import { broadcastToRelay, Connect, connectToRelay, ConnectURI } from '@nostr-connect/connect';

import { QRCodeSVG } from 'qrcode.react';
import { getEventHash, getPublicKey, generatePrivateKey, Event } from 'nostr-tools';

const secretKey = generatePrivateKey();
const connectURI = new ConnectURI({
  target: getPublicKey(secretKey),
  relay: 'wss://nostr.vulpem.com',
  metadata: {
    name: 'Example',
    description: '🔉🔉🔉',
    url: 'https://example.com',
    icons: ['https://example.com/icon.png'],
  },
});

const App = () => {
  const [pubkey, setPubkey] = useStatePersist('@pubkey', '');
  const [getPublicKeyReply, setGetPublicKeyReply] = useState('');
  const [eventWithSig, setEvent] = useState({});
  const [schnorrSig, setSchnorrSig] = useState('');
  const [delegationSig, setDelegateSig] = useState('');

  useEffect(() => {
    (async () => {
      const target = pubkey.length > 0 ? pubkey : undefined;
      const connect = new Connect({
        secretKey,
        target,
      });
      connect.events.on('connect', (pubkey: string) => {
        setPubkey(pubkey);
      });
      connect.events.on('disconnect', () => {
        setEvent({});
        setPubkey('');
        setGetPublicKeyReply('');
      });
      await connect.init();
    })();
  }, []);


  const getPub = async () => {
    if (pubkey.length === 0) return;
    const connect = new Connect({
      secretKey,
      target: pubkey,
    });
    const pk = await connect.getPublicKey();
    setGetPublicKeyReply(pk);
  }

  const sendMessage = async () => {
    try {
      if (pubkey.length === 0) return;

      const connect = new Connect({
        secretKey,
        target: pubkey,
      });

      let event: Event = {
        kind: 1,
        pubkey: pubkey,
        created_at: Math.floor(Date.now() / 1000),
        tags: [],
        content: "Running Nostr Connect 🔌",
        id: '',
        sig: '',
      };
      event.id = getEventHash(event)
      event.sig = (await connect.signEvent(event)).sig;
      const relay = await connectToRelay('wss://relay.damus.io');
      await broadcastToRelay(relay, event, true);

      setEvent(event);
    } catch (error) {
      console.error(error);
    }

  }

  const getSchnorrSig = async () => {
    try {
      if (pubkey.length === 0) return;

      const connect = new Connect({
        secretKey,
        target: pubkey,
      });

      const sig = await connect.rpc.call({
        target: pubkey,
        request: {
          method: 'sign_schnorr',
          params: ['Hello World'],
        }
      });
      setSchnorrSig(sig);
    } catch (error) {
      console.error(error);
    }
  }

  const delegate = async () => {
    try {
      if (pubkey.length === 0) return;

      const connect = new Connect({
        secretKey,
        target: pubkey,
      });

      const sig = await connect.rpc.call({
        target: pubkey,
        request: {
          method: 'delegate',
          params: [
            getPublicKey(secretKey),
            {
              kind: 0,
              until: Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 365,
            }
          ],
        }
      });
      setDelegateSig(sig);
    } catch (error) {
      console.error(error);
    }
  }

  const isConnected = () => {
    return pubkey.length > 0;
  }

  const disconnect = async () => {
    const connect = new Connect({
      secretKey,
      target: pubkey,
    });
    await connect.disconnect();
    //cleanup
    setEvent({});
    setPubkey('');
    setGetPublicKeyReply('');
  }

  const copyToClipboard = () => {
    navigator.clipboard.writeText(connectURI.toString()).then(undefined,
      function (err) {
        console.error('Async: Could not copy text: ', err);
      });
  }

  return (
    <div className='hero is-fullheight has-text-dark'>
      <section className="container">
        <div className='content'>
          <h1 className='title'>Nostr Connect Playground</h1>
        </div>
        <div className='content'>
          <p className='subtitle is-6'><b>Nostr ID</b> {getPublicKey(secretKey)}</p>
        </div>
        <div className='content'>
          <p className='subtitle is-6'><b>Status</b> {isConnected() ? '🟢 Connected' : '🔴 Disconnected'}</p>
        </div>
       {
       isConnected() && <div className='content'>
          <button className='button is-danger' onClick={disconnect}>
            <p className='subtitle is-6'>💤 <i>Disconnect</i></p>
          </button>
        </div>
        }
        {!isConnected() && <div className='content has-text-centered'>
          <div className='notification is-dark'>
            <h2 className='title is-5'>Connect with Nostr</h2>


            <QRCodeSVG value={connectURI.toString()} includeMargin={true} />
            <input
              className='input is-info'
              type='text'
              value={connectURI.toString()}
              readOnly
            />
            <button className='button is-info mt-3' onClick={copyToClipboard}>
              Copy to clipboard
            </button>
          </div>
        </div>
        }
        {
          isConnected() &&
          <div className='notification is-dark'>
            <div className='content'>
              <h2 className='title is-5 has-text-white'>Get Public Key</h2>
              <button className='button is-info has-text-white' onClick={getPub}>
                Get public key
              </button>
              {getPublicKeyReply.length > 0 && <input
                className='input is-info mt-3'
                type='text'
                value={getPublicKeyReply}
                readOnly
              />}
            </div>
            <div className='content'>
              <h2 className='title is-5 has-text-white'>Post a message on Damus relay with text <b>Running Nostr Connect 🔌</b></h2>
              <button className='button is-info' onClick={sendMessage}>
                Sign Event
              </button>
              {
                Object.keys(eventWithSig).length > 0 &&
                <textarea
                  className="textarea"
                  readOnly
                  rows={12}
                  defaultValue={JSON.stringify(eventWithSig, null, 2)}
                />
              }
            </div>
            <div className='content'>
              <h2 className='title is-5 has-text-white'>Get a Schnorr signature for the message <b>Hello World</b></h2>
              <button className='button is-info' onClick={getSchnorrSig}>
                Sign Schnorr
              </button>
              {
                Object.keys(schnorrSig).length > 0 &&
                <input
                className='input is-info mt-3'
                type='text'
                value={schnorrSig}
                readOnly
              />
              }
            </div>
            <div className='content'>
              <h2 className='title is-5 has-text-white'>Delegate this app to make signature for 1 day</h2>
              <button className='button is-info' onClick={delegate}>
                Delegate
              </button>
              {
                Object.keys(delegationSig).length > 0 &&
                <input
                className='input is-info mt-3'
                type='text'
                value={delegationSig}
                readOnly
              />
              }
            </div>
          </div>
        }
      </section>
    </div>


  )
}
ReactDOM.render(<App />, document.getElementById('root'));
