import { useState, useEffect } from "react";
import { useNavigate, useParams } from "react-router-dom";
import {
  Box,
  Button,
  CircularProgress,
  TextField,
  Typography,
  FormControl,
  InputLabel,
  Select,
  MenuItem,
  Checkbox,
  FormControlLabel,
} from "@mui/material";
import { useGetPublicationsById } from "../../hooks/publications/useGetPublicationById";
import { useCreatePublication } from "../../hooks/publications/useCreatePublication";
import { useUpdatePublication } from "../../hooks/publications/useUpdatePublication";
import type {
  PublicationPayload,
  UpdatePublicationPayload,
} from "../../api/publications";
import { useCategories } from "../../hooks/categories/useCategories";
import { toast } from "react-toastify";

const PublicationForm = () => {
  const { id } = useParams<{ id: string }>();
  const isUpdate = Boolean(id);
  const navigate = useNavigate();

  const [file, setFile] = useState<File | null>(null);
  const [contentType, setContentType] = useState<"image" | "video">("image");
  const [status, setStatus] = useState<"public" | "pending">("public");
  const [description, setDescription] = useState("");
  const [isPinned, setIsPinned] = useState(false);
  const [category, setCategory] = useState<number>(0);

  const { data: publication, isLoading } = useGetPublicationsById(
    id ? Number(id) : undefined
  );
  const { data: categories } = useCategories();
  const createMutation = useCreatePublication();
  const updateMutation = useUpdatePublication();
  const previewUrl = file ? URL.createObjectURL(file) : null;

  useEffect(() => {
    return () => {
      if (previewUrl) URL.revokeObjectURL(previewUrl);
    };
  }, [previewUrl]);

  useEffect(() => {
    if (publication) {
      setContentType(publication.content_type);
      setStatus(publication.status);
      setDescription(publication.description);
      setIsPinned(publication.is_pinned);
      setCategory(publication.category);
    }
  }, [publication]);

  if (isUpdate && isLoading) return <CircularProgress />;

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();

    if (isUpdate && id) {
      const payload: UpdatePublicationPayload = {
        content_type: contentType,
        status,
        description,
        is_pinned: isPinned,
        category,
        file: file ?? undefined,
      };

      updateMutation.mutate(
        { id: Number(id), payload },
        { onSuccess: () => navigate("/publications") }
      );
    } else {
      if (!file) {
        toast.error("File is required");
        return;
      }

      const payload: PublicationPayload = {
        file,
        content_type: contentType,
        status,
        description,
        is_pinned: isPinned,
        category,
      };

      createMutation.mutate(payload, {
        onSuccess: () => navigate("/publications"),
      });
    }
  };

  return (
    <Box sx={{ maxWidth: 600, mx: "auto", mt: 5 }}>
      <Typography variant="h5" mb={3}>
        {isUpdate ? "Update Publication" : "Create Publication"}
      </Typography>

      <form onSubmit={handleSubmit}>
        <FormControl fullWidth sx={{ mb: 3 }}>
          <InputLabel>Content Type</InputLabel>
          <Select
            value={contentType}
            label="Content Type"
            onChange={(e) =>
              setContentType(e.target.value as "image" | "video")
            }
          >
            <MenuItem value="image">Image</MenuItem>
            <MenuItem value="video">Video</MenuItem>
          </Select>
        </FormControl>

        <Box sx={{ mb: 3, textAlign: "center" }}>
          {file &&
            (contentType === "image" ? (
              <Box
                component="img"
                src={previewUrl!}
                alt="New upload"
                sx={{ maxWidth: "100%", maxHeight: 300, borderRadius: 2 }}
              />
            ) : (
              <Box
                component="video"
                src={previewUrl!}
                controls
                sx={{ maxWidth: "100%", maxHeight: 300, borderRadius: 2 }}
              />
            ))}

          {!file &&
            isUpdate &&
            publication &&
            (contentType === publication.content_type ? (
              publication.content_type === "image" && publication.image ? (
                <Box
                  component="img"
                  src={publication.image}
                  alt="Current publication"
                  sx={{ maxWidth: "100%", maxHeight: 300, borderRadius: 2 }}
                />
              ) : publication.video ? (
                <Box
                  component="video"
                  src={publication.video}
                  controls
                  sx={{ maxWidth: "100%", maxHeight: 300, borderRadius: 2 }}
                />
              ) : null
            ) : (
              <Typography
                color="text.secondary"
                sx={{
                  height: 300,
                  display: "flex",
                  alignItems: "center",
                  justifyContent: "center",
                  border: "1px dashed",
                  borderColor: "divider",
                  borderRadius: 2,
                }}
              >
                Current publication is a {publication.content_type}.
                <br />
                Select a new {contentType} file to replace it.
              </Typography>
            ))}
        </Box>

        <Button variant="outlined" component="label" sx={{ mb: 3 }}>
          {file
            ? file.name
            : isUpdate
            ? "Change file"
            : "Select file"}
          <input
            type="file"
            hidden
            accept={`${contentType}/*`}
            onChange={(e) => e.target.files && setFile(e.target.files[0])}
          />
        </Button>

        <TextField
          label="Description"
          value={description}
          onChange={(e) => setDescription(e.target.value)}
          fullWidth
          required
          sx={{ mb: 3 }}
        />

        <FormControl fullWidth sx={{ mb: 3 }}>
          <InputLabel>Status</InputLabel>
          <Select
            value={status}
            label="Status"
            onChange={(e) => setStatus(e.target.value as "public" | "pending")}
          >
            <MenuItem value="public">Public</MenuItem>
            <MenuItem value="pending">Pending</MenuItem>
          </Select>
        </FormControl>

        <FormControlLabel
          control={
            <Checkbox
              checked={isPinned}
              onChange={(e) => setIsPinned(e.target.checked)}
            />
          }
          label="Pinned"
          sx={{ mb: 3 }}
        />

        <TextField
          select
          label="Category"
          value={category}
          onChange={(e) => setCategory(Number(e.target.value))}
          fullWidth
          required
          sx={{ mb: 3 }}
        >
          {categories?.map((cat) => (
            <MenuItem key={cat.pk} value={cat.pk}>
              {cat.name}
            </MenuItem>
          ))}
        </TextField>

        <Button
          variant="contained"
          color="primary"
          type="submit"
          disabled={createMutation.isPending || updateMutation.isPending}
        >
          {isUpdate ? "Update" : "Create"}
        </Button>
      </form>
    </Box>
  );
};

export default PublicationForm;
