/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable @typescript-eslint/no-explicit-any */

import React, { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { Container, Row, Col } from "react-bootstrap";
import { Editor } from "@monaco-editor/react";


import { TestPageNavbar } from "./TestPageNavbar";
import { TestPageMainContent } from "./TestPageMainContent";
import { TestPageLeftContent } from "./TestPageLeftContent";
import { MagicRobotModal } from "../components/pure/MagicRobotModal";
import { ToastNotification } from "../components/pure/ToastNotification";
import { ITestPageViewProps } from "./ITestPageViewProps";


export const TestPageView = ({
  projectName,
  testName,
  decodedTestPath,
  runtime,
  testsExist,
  errorCounts,
  logs,
  isWebSocketConnected,
}: ITestPageViewProps) => {
  const navigate = useNavigate();
  const [showAiderModal, setShowAiderModal] = useState(false);
  const [messageOption, setMessageOption] = useState<"default" | "custom">(
    "default"
  );
  const [customMessage, setCustomMessage] = useState(
    typeof logs["message.txt"] === "string"
      ? logs["message.txt"]
      : "make a script that prints hello"
  );
  const [showToast, setShowToast] = useState(false);
  const [toastMessage, setToastMessage] = useState("");
  const [toastVariant, setToastVariant] = useState<"success" | "danger">(
    "success"
  );
  const [expandedSections, setExpandedSections] = useState({
    standardLogs: true,
    runtimeLogs: true,
    sourceFiles: true,
    buildErrors: true,
  });
  // const [isNavbarCollapsed, setIsNavbarCollapsed] = useState(false);

  // // Extract build errors and warnings relevant to this test
  // const [buildErrors, setBuildErrors] = useState<{
  //   errors: any[];
  //   warnings: any[];
  // }>({ errors: [], warnings: [] });

  // useEffect(() => {
  //   const metafile = logs.build_logs?.metafile;
  //   if (!metafile) {
  //     setBuildErrors({ errors: [], warnings: [] });
  //     return;
  //   }
  //   const sourceFilesSet = new Set<string>();
  //   // Collect all input files from metafile outputs related to this test
  //   Object.entries(metafile.outputs || {}).forEach(([outputPath, output]) => {
  //     // Normalize paths for comparison
  //     const normalizedTestName = testName.replace(/\\/g, "/");
  //     const normalizedEntryPoint = output.entryPoint
  //       ? output.entryPoint.replace(/\\/g, "/")
  //       : "";
  //     if (normalizedEntryPoint.includes(normalizedTestName)) {
  //       Object.keys(output.inputs || {}).forEach((inputPath) => {
  //         sourceFilesSet.add(inputPath.replace(/\\/g, "/"));
  //       });
  //     }
  //   });

  //   // Filter errors and warnings to those originating from source files of this test
  //   const filteredErrors = (logs.build_logs?.errors || []).filter(
  //     (err: any) => {
  //       if (!err.location || !err.location.file) return false;
  //       return sourceFilesSet.has(err.location.file.replace(/\\/g, "/"));
  //     }
  //   );
  //   const filteredWarnings = (logs.build_logs?.warnings || []).filter(
  //     (warn: any) => {
  //       if (!warn.location || !warn.location.file) return false;
  //       return sourceFilesSet.has(warn.location.file.replace(/\\/g, "/"));
  //     }
  //   );

  //   setBuildErrors({ errors: filteredErrors, warnings: filteredWarnings });
  // }, [logs, testName]);

  // // Update customMessage when logs change
  // useEffect(() => {
  //   if (typeof logs["message.txt"] === "string" && logs["message.txt"].trim()) {
  //     setCustomMessage(logs["message.txt"]);
  //   }
  // }, [logs]);

  // // Fetch projects data
  // useEffect(() => {
  //   const fetchProjects = async () => {
  //     try {
  //       // First try to fetch from the API endpoint
  //       try {
  //         const response = await fetch('/api/projects/list');
  //         if (response.ok) {
  //           const projectsData = await response.json();
  //           setProjects(projectsData);
  //           return;
  //         }
  //         // If response is not ok, throw to trigger the catch block
  //         throw new Error(`HTTP ${response.status}: ${response.statusText}`);
  //       } catch (apiError) {
  //         console.warn('API endpoint failed, trying projects.json:', apiError);
  //       }

  //       // Fall back to projects.json
  //       const response = await fetch('/projects.json');
  //       if (response.ok) {
  //         const projectsData = await response.json();
  //         setProjects(projectsData);
  //       } else {
  //         // Throw an error if projects.json doesn't exist
  //         throw new Error('projects.json not found');
  //       }
  //     } catch (error) {
  //       console.error('Error fetching projects:', error);
  //       // Set projects to empty array to show appropriate UI
  //       setProjects([]);
  //     }
  //   };

  //   fetchProjects();
  // }, []);

  // // Use the centralized WebSocket from App context
  // const wsContext = useWebSocket();
  // const ws = wsContext?.ws;
  const [activeTab, setActiveTab] = React.useState("tests.json");
  const [openFiles, setOpenFiles] = useState<Array<{
    path: string;
    content: string;
    language?: string;
  }>>([]);
  const [activeFileIndex, setActiveFileIndex] = useState<number>(-1);
  const [selectedSourcePath, setSelectedSourcePath] = useState<string | null>(
    null
  );
  const [editorTheme, setEditorTheme] = useState<"light" | "vs-dark">(
    "vs-dark"
  );
  // Add state for projects
  const [projects, setProjects] = useState<string[]>([]);

  // Reference to the editor instance and model
  const [editorRef, setEditorRef] = useState<any>(null);
  const [modelRef, setModelRef] = useState<any>(null);

  // Function to open a file in a new tab
  const openFile = (file: {
    path: string;
    content: string;
    language?: string;
  }) => {
    // Check if the file is already open
    const existingIndex = openFiles.findIndex(f => f.path === file.path);
    if (existingIndex !== -1) {
      setActiveFileIndex(existingIndex);
      return;
    }

    // Add the file to open files and set it as active
    setOpenFiles(prev => [...prev, file]);
    setActiveFileIndex(openFiles.length);
  };

  // Function to close a tab
  const closeFile = (index: number) => {
    setOpenFiles(prev => prev.filter((_, i) => i !== index));
    // Adjust active index if needed
    if (activeFileIndex === index) {
      // If closing the active tab, activate the next one or previous one
      if (openFiles.length > 1) {
        setActiveFileIndex(Math.min(index, openFiles.length - 2));
      } else {
        setActiveFileIndex(-1);
      }
    } else if (activeFileIndex > index) {
      setActiveFileIndex(activeFileIndex - 1);
    }
  };

  // Update selectedFile when activeFileIndex changes
  const selectedFile = activeFileIndex >= 0 ? openFiles[activeFileIndex] : null;

  // Debug: track selectedFile changes
  // useEffect(() => {
  //   console.log('selectedFile changed:', {
  //     path: selectedFile?.path,
  //     contentLength: selectedFile?.content?.length,
  //     language: selectedFile?.language
  //   });
  // }, [selectedFile]);

  // Update editor content when selectedFile changes
  useEffect(() => {
    // console.log('selectedFile useEffect triggered', {
    //   selectedFile: selectedFile,
    //   editorRefExists: !!editorRef,
    //   modelRefExists: !!modelRef
    // });

    if (selectedFile && editorRef) {
      console.log('Updating editor for selected file:', selectedFile.path);

      const monaco = (window as any).monaco;
      if (monaco) {
        // Get current model or create a new one if needed
        let currentModel = editorRef.getModel();

        if (!currentModel) {
          // Create a new model if none exists
          currentModel = monaco.editor.createModel(
            selectedFile.content || "// No content",
            selectedFile.language || "plaintext"
          );
          editorRef.setModel(currentModel);
          setModelRef(currentModel);
          console.log('New model created and set');
        } else {
          // Update existing model's value and language if needed
          const currentValue = currentModel.getValue();
          const newValue = selectedFile.content || "// No content";

          // Only update if content has changed
          if (currentValue !== newValue) {
            currentModel.setValue(newValue);
            console.log('Model value updated');
          }

          // Update language if needed
          const currentLanguage = currentModel.getLanguageId();
          const newLanguage = selectedFile.language || "plaintext";
          if (currentLanguage !== newLanguage) {
            monaco.editor.setModelLanguage(currentModel, newLanguage);
            console.log('Model language updated to:', newLanguage);
          }
        }

        // Always reveal the beginning of the file
        editorRef.revealPosition({ lineNumber: 1, column: 1 });
      }
    } else {
      console.log('No selectedFile or editorRef available');
    }
  }, [selectedFile, editorRef, modelRef]);

  return (
    <Container fluid className="px-0">
      <TestPageNavbar
        decodedTestPath={decodedTestPath}
        projectName={projectName}
        runtime={runtime}
        setShowAiderModal={setShowAiderModal}
        isWebSocketConnected={isWebSocketConnected}
      />

      <MagicRobotModal
        customMessage={customMessage}
        isWebSocketConnected={isWebSocketConnected}
        messageOption={messageOption}
        navigate={navigate}
        projectName={projectName}
        runtime={runtime}
        setCustomMessage={setCustomMessage}
        setMessageOption={setMessageOption}
        setShowAiderModal={setShowAiderModal}
        setShowToast={setShowToast}
        setToastMessage={setToastMessage}
        setToastVariant={setToastVariant}
        showAiderModal={showAiderModal}
        testName={testName}
      />

      <Row className="g-0 flex-nowrap overflow-x-auto">
        <Col
          sm={3}
          style={{
            height: "calc(100vh - 56px)",
            overflowY: "auto",
          }}
        >
          <TestPageLeftContent
            projects={projects}
            setExpandedSections={setExpandedSections}
            expandedSections={expandedSections}
            logs={logs}
            setActiveTab={setActiveTab}
            setSelectedFile={openFile}
            runtime={runtime}
            selectedSourcePath={selectedSourcePath}
            activeTab={activeTab}
            setSelectedSourcePath={setSelectedSourcePath}
            projectName={projectName}
            testName={testName}
          />
        </Col>

        {/* <Col sm={2} style={{ height: "calc(100vh - 56px)", overflowY: "auto" }}>
          tabs here
        </Col> */}

        <Col
          sm={8}
          style={{
            height: "calc(100vh - 56px)",
            overflowY: "auto",
            display: "flex",
            flexDirection: "column",
          }}
        >
          {/* Tab Bar */}
          {openFiles.length > 0 && (
            <div style={{
              display: "flex",
              backgroundColor: "#1e1e1e",
              borderBottom: "1px solid #3c3c3c"
            }}>
              {openFiles.map((file, index) => (
                <div
                  key={file.path}
                  style={{
                    padding: "8px 16px",
                    cursor: "pointer",
                    backgroundColor: index === activeFileIndex ? "#2d2d30" : "transparent",
                    color: index === activeFileIndex ? "#ffffff" : "#cccccc",
                    borderRight: "1px solid #3c3c3c",
                    display: "flex",
                    alignItems: "center",
                  }}
                  onClick={() => setActiveFileIndex(index)}
                >
                  <span style={{ marginRight: "8px" }}>
                    {file.path.split('/').pop()}
                  </span>
                  <button
                    onClick={(e) => {
                      e.stopPropagation();
                      closeFile(index);
                    }}
                    style={{
                      background: "none",
                      border: "none",
                      color: "#cccccc",
                      cursor: "pointer",
                      padding: "0",
                      width: "16px",
                      height: "16px",
                      borderRadius: "50%",
                      display: "flex",
                      alignItems: "center",
                      justifyContent: "center",
                    }}
                    onMouseOver={(e) => {
                      e.currentTarget.style.backgroundColor = '#e81123';
                      e.currentTarget.style.color = '#ffffff';
                    }}
                    onMouseOut={(e) => {
                      e.currentTarget.style.backgroundColor = 'transparent';
                      e.currentTarget.style.color = '#cccccc';
                    }}
                  >
                    ×
                  </button>
                </div>
              ))}
            </div>
          )}

          {/* Editor */}
          <div style={{ height: "100%", width: "100%", flexGrow: 1 }} id="editor-wrapper">
            <Editor
              height="100%" // Fill the container
              path={selectedFile?.path || "empty"}
              defaultLanguage={selectedFile?.language || "plaintext"}
              theme={editorTheme}
              options={{
                minimap: { enabled: false },
                fontSize: 14,
                wordWrap: "on",
                automaticLayout: true,
                readOnly: !selectedFile?.path?.includes("source_files"),
                // Configure scrollbars to allow horizontal scrolling to bubble up when appropriate
                scrollbar: {
                  vertical: 'auto',
                  horizontal: 'auto',
                  verticalScrollbarSize: 8,
                  horizontalScrollbarSize: 8,
                  handleMouseWheel: true,
                  // This is the key option: don't always consume mouse wheel events
                  alwaysConsumeMouseWheel: false
                },
                mouseWheelScrollSensitivity: 1,
                fastScrollSensitivity: 1,
                scrollBeyondLastColumn: 0,
                scrollBeyondLastLine: true,
              }}
              onMount={(editor, monaco) => {
                console.log('Editor mounted', {
                  selectedFileAtMount: selectedFile,
                  monacoAvailable: !!monaco
                });

                // Store editor reference
                setEditorRef(editor);

                // Create initial model if selectedFile is available
                if (selectedFile) {
                  const model = monaco.editor.createModel(
                    selectedFile.content || "// Select a file to view its contents",
                    selectedFile.language || "plaintext"
                  );
                  editor.setModel(model);
                  setModelRef(model);
                  console.log('Initial model created and set');
                }

                console.log('Editor reference set');

                // Clean up when editor is unmounted
                return () => {
                  // Dispose of the model if it exists
                  const currentModel = editor.getModel();
                  if (currentModel) {
                    currentModel.dispose();
                  }
                  // Clear the references
                  setEditorRef(null);
                  setModelRef(null);
                };
              }}
            />
          </div>
        </Col>

        <Col
          sm={8}
          style={{
            height: "calc(100vh - 56px)",
            overflowY: "auto",
          }}
        >
          <TestPageMainContent
            selectedFile={selectedFile}
            buildErrors={buildErrors}
            projectName={projectName}
            testName={testName}
            runtime={runtime}
          />
        </Col>

        <Col sm={3} style={{ height: "calc(100vh - 56px)", overflowY: "auto" }}>
          atttibute editor here
        </Col>
        <Col sm={3} style={{ height: "calc(100vh - 56px)", overflowY: "auto" }}>
          tree editor here
        </Col>
      </Row>

      <ToastNotification
        showToast={showToast}
        setShowToast={setShowToast}
        toastVariant={toastVariant}
        toastMessage={toastMessage}
      />
    </Container>
  );
};
