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,
  languageStore,
  LoadingSpinner,
  selectedCityStore,
} 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);

  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(() => {
    selectedCityStore.setIsLocked(true);
    return () => selectedCityStore.setIsLocked(false);
  }, []);

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

  useEffect(() => {}, [newFile, uploadDialogOpen]);

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

      const extension = media.filename.split(".").pop()?.toLowerCase();
      if (extension) {
        if (["glb", "gltf"].includes(extension)) {
          setAvailableMediaTypes([6]);
        } else if (
          ["jpg", "jpeg", "png", "gif", "svg", "webp", "bmp"].includes(
            extension
          )
        ) {
          setAvailableMediaTypes([1, 3, 4, 5]);
        } else if (["mp4", "webm", "mov"].includes(extension)) {
          setAvailableMediaTypes([2]);
        }
      }
    }
  }, [media]);

  useEffect(() => {
    languageStore.setLanguage("ru");
  }, []);

  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);

      const extension = file.name.split(".").pop()?.toLowerCase();
      if (extension) {
        if (["glb", "gltf"].includes(extension)) {
          setAvailableMediaTypes([6]);
          setMediaType(6);
        } else if (
          ["jpg", "jpeg", "png", "gif", "svg", "webp", "bmp"].includes(
            extension
          )
        ) {
          setAvailableMediaTypes([1, 3, 4, 5]);
          setMediaType(1);
        } else if (["mp4", "webm", "mov"].includes(extension)) {
          setAvailableMediaTypes([2]);
          setMediaType(2);
        }
      }

      setUploadDialogOpen(true);
    }
  };

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

    setIsLoading(true);
    setError(null);

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

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

  const handleUploadSuccess = () => {
    if (id) {
      mediaStore.getOneMedia(id);
    }
    setNewFile(null);
    setUploadDialogOpen(false);
    setSuccess(true);
  };

  if (!media && id) {
    return (
      <Box
        sx={{
          display: "flex",
          justifyContent: "center",
          alignItems: "center",
          minHeight: "60vh",
        }}
      >
        <LoadingSpinner message="Загрузка данных медиа..." />
      </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>
  );
});
