// src/components/Terminal.tsx
import React, { useEffect, useRef } from 'react';
import { Terminal } from 'xterm';
import { FitAddon } from 'xterm-addon-fit';
import 'xterm/css/xterm.css';


const useTerminalResize = (terminalRef: React.RefObject<HTMLDivElement>, fitAddon: FitAddon) => {
    useEffect(() => {
      const handleResize = () => {
        if (fitAddon && terminalRef.current) {
          fitAddon.fit();
        }
      };
  
      window.addEventListener('resize', handleResize);
  
      // Fit the terminal initially
      handleResize();
  
      return () => {
        window.removeEventListener('resize', handleResize);
      };
    }, [terminalRef, fitAddon]);
  };


function TerminalComponent (p: {websocket: string|null}) {
    const {websocket} = p
    const terminalRef = useRef<HTMLDivElement>(null);
    const terminal = useRef<Terminal | null>(null);
    const fitAddon = useRef<FitAddon | null>(null);

    useEffect(() => {
        if (terminalRef.current) {
            terminal.current = new Terminal();
            fitAddon.current = new FitAddon();
            terminal.current.loadAddon(fitAddon.current);
            terminal.current.open(terminalRef.current);
            fitAddon.current.fit();
            if (websocket == null){
                
                return ()=>{
                    terminal.current?.dispose();
                }
            }
            
            const socket = new WebSocket(websocket);
            

            terminal.current.onResize(
                ({cols, rows}, _)=>{
                    socket.send(JSON.stringify({CommandType: 'resize', Arguments: [cols, rows]}))
                }
            )

            socket.addEventListener('open', () => {
                socket.send(JSON.stringify({CommandType: 'resize', Arguments: [terminal.current?.cols, terminal.current?.rows]}))
            });

            socket.addEventListener('message', (event) => {
                terminal.current?.write(JSON.parse(event.data));
            });

            terminal.current.onData((data) => {
                socket.send(JSON.stringify({CommandType: 'insert', Arguments: [data]}));
            });

            return () => {
                terminal.current?.dispose();
                socket.close();
            };
        }
    }, []);

    useTerminalResize(terminalRef, fitAddon.current!)

    return <div ref={terminalRef} style={{ width: '100%', height: '100%' }}></div>;
};

export default TerminalComponent;
