import { useEffect, useState, useRef } from "react";
import { observer } from "mobx-react-lite";
import { useNavigate, useParams } from "react-router-dom";
import {
  Box,
  Button,
  CircularProgress,
  FormControl,
  InputLabel,
  MenuItem,
  Paper,
  Select,
  TextField,
  Typography,
  Alert,
  Snackbar,
} from "@mui/material";
import { Save, ArrowLeft } from "lucide-react";
import { authInstance, mediaStore, MEDIA_TYPE_LABELS } from "@shared";
import { MediaViewer } from "@widgets";

export const MediaEditPage = observer(() => {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState(false);

  const fileInputRef = useRef<HTMLInputElement>(null);
  const [newFile, setNewFile] = useState<File | null>(null);
  const [uploadDialogOpen, setUploadDialogOpen] = useState(false); // State for the upload dialog

  const media = id ? mediaStore.media.find((m) => m.id === id) : null;
  const [mediaName, setMediaName] = useState(media?.media_name ?? "");
  const [mediaFilename, setMediaFilename] = useState(media?.filename ?? "");
  const [mediaType, setMediaType] = useState(media?.media_type ?? 1);
  const [availableMediaTypes, setAvailableMediaTypes] = useState<number[]>([]);

  useEffect(() => {
    if (id) {
      mediaStore.getOneMedia(id);
    }
    console.log(newFile);
    console.log(uploadDialogOpen);
  }, [id]);

  useEffect(() => {
    if (media) {
      setMediaName(media.media_name);
      setMediaFilename(media.filename);
      setMediaType(media.media_type);

      // Set available media types based on current file extension
      const extension = media.filename.split(".").pop()?.toLowerCase();
      if (extension) {
        if (["glb", "gltf"].includes(extension)) {
          setAvailableMediaTypes([6]); // 3D model
        } else if (["jpg", "jpeg", "png", "gif"].includes(extension)) {
          setAvailableMediaTypes([1, 3, 4, 5]); // Photo, Icon, Watermark, Panorama
        } else if (["mp4", "webm", "mov"].includes(extension)) {
          setAvailableMediaTypes([2]); // Video
        }
      }
    }
  }, [media]);

  // const handleDrop = (e: DragEvent<HTMLDivElement>) => {
  //   e.preventDefault();
  //   e.stopPropagation();
  //   setIsDragging(false);

  //   const files = Array.from(e.dataTransfer.files);
  //   if (files.length > 0) {
  //     setNewFile(files[0]);
  //     setMediaFilename(files[0].name);
  //     setUploadDialogOpen(true); // Open dialog on file drop
  //   }
  // };

  // const handleDragOver = (e: DragEvent<HTMLDivElement>) => {
  //   e.preventDefault();
  //   setIsDragging(true);
  // };

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

  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files;
    if (files && files.length > 0) {
      const file = files[0];
      setNewFile(file);
      setMediaFilename(file.name);

      // Determine media type based on file extension
      const extension = file.name.split(".").pop()?.toLowerCase();
      if (extension) {
        if (["glb", "gltf"].includes(extension)) {
          setAvailableMediaTypes([6]); // 3D model
          setMediaType(6);
        } else if (["jpg", "jpeg", "png", "gif"].includes(extension)) {
          setAvailableMediaTypes([1, 3, 4, 5]); // Photo, Icon, Watermark, Panorama
          setMediaType(1); // Default to Photo
        } else if (["mp4", "webm", "mov"].includes(extension)) {
          setAvailableMediaTypes([2]); // Video
          setMediaType(2);
        }
      }

      setUploadDialogOpen(true); // Open dialog on file selection
    }
  };

  const handleSave = async () => {
    if (!id) return;

    setIsLoading(true);
    setError(null);

    try {
      await authInstance.patch(`/media/${id}`, {
        media_name: mediaName,
        filename: mediaFilename,
        type: mediaType,
      });

      // If a new file was selected, the actual file upload will happen
      // via the UploadMediaDialog. We just need to make sure the metadata
      // is updated correctly before or after.
      // Since the dialog handles the actual upload, we don't call updateMediaFile here.

      setSuccess(true);
      handleUploadSuccess();
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to save media");
    } finally {
      setIsLoading(false);
    }
  };

  const handleUploadSuccess = () => {
    // After successful upload in the dialog, refresh media data if needed
    if (id) {
      mediaStore.getOneMedia(id);
    }
    setNewFile(null); // Clear the new file state after successful upload
    setUploadDialogOpen(false);
    setSuccess(true);
  };

  if (!media && id) {
    // Only show loading if an ID is present and media is not yet loaded
    return (
      <Box className="flex justify-center items-center h-screen">
        <CircularProgress />
      </Box>
    );
  }

  return (
    <Box className="p-6 max-w-4xl mx-auto">
      <Box className="flex items-center gap-4 mb-6">
        <Button
          variant="outlined"
          startIcon={<ArrowLeft size={20} />}
          onClick={() => navigate(-1)}
        >
          Назад
        </Button>
        <Typography variant="h5">Редактирование медиа</Typography>
      </Box>

      <Paper className="p-6">
        <input
          type="file"
          ref={fileInputRef}
          className="hidden"
          onChange={handleFileSelect}
          accept="image/*,video/*,.glb,.gltf"
        />
        <Box className="flex flex-col gap-6">
          <Box className="flex gap-4">
            <TextField
              fullWidth
              value={mediaName}
              onChange={(e) => setMediaName(e.target.value)}
              label="Название медиа"
              disabled={isLoading}
            />
            <TextField
              fullWidth
              value={mediaFilename}
              onChange={(e) => setMediaFilename(e.target.value)}
              label="Название файла"
              disabled={isLoading}
            />
          </Box>

          <FormControl fullWidth sx={{ width: "50%" }}>
            <InputLabel>Тип медиа</InputLabel>
            <Select
              value={mediaType}
              label="Тип медиа"
              onChange={(e) => setMediaType(Number(e.target.value))}
              disabled={isLoading}
            >
              {availableMediaTypes.length > 0
                ? availableMediaTypes.map((type) => (
                    <MenuItem key={type} value={type}>
                      {
                        MEDIA_TYPE_LABELS[
                          type as keyof typeof MEDIA_TYPE_LABELS
                        ]
                      }
                    </MenuItem>
                  ))
                : Object.entries(MEDIA_TYPE_LABELS).map(([type, label]) => (
                    <MenuItem key={type} value={Number(type)}>
                      {label}
                    </MenuItem>
                  ))}
            </Select>
          </FormControl>

          <Box className="flex gap-6">
            <Paper
              elevation={2}
              sx={{
                flex: 1,
                p: 2,
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
                minHeight: 400,
              }}
            >
              <MediaViewer
                media={{
                  id: id || "",
                  media_type: mediaType,
                  filename: mediaFilename,
                }}
              />
            </Paper>

            <Box className="flex flex-col gap-4 self-end">
              <Button
                variant="contained"
                color="primary"
                startIcon={<Save size={20} />}
                onClick={handleSave}
                disabled={isLoading || (!mediaName && !mediaFilename)}
              >
                {isLoading ? <CircularProgress size={20} /> : "Сохранить"}
              </Button>
              {/* Only show "Replace file" button if no new file is currently selected */}
            </Box>
          </Box>

          {error && (
            <Typography color="error" className="mt-2">
              {error}
            </Typography>
          )}
          {success && (
            <Typography color="success.main" className="mt-2">
              Медиа успешно сохранено
            </Typography>
          )}
        </Box>
      </Paper>

      <Snackbar
        open={!!error}
        autoHideDuration={6000}
        onClose={() => setError(null)}
      >
        <Alert severity="error" onClose={() => setError(null)}>
          {error}
        </Alert>
      </Snackbar>

      <Snackbar
        open={success}
        autoHideDuration={2000}
        onClose={() => setSuccess(false)}
      >
        <Alert severity="success" onClose={() => setSuccess(false)}>
          Медиа успешно сохранено
        </Alert>
      </Snackbar>
    </Box>
  );
});
