"use client";

import * as monaco from "monaco-editor";
import { connectToLanguageServer } from "@/lib/lsp";
import { useEffect, useRef, useState } from "react";
import { Editor, loader } from "@monaco-editor/react";
import { MonacoLanguageClient } from "monaco-languageclient";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area";
import { COriginal, CplusplusOriginal, JavaOriginal } from "devicons-react";

const files: {
  [key: string]: { name: string; language: string; value: string };
} = {
  c: {
    name: "main.c",
    language: "c",
    value: `#include <stdio.h>
int main() {
    printf("Hello, World!");
    return 0;
}`,
  },
  cpp: {
    name: "main.cpp",
    language: "cpp",
    value: `#include <iostream>
int main() {
    std::cout << "Hello, World!";
    return 0;
}`,
  },
  java: {
    name: "Main.java",
    language: "java",
    value: `public class Main {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}`,
  },
};

loader.config({ monaco });

export default function PlaygroundPage() {
  const [language, setLanguage] = useState<string>("c");
  const file = files[language];
  const editorRef = useRef<monaco.editor.IStandaloneCodeEditor | null>(null);
  const webSocketRef = useRef<WebSocket | null>(null);
  const languageClientRef = useRef<MonacoLanguageClient | null>(null);

  useEffect(() => {
    const handleLanguageChange = async () => {
      if (editorRef.current) {
        const model = editorRef.current.getModel();
        if (model) {
          const lineCount = model.getLineCount();
          const lastLineLength = model.getLineLength(lineCount);
          editorRef.current.setPosition({
            lineNumber: lineCount,
            column: lastLineLength + 1,
          });
          editorRef.current.focus();
          if (languageClientRef.current) {
            await languageClientRef.current.stop();
            languageClientRef.current = null;
          }
          if (
            webSocketRef.current &&
            webSocketRef.current.readyState !== WebSocket.CLOSED &&
            webSocketRef.current.readyState !== WebSocket.CLOSING
          ) {
            webSocketRef.current.close();
            webSocketRef.current = null;
          }
          try {
            const languageClient = await connectToLanguageServer(
              language,
              webSocketRef
            );
            languageClientRef.current = languageClient;
          } catch (error) {
            console.error("Failed to connect to language server:", error);
          }
        }
      }
    };

    handleLanguageChange();
  }, [language]);

  return (
    <div className="h-full flex flex-col">
      <Tabs defaultValue={language as string}>
        <ScrollArea>
          <TabsList className="m-3">
            <TabsTrigger
              value="c"
              onClick={() => setLanguage("c")}
              disabled={language === "c"}
            >
              <COriginal
                className="-ms-0.5 me-1.5"
                size={16}
                strokeWidth={2}
                aria-hidden="true"
              />
              C
            </TabsTrigger>
            <TabsTrigger
              value="cpp"
              className="group"
              onClick={() => setLanguage("cpp")}
              disabled={language === "cpp"}
            >
              <CplusplusOriginal
                className="-ms-0.5 me-1.5"
                size={16}
                strokeWidth={2}
                aria-hidden="true"
              />
              C++
            </TabsTrigger>
            <TabsTrigger
              value="java"
              className="group"
              onClick={() => setLanguage("java")}
              disabled={language === "java"}
            >
              <JavaOriginal
                className="-ms-0.5 me-1.5"
                size={16}
                strokeWidth={2}
                aria-hidden="true"
              />
              Java
            </TabsTrigger>
          </TabsList>
          <ScrollBar orientation="horizontal" />
        </ScrollArea>
      </Tabs>
      <Editor
        theme="vs-dark"
        path={file.name}
        defaultLanguage={file.language}
        defaultValue={file.value}
        options={{ automaticLayout: true }}
        onMount={(editor) => {
          editorRef.current = editor;
          if (editorRef.current) {
            const model = editorRef.current.getModel();
            if (model) {
              const lineCount = model.getLineCount();
              const lastLineLength = model.getLineLength(lineCount);
              editorRef.current.setPosition({
                lineNumber: lineCount,
                column: lastLineLength + 1,
              });
              editorRef.current.focus();
              connectToLanguageServer(language, webSocketRef)
                .then((languageClient) => {
                  languageClientRef.current = languageClient;
                })
                .catch((error) => {
                  console.error("Failed to connect to language server:", error);
                });
            }
          }
        }}
      />
    </div>
  );
}
