import React, { useState, useRef, useEffect } from "react";
import {
  Box,
  Paper,
  Typography,
  CircularProgress,
  Alert,
  Button,
  Stepper,
  Step,
  StepLabel,
} from "@mui/material";
import { useLocation } from "react-router-dom";
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
import AutoFixHighIcon from "@mui/icons-material/AutoFixHigh";
import AuthContainer from "./shared/AuthContainer";
import { useThemeMode } from "../hooks/useThemeMode";
import getTheme from "../config/theme";
import API_CONFIG from "../config/api";

/**
 * Component to display a stepper with three steps: Login, Upload File, and Generate
 *
 * @param {Object} props - Component props
 * @param {number} props.activeStep - Current active step (0-based index)
 * @returns {JSX.Element} Stepper component
 */
const StepsDisplay = ({ activeStep }) => {
  const steps = ["Login", "Upload File", "Generate"];

  return (
    <Box sx={{ width: "100%", mb: 4 }}>
      <Stepper activeStep={activeStep} alternativeLabel>
        {steps.map((label) => (
          <Step key={label}>
            <StepLabel>{label}</StepLabel>
          </Step>
        ))}
      </Stepper>
    </Box>
  );
};

/**
 * Component for creating a new benchmark, including authentication, file upload, and generation initiation
 *
 * @param {Object} props - Component props
 * @param {Function} props.onStartGeneration - Callback when generation starts with sessionId
 * @returns {JSX.Element} BenchmarkCreateForm component
 */
function BenchmarkCreateForm({ onStartGeneration }) {
  const { mode } = useThemeMode();
  const theme = getTheme(mode);
  const [isDragging, setIsDragging] = useState(false);
  const [uploadStatus, setUploadStatus] = useState(null);
  const [isLoading, setIsLoading] = useState(false);
  const [activeStep, setActiveStep] = useState(0);
  const [sessionId, setSessionId] = useState(null);
  const fileInputRef = useRef(null);
  const location = useLocation();

  // Check if we're coming back from an OAuth redirect
  useEffect(() => {
    // If we have code in URL parameters, it's an OAuth callback
    const params = new URLSearchParams(window.location.search);
    if (params.has("code")) {
      console.log("Detected OAuth callback, cleaning URL");

      // Remove the query parameters from the URL without reloading
      window.history.replaceState({}, document.title, window.location.pathname);

      // Check if we have auth data in localStorage after a brief delay to let OAuth process complete
      setTimeout(() => {
        const storedAuth = localStorage.getItem("hf_oauth");
        if (storedAuth) {
          console.log("Found auth data after redirect, refreshing UI state");
          setActiveStep(1); // Move to next step if authenticated
        }
      }, 1000);
    }
  }, [location]);

  const handleDragOver = (e) => {
    e.preventDefault();
    setIsDragging(true);
  };

  const handleDragLeave = () => {
    setIsDragging(false);
  };

  const handleClick = () => {
    fileInputRef.current.click();
  };

  const handleFileChange = (e) => {
    const file = e.target.files[0];
    if (!file) return;

    // Vérifier si c'est un PDF, TXT, HTML ou MD
    if (
      !file.name.endsWith(".pdf") &&
      !file.name.endsWith(".txt") &&
      !file.name.endsWith(".html") &&
      !file.name.endsWith(".md")
    ) {
      setUploadStatus({
        success: false,
        message: "Only PDF, TXT, HTML and MD files are accepted",
      });
      return;
    }

    handleFileUpload(file);
  };

  const handleFileUpload = async (file) => {
    setIsLoading(true);
    setUploadStatus(null);

    try {
      const formData = new FormData();
      formData.append("file", file);

      const response = await fetch(`${API_CONFIG.BASE_URL}/upload`, {
        method: "POST",
        body: formData,
      });

      const result = await response.json();

      if (response.ok) {
        setUploadStatus({
          success: true,
          message: `File ${result.filename} uploaded successfully`,
        });
        // Store the session ID for the benchmark generation
        setSessionId(result.session_id);
        setActiveStep(2); // Advance to Generate step after successful upload
      } else {
        setUploadStatus({
          success: false,
          message: result.error || "Upload failed",
        });
      }
    } catch (error) {
      setUploadStatus({
        success: false,
        message: "Server connection error",
      });
    } finally {
      setIsLoading(false);
    }
  };

  const handleDrop = async (e) => {
    e.preventDefault();
    setIsDragging(false);

    const file = e.dataTransfer.files[0];
    if (!file) {
      setUploadStatus({ success: false, message: "No file detected" });
      return;
    }

    // Vérifier si c'est un PDF, TXT, HTML ou MD
    if (
      !file.name.endsWith(".pdf") &&
      !file.name.endsWith(".txt") &&
      !file.name.endsWith(".html") &&
      !file.name.endsWith(".md")
    ) {
      setUploadStatus({
        success: false,
        message: "Only PDF, TXT, HTML and MD files are accepted",
      });
      return;
    }

    handleFileUpload(file);
  };

  const handleGenerateClick = () => {
    if (onStartGeneration && sessionId) {
      onStartGeneration(sessionId);
    }
  };

  return (
    <>
      <StepsDisplay activeStep={activeStep} />

      {/* Authentication step */}
      {activeStep === 0 && (
        <AuthContainer
          actionText="use this demo"
          onSuccess={() => setActiveStep(1)}
        />
      )}

      {/* File upload step */}
      {activeStep === 1 && (
        <Paper
          elevation={3}
          sx={{
            p: 4,
            mt: 3,
            mb: 3,
            border: isDragging
              ? `2px dashed ${theme.palette.primary.main}`
              : "2px dashed #ccc",
            backgroundColor: isDragging ? "rgba(0, 0, 0, 0.05)" : "transparent",
            display: "flex",
            flexDirection: "column",
            alignItems: "center",
            justifyContent: "center",
            minHeight: 200,
            cursor: "pointer",
            transition: "all 0.3s ease",
          }}
          onDragOver={handleDragOver}
          onDragLeave={handleDragLeave}
          onDrop={handleDrop}
          onClick={handleClick}
        >
          <input
            type="file"
            ref={fileInputRef}
            onChange={handleFileChange}
            accept=".pdf,.txt,.html,.md"
            style={{ display: "none" }}
          />
          <CloudUploadIcon
            sx={{ fontSize: 60, color: "text.secondary", mb: 1 }}
          />
          <Typography variant="h6" component="div" gutterBottom>
            Drag and drop your file here or click to browse
          </Typography>
          <Typography variant="body2" color="text.secondary">
            Accepted formats: PDF, TXT, HTML, MD
          </Typography>

          {isLoading && (
            <Box sx={{ mt: 2 }}>
              <CircularProgress size={30} />
            </Box>
          )}

          {uploadStatus && (
            <Alert
              severity={uploadStatus.success ? "success" : "error"}
              sx={{ mt: 2, width: "100%" }}
            >
              {uploadStatus.message}
            </Alert>
          )}
        </Paper>
      )}

      {/* Generate button step */}
      {activeStep === 2 && (
        <Paper
          elevation={3}
          sx={{
            p: 4,
            mt: 3,
            display: "flex",
            flexDirection: "column",
            alignItems: "center",
            justifyContent: "center",
            minHeight: 200,
          }}
        >
          <AutoFixHighIcon
            sx={{ fontSize: 60, color: "text.secondary", mb: 1 }}
          />
          <Typography variant="h6" component="div" gutterBottom>
            Ready to generate your benchmark
          </Typography>
          <Button
            variant="contained"
            color="primary"
            onClick={handleGenerateClick}
            sx={{ mt: 2 }}
          >
            Generate Benchmark
          </Button>
        </Paper>
      )}
    </>
  );
}

export default BenchmarkCreateForm;
