import { useEffect, useState } from "react";
import styles from "./chatView.module.css";
import { useStore } from "../store/root";
import { vscode } from "../utils/vscode";
import type { FileInWorkspace, QueueTaskItem } from "@codeflash/types";
import TaskLogging from "./tasksLogging";
import {
  isTaskRunning,
  canRetryTaskInQueue,
  getFileNameFromPath,
  isOutsideModuleRoot,
} from "@codeflash/shared";
import ChatViewBanner from "./chatViewBanner";
import Tooltip from "./tooltip";
import { Options } from "./optimizationQueue";
import FunctionSelector from "./functionSelector";

const ChatView: React.FC = () => {
  const filesInWorkspace = useStore((state) => state.filesInWorkspace);
  const functionsInCurrentContextFile = useStore(
    (state) => state.functionsInCurrentContextFile,
  );
  const focusedTask = useStore((state) =>
    state.queueTasks.find((t) => t.id === state.focusedTaskId),
  );
  const currentRunningTask = useStore((state) =>
    state.queueTasks.find(isTaskRunning),
  );

  return (
    <div className={styles.container}>
      <OptimizeInput
        fileSuggestions={filesInWorkspace}
        functionSuggestions={functionsInCurrentContextFile}
        currentOptimizationTask={
          currentRunningTask && focusedTask?.id == currentRunningTask.id
            ? currentRunningTask
            : undefined
        }
      />
      {focusedTask ? <TaskLogging task={focusedTask} /> : <ChatViewBanner />}
    </div>
  );
};

interface OptimizeInputProps {
  fileSuggestions?: FileInWorkspace[];
  functionSuggestions?: { file: string; functions: string[] };
  currentOptimizationTask: QueueTaskItem | undefined;
  forDemo?: boolean;
}

const OptimizeInput: React.FC<OptimizeInputProps> = ({
  fileSuggestions = [],
  functionSuggestions = { file: "", functions: [] },
  currentOptimizationTask,
  forDemo = false,
}) => {
  const [outsideModuleRoot, setOutsideModuleRoot] = useState<boolean>(false);

  const moduleRoot = useStore((state) => state.moduleRoot);
  const currentFocusedFile = useStore((state) => state.currentFilePath);
  const queueTasks = useStore((state) => state.queueTasks);
  const setActiveTab = useStore((state) => state.setActiveTab);

  const [selectedFile, setSelectedFile] = useState<string>();
  const [selectedFunction, setSelectedFunction] = useState<string>();

  useEffect(() => {
    if (forDemo) {
      return;
    }
    if (selectedFile) {
      const outside = isOutsideModuleRoot(moduleRoot, selectedFile);
      setOutsideModuleRoot(outside);
      if (!outside) {
        requestFunctionsFromFile(selectedFile);
      }
    } else {
      setOutsideModuleRoot(false);
    }
  }, [selectedFile, moduleRoot]);

  // Initialize with current file + request workspace files if not provided
  useEffect(() => {
    if (currentOptimizationTask) {
      return;
    }
    if (currentFocusedFile) {
      setSelectedFile(currentFocusedFile);
      setSelectedFunction(undefined);
    }
  }, [currentFocusedFile]);

  useEffect(() => {
    if (!fileSuggestions.length) {
      vscode.postMessage({ type: "filesInWorkspace" });
    }
  }, []);

  useEffect(() => {
    if (currentOptimizationTask) {
      setSelectedFile(currentOptimizationTask.filepath);
      setSelectedFunction(currentOptimizationTask.functionName);
    }
  }, [currentOptimizationTask]);

  const handleFileSelect = (file: FileInWorkspace) => {
    setSelectedFile(file.abs);
    setSelectedFunction(undefined);
  };

  const handleFunctionSelect = (fn: string) => {
    setSelectedFunction(fn);
  };

  const handleFileRemove = () => {
    setSelectedFile(undefined);
    setSelectedFunction(undefined);
  };

  const handleFunctionRemove = () => {
    setSelectedFunction(undefined);
  };

  const requestFunctionsFromFile = (file?: string) => {
    const finalPath = file || selectedFile;
    if (!finalPath) {
      return;
    }
    vscode.postMessage({
      type: "requestFunctions",
      payload: {
        filePath: finalPath,
      },
    });
  };

  const handleOptimize = () => {
    if (forDemo) {
      vscode.postMessage({
        type: "cancelDemoTask",
      });
      return;
    }

    if (!selectedFile || !selectedFunction) {
      return;
    }

    const existingTask = queueTasks.find(
      (task) =>
        task.filepath === selectedFile &&
        task.functionName === selectedFunction,
    );

    if (isRunning) {
      vscode.postMessage({
        type: "cancelTask",
        payload: { id: existingTask?.id || "" },
      });
      return;
    }

    const allowOptimization = existingTask
      ? canRetryTaskInQueue(existingTask)
      : true;

    if (!allowOptimization) {
      vscode.postMessage({
        type: "showMessage",
        payload: {
          type: "warning",
          message: `This function is already ${existingTask?.status}. View it in the Tasks tab.`,
        },
      });
      return;
    }

    vscode.postMessage({
      type: "optimizeFunction",
      payload: {
        filePath: selectedFile,
        functionName: selectedFunction,
      },
    });
  };

  const isRunning = !!currentOptimizationTask;
  const canOptimize = selectedFile && selectedFunction && !outsideModuleRoot;

  return (
    <div className={styles.optimizeContainer}>
      {/* Running State */}
      {isRunning ? (
        <div className={styles.runningState}>
          <div className={styles.runningInfo}>
            <span className="codicon codicon-loading spin"></span>
            <div className={styles.runningDetails}>
              <span className={styles.runningLabel}>Optimizing</span>
              <span className={styles.runningFunction}>
                {getFileNameFromPath(selectedFile || "")} → {selectedFunction}
              </span>
            </div>
          </div>
          <Tooltip position="left" content="Stop optimization">
            <button
              type="button"
              className={styles.stopButton}
              onClick={handleOptimize}
            >
              <span className="codicon codicon-debug-stop"></span>
            </button>
          </Tooltip>
        </div>
      ) : (
        <>
          {/* Function Selector */}
          <FunctionSelector
            files={fileSuggestions}
            functions={functionSuggestions.functions}
            selectedFile={selectedFile}
            selectedFunction={selectedFunction}
            onFileSelect={handleFileSelect}
            onFunctionSelect={handleFunctionSelect}
            onFileRemove={handleFileRemove}
            onFunctionRemove={handleFunctionRemove}
            disabled={isRunning}
          />

          {/* Warning for files outside module root */}
          {!forDemo && selectedFile && outsideModuleRoot && (
            <div className={styles.warningBanner}>
              <span className="codicon codicon-warning"></span>
              <span>
                This file is outside the module root.{" "}
                <a href="#" onClick={() => setActiveTab("projectConfig")}>
                  Check settings
                </a>
              </span>
            </div>
          )}

          {/* Optimize Button */}
          <div className={styles.actionRow}>
            <Options />
            <button
              type="button"
              className={styles.optimizeButton}
              onClick={handleOptimize}
              disabled={!canOptimize}
            >
              <span className="codicon codicon-zap"></span>
              <span>Optimize</span>
            </button>
          </div>
        </>
      )}
    </div>
  );
};

// Export ChatInput for backward compatibility with demo
export const ChatInput = OptimizeInput;

export default ChatView;
