import { useEffect, useRef, useState } from 'react';
import styles from './Emulator.module.scss';

type EmulatorSystem = (
  'gb' | 'gbc' | 'gba'
);

type EmulatorCore = (
  'gambatte' | 'mgba'
);

const EMULATOR_SYSTEM_CORES:{ [key in EmulatorSystem]:EmulatorCore } = {
  'gb': 'gambatte',
  'gbc': 'gambatte',
  'gba': 'mgba'
}

export type EmulatorProps = {
  system:EmulatorSystem;
};

type SendEmulatorMessageInit = {
  message:'init';
  core:EmulatorCore;
  system:EmulatorSystem;
  game:string;
  gameName:string;
}

type SendEmulatorMessage = (
  SendEmulatorMessageInit
);

type ReceiveEmulatorOnGameStart = {
  message:'start'
}

type ReceiveEmulatorMessage = (
  ReceiveEmulatorOnGameStart
);

export const Emulator:React.FC<EmulatorProps> = props => {
  const iframeRef = useRef<HTMLIFrameElement>(null);
  const [ hasInit, setHasInit ] = useState(false);

  const send = (msg:SendEmulatorMessage) => {
    iframeRef.current?.contentWindow?.postMessage(msg, '*');
  };

  useEffect(() => {
    if(hasInit) return;
    setHasInit(true);

    send({
      message: 'init',
      core: EMULATOR_SYSTEM_CORES[props.system],
      system: props.system,
      game: '/test.gbc',
      gameName: 'Pokemon - Crystal Version'
    });

    window.onmessage = (e) => {
      if(!e.data) {
        console.error('Invalid message received:', e.data);
        return;
      }
      
      const msg = e.data as ReceiveEmulatorMessage;
      console.log('recv', msg);
      switch(msg.message) {
        case 'start':
          console.log('Game started!');
          break

        default:
          console.error('Invalid message received:', msg);
          break
      }
    };
  }, [ iframeRef ]);

  return (
    <div className={styles.emulator}>
      <div className={[
        styles.emulator__box,
        styles[`emulator__box--${props.system}`]
      ].join(' ')} />

      <iframe
        src="/emulator.html"
        className={styles.emulator__iframe}
        ref={iframeRef}
      />
    </div>
  );
}