"use client";

import React, { useEffect, useState, useRef } from "react";
import Stats from "./stats";

const Console = () => {
  const [url, setUrl] = useState("");
  const [token, setToken] = useState("");
  const [output, setOutput] = useState<string[]>([]);
  const [input, setInput] = useState<string>("");
  const [cpuStat, setCpuStat] = useState<number>(0);
  const [ramStat, setRamStat] = useState<number>(0);
  const [ramTotal, setRamTotal] = useState<number>(0);
  const [diskUsage, setDiskUsage] = useState<number>(0);
  const [diskTotal, setDiskTotal] = useState<number>(0);
  const [network, setNetwork] = useState({ inbound: 0, outbound: 0 });
  const [uptime, setUptime] = useState<number>(0);

  const websocketRef = useRef<WebSocket | null>(null); // Dodajemy ref do WebSocket
  const textareaRef = useRef<HTMLTextAreaElement>(null); // Dodajemy referencję do textarea

  const fetchData = async () => {
    try {
      const response = await fetch(
        "https://ptero.przeqpiciel.com/api/client/servers/0bf192ab/websocket",
        {
          method: "GET",
          headers: {
            Authorization:
              "Bearer ptlc_aDGU4VHNQuN5t6dyxNzVon3UZLR5ehuySmdR7xsUbMm",
            "Content-Type": "application/json",
          },
        }
      );
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const data = await response.json();
      setUrl(data.data.socket);
      setToken(data.data.token);
    } catch (error) {
      console.error("Error fetching data:", error);
    }
  };

  const fetchStats = async () => {
    setDiskTotal(5);
  };

  useEffect(() => {
    fetchData();
    fetchStats();
  }, []);

  useEffect(() => {
    if (url && token) {
      const websocket = new WebSocket(url);
      websocketRef.current = websocket;

      websocket.onopen = () => {
        console.log("WebSocket connection established.");
        websocket.send(`{"event":"auth","args":["${token}"]}`);
      };

      websocket.onmessage = (event) => {
        const message = JSON.parse(event.data);
        // console.log("Received message:", message.event);

        if (message.event === "token expiring") {
          fetchData();
          websocket.send(`{"event":"auth","args":["${token}"]}`);
          console.log("New token fetched");
        }

        if (message.event === "stats") {
          let data = JSON.parse(JSON.parse(event.data).args[0]);
          setCpuStat(data.cpu_absolute.toFixed(2));
          setRamStat(
            Number((data.memory_bytes / (1024 * 1024 * 1024)).toFixed(2))
          );
          setRamTotal(
            Number((data.memory_limit_bytes / (1024 * 1024 * 1024)).toFixed(2))
          );
          setDiskUsage(
            Number((data.disk_bytes / (1024 * 1024 * 1024)).toFixed(2))
          );
          setNetwork({
            inbound: data.network.rx_bytes,
            outbound: data.network.tx_bytes,
          });
          setUptime(data.uptime);
        }

        if (message.event === "console output") {
          setOutput((prevOutput) => {
            let tmpMessage = JSON.parse(event.data).args[0];
            tmpMessage = tmpMessage.replace(/\u001b\[[0-9;]*m/g, "");
            const newOutput = [...prevOutput, tmpMessage];
            if (newOutput.length > 1000) {
              return newOutput.slice(-1000);
            }
            return newOutput;
          });
        }
      };

      websocket.onclose = () => {
        console.log("WebSocket connection closed.");
      };

      websocket.onerror = (error) => {
        console.error("WebSocket error:", error);
      };

      return () => {
        websocket.close();
      };
    }
  }, [url, token]);

  useEffect(() => {
    if (textareaRef.current) {
      textareaRef.current.scrollTop = textareaRef.current.scrollHeight;
    }
  }, [output]);

  const handleKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === "Enter" && websocketRef.current) {
      console.log("Sending message:", input);
      websocketRef.current.send(`{"event":"send command","args":["${input}"]}`);
      setInput("");
    }
  };

  return (
    <div className="flex gap-4">
      <div className="w-3/5">
        <div>
          <textarea
            className="textarea textarea-bordered text-yellow-200 w-full"
            ref={textareaRef}
            cols={110}
            rows={20}
            value={output.join("\n")}
            readOnly
          />
        </div>
        <div>
          <input
            className="input input-bordered w-full text-yellow-200"
            type="text"
            value={input}
            onChange={(e) => setInput(e.target.value)}
            onKeyPress={handleKeyPress}
          />
        </div>
      </div>
      <div className="w-2/5">
        <Stats
          cpu={cpuStat}
          ramUsage={ramStat}
          ramTotal={ramTotal}
          diskUsage={diskUsage}
          diskTotal={diskTotal}
          network={network}
          uptime={uptime}
        />
      </div>
    </div>
  );
};

export default Console;
