import React, { useState, useEffect, useCallback } from "react";
import axios from "axios";
import {
  Upload,
  Image as ImageIcon,
  FileText,
  Video,
  File,
  Trash2,
  Copy,
  Check,
  Search,
  Grid,
  List,
  Download,
  Edit2,
  X,
  Loader2,
  Filter,
} from "lucide-react";
import { Button } from "./ui/button";
import { Input } from "./ui/input";
import { Label } from "./ui/label";
import { Textarea } from "./ui/textarea";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from "./ui/dialog";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "./ui/alert-dialog";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "./ui/select";
import { toast } from "sonner";
import { useAuth } from "../context/AuthContext";

const API = `${process.env.REACT_APP_BACKEND_URL}/api`;

const MediaManager = ({ onSelect, selectable = false }) => {
  const { token } = useAuth();
  const [media, setMedia] = useState([]);
  const [loading, setLoading] = useState(true);
  const [uploading, setUploading] = useState(false);
  const [page, setPage] = useState(1);
  const [totalPages, setTotalPages] = useState(1);
  const [total, setTotal] = useState(0);
  const [search, setSearch] = useState("");
  const [mediaType, setMediaType] = useState("all");
  const [viewMode, setViewMode] = useState("grid");
  const [selectedMedia, setSelectedMedia] = useState(null);
  const [editDialog, setEditDialog] = useState(false);
  const [deleteDialog, setDeleteDialog] = useState(false);
  const [mediaToDelete, setMediaToDelete] = useState(null);
  const [editForm, setEditForm] = useState({
    alt_text: "",
    title: "",
    description: "",
  });
  const [copiedId, setCopiedId] = useState(null);
  const [dragActive, setDragActive] = useState(false);

  const fetchMedia = useCallback(async () => {
    try {
      setLoading(true);
      const params = new URLSearchParams({
        page: page.toString(),
        limit: "24",
      });
      if (search) params.append("search", search);
      if (mediaType !== "all") params.append("media_type", mediaType);

      const response = await axios.get(`${API}/media?${params}`, {
        headers: { Authorization: `Bearer ${token}` },
      });

      setMedia(response.data.items);
      setTotalPages(response.data.pages);
      setTotal(response.data.total);
    } catch (error) {
      console.error("Error fetching media:", error);
      toast.error("Failed to load media");
    } finally {
      setLoading(false);
    }
  }, [token, page, search, mediaType]);

  useEffect(() => {
    fetchMedia();
  }, [fetchMedia]);

  const handleUpload = async (files) => {
    if (!files || files.length === 0) return;

    setUploading(true);
    const formData = new FormData();

    if (files.length === 1) {
      formData.append("file", files[0]);

      try {
        await axios.post(`${API}/media/upload`, formData, {
          headers: {
            Authorization: `Bearer ${token}`,
            "Content-Type": "multipart/form-data",
          },
        });
        toast.success("File uploaded successfully");
        fetchMedia();
      } catch (error) {
        console.error("Upload error:", error);
        toast.error(error.response?.data?.detail || "Upload failed");
      }
    } else {
      // Multiple files
      for (const file of files) {
        formData.append("files", file);
      }

      try {
        const response = await axios.post(
          `${API}/media/upload-multiple`,
          formData,
          {
            headers: {
              Authorization: `Bearer ${token}`,
              "Content-Type": "multipart/form-data",
            },
          },
        );
        toast.success(`${response.data.total_uploaded} files uploaded`);
        if (response.data.total_errors > 0) {
          toast.warning(`${response.data.total_errors} files failed to upload`);
        }
        fetchMedia();
      } catch (error) {
        console.error("Upload error:", error);
        toast.error("Upload failed");
      }
    }

    setUploading(false);
  };

  const handleDrag = (e) => {
    e.preventDefault();
    e.stopPropagation();
    if (e.type === "dragenter" || e.type === "dragover") {
      setDragActive(true);
    } else if (e.type === "dragleave") {
      setDragActive(false);
    }
  };

  const handleDrop = (e) => {
    e.preventDefault();
    e.stopPropagation();
    setDragActive(false);

    if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
      handleUpload(Array.from(e.dataTransfer.files));
    }
  };

  const handleFileSelect = (e) => {
    if (e.target.files && e.target.files.length > 0) {
      handleUpload(Array.from(e.target.files));
    }
  };

  const copyUrl = (url) => {
    const fullUrl = `${process.env.REACT_APP_BACKEND_URL}${url}`;
    navigator.clipboard.writeText(fullUrl);
    setCopiedId(url);
    toast.success("URL copied to clipboard");
    setTimeout(() => setCopiedId(null), 2000);
  };

  const openEditDialog = (item) => {
    setSelectedMedia(item);
    setEditForm({
      alt_text: item.alt_text || "",
      title: item.title || "",
      description: item.description || "",
    });
    setEditDialog(true);
  };

  const handleUpdate = async () => {
    try {
      const formData = new FormData();
      formData.append("alt_text", editForm.alt_text);
      formData.append("title", editForm.title);
      formData.append("description", editForm.description);

      await axios.put(`${API}/media/${selectedMedia.id}`, formData, {
        headers: { Authorization: `Bearer ${token}` },
      });

      toast.success("Media updated");
      setEditDialog(false);
      fetchMedia();
    } catch (error) {
      toast.error("Failed to update media");
    }
  };

  const confirmDelete = (item) => {
    setMediaToDelete(item);
    setDeleteDialog(true);
  };

  const handleDelete = async () => {
    try {
      await axios.delete(`${API}/media/${mediaToDelete.id}`, {
        headers: { Authorization: `Bearer ${token}` },
      });
      toast.success("Media deleted");
      setDeleteDialog(false);
      setMediaToDelete(null);
      fetchMedia();
    } catch (error) {
      toast.error("Failed to delete media");
    }
  };

  const getMediaIcon = (type) => {
    switch (type) {
      case "image":
        return <ImageIcon className="h-8 w-8" />;
      case "video":
        return <Video className="h-8 w-8" />;
      case "document":
        return <FileText className="h-8 w-8" />;
      default:
        return <File className="h-8 w-8" />;
    }
  };

  const formatFileSize = (bytes) => {
    if (bytes === 0) return "0 Bytes";
    const k = 1024;
    const sizes = ["Bytes", "KB", "MB", "GB"];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
  };

  const handleMediaSelect = (item) => {
    if (selectable && onSelect) {
      onSelect(item);
    } else {
      setSelectedMedia(item);
    }
  };

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex flex-col md:flex-row gap-4 items-start md:items-center justify-between">
        <div>
          <h2 className="text-2xl font-bold font-['Outfit']">Media Library</h2>
          <p className="text-muted-foreground">
            {total} files • Upload and manage your images and documents
          </p>
        </div>
        <div className="flex gap-2">
          <Button
            variant={viewMode === "grid" ? "default" : "outline"}
            size="icon"
            onClick={() => setViewMode("grid")}
          >
            <Grid className="h-4 w-4" />
          </Button>
          <Button
            variant={viewMode === "list" ? "default" : "outline"}
            size="icon"
            onClick={() => setViewMode("list")}
          >
            <List className="h-4 w-4" />
          </Button>
        </div>
      </div>

      {/* Upload Area */}
      <div
        className={`border-2 border-dashed rounded-xl p-8 text-center transition-colors ${
          dragActive
            ? "border-primary bg-primary/5"
            : "border-border hover:border-primary/50"
        }`}
        onDragEnter={handleDrag}
        onDragLeave={handleDrag}
        onDragOver={handleDrag}
        onDrop={handleDrop}
      >
        {uploading ? (
          <div className="flex flex-col items-center gap-2">
            <Loader2 className="h-10 w-10 animate-spin text-primary" />
            <p className="text-muted-foreground">Uploading...</p>
          </div>
        ) : (
          <>
            <Upload className="h-10 w-10 mx-auto text-muted-foreground mb-4" />
            <p className="text-lg font-medium mb-2">Drag and drop files here</p>
            <p className="text-sm text-muted-foreground mb-4">
              Supports: JPG, PNG, GIF, WebP, SVG, PDF, DOC, MP4 and more
            </p>
            <label htmlFor="file-upload">
              <Button asChild>
                <span>
                  <Upload className="h-4 w-4 mr-2" />
                  Choose Files
                </span>
              </Button>
              <input
                id="file-upload"
                type="file"
                multiple
                accept="image/*,.pdf,.doc,.docx,.xls,.xlsx,.mp4,.webm,.mov"
                className="hidden"
                onChange={handleFileSelect}
              />
            </label>
          </>
        )}
      </div>

      {/* Filters */}
      <div className="flex flex-col md:flex-row gap-4">
        <div className="relative flex-1">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
          <Input
            placeholder="Search files..."
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="pl-10"
          />
        </div>
        <Select value={mediaType} onValueChange={setMediaType}>
          <SelectTrigger className="w-full md:w-48">
            <Filter className="h-4 w-4 mr-2" />
            <SelectValue placeholder="Filter by type" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="all">All Types</SelectItem>
            <SelectItem value="image">Images</SelectItem>
            <SelectItem value="document">Documents</SelectItem>
            <SelectItem value="video">Videos</SelectItem>
          </SelectContent>
        </Select>
      </div>

      {/* Media Grid/List */}
      {loading ? (
        <div className="flex items-center justify-center py-12">
          <Loader2 className="h-8 w-8 animate-spin text-primary" />
        </div>
      ) : media.length === 0 ? (
        <div className="text-center py-12">
          <ImageIcon className="h-12 w-12 mx-auto text-muted-foreground mb-4" />
          <p className="text-lg font-medium">No media files yet</p>
          <p className="text-muted-foreground">
            Upload your first file to get started
          </p>
        </div>
      ) : viewMode === "grid" ? (
        <div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-4">
          {media.map((item) => (
            <div
              key={item.id}
              className={`group relative bg-card border border-border rounded-lg overflow-hidden cursor-pointer hover:border-primary transition-colors ${
                selectable ? "hover:ring-2 ring-primary" : ""
              }`}
              onClick={() => handleMediaSelect(item)}
            >
              <div className="aspect-square bg-muted flex items-center justify-center">
                {item.media_type === "image" ? (
                  <img
                    src={`${process.env.REACT_APP_BACKEND_URL}${item.file_url}`}
                    alt={item.alt_text || item.original_filename}
                    className="w-full h-full object-cover"
                  />
                ) : (
                  <div className="text-muted-foreground">
                    {getMediaIcon(item.media_type)}
                  </div>
                )}
              </div>
              <div className="p-2">
                <p className="text-xs truncate font-medium">
                  {item.original_filename}
                </p>
                <p className="text-xs text-muted-foreground">
                  {formatFileSize(item.file_size)}
                </p>
              </div>
              {/* Actions overlay */}
              <div className="absolute inset-0 bg-black/60 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center gap-2">
                <Button
                  size="icon"
                  variant="secondary"
                  onClick={(e) => {
                    e.stopPropagation();
                    copyUrl(item.file_url);
                  }}
                >
                  {copiedId === item.file_url ? (
                    <Check className="h-4 w-4" />
                  ) : (
                    <Copy className="h-4 w-4" />
                  )}
                </Button>
                <Button
                  size="icon"
                  variant="secondary"
                  onClick={(e) => {
                    e.stopPropagation();
                    openEditDialog(item);
                  }}
                >
                  <Edit2 className="h-4 w-4" />
                </Button>
                <Button
                  size="icon"
                  variant="destructive"
                  onClick={(e) => {
                    e.stopPropagation();
                    confirmDelete(item);
                  }}
                >
                  <Trash2 className="h-4 w-4" />
                </Button>
              </div>
            </div>
          ))}
        </div>
      ) : (
        <div className="space-y-2">
          {media.map((item) => (
            <div
              key={item.id}
              className="flex items-center gap-4 p-4 bg-card border border-border rounded-lg hover:border-primary cursor-pointer transition-colors"
              onClick={() => handleMediaSelect(item)}
            >
              <div className="w-16 h-16 bg-muted rounded flex items-center justify-center flex-shrink-0">
                {item.media_type === "image" ? (
                  <img
                    src={`${process.env.REACT_APP_BACKEND_URL}${item.file_url}`}
                    alt={item.alt_text}
                    className="w-full h-full object-cover rounded"
                  />
                ) : (
                  getMediaIcon(item.media_type)
                )}
              </div>
              <div className="flex-1 min-w-0">
                <p className="font-medium truncate">{item.original_filename}</p>
                <p className="text-sm text-muted-foreground">
                  {formatFileSize(item.file_size)} • {item.mime_type}
                  {item.width &&
                    item.height &&
                    ` • ${item.width}×${item.height}`}
                </p>
              </div>
              <div className="flex gap-2">
                <Button
                  size="icon"
                  variant="outline"
                  onClick={(e) => {
                    e.stopPropagation();
                    copyUrl(item.file_url);
                  }}
                >
                  {copiedId === item.file_url ? (
                    <Check className="h-4 w-4" />
                  ) : (
                    <Copy className="h-4 w-4" />
                  )}
                </Button>
                <Button
                  size="icon"
                  variant="outline"
                  onClick={(e) => {
                    e.stopPropagation();
                    openEditDialog(item);
                  }}
                >
                  <Edit2 className="h-4 w-4" />
                </Button>
                <Button
                  size="icon"
                  variant="destructive"
                  onClick={(e) => {
                    e.stopPropagation();
                    confirmDelete(item);
                  }}
                >
                  <Trash2 className="h-4 w-4" />
                </Button>
              </div>
            </div>
          ))}
        </div>
      )}

      {/* Pagination */}
      {totalPages > 1 && (
        <div className="flex items-center justify-center gap-2">
          <Button
            variant="outline"
            size="sm"
            onClick={() => setPage(Math.max(1, page - 1))}
            disabled={page === 1}
          >
            Previous
          </Button>
          <span className="text-sm text-muted-foreground">
            Page {page} of {totalPages}
          </span>
          <Button
            variant="outline"
            size="sm"
            onClick={() => setPage(Math.min(totalPages, page + 1))}
            disabled={page === totalPages}
          >
            Next
          </Button>
        </div>
      )}

      {/* Edit Dialog */}
      <Dialog open={editDialog} onOpenChange={setEditDialog}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Edit Media</DialogTitle>
          </DialogHeader>
          <div className="space-y-4">
            {selectedMedia?.media_type === "image" && (
              <div className="aspect-video bg-muted rounded-lg overflow-hidden">
                <img
                  src={`${process.env.REACT_APP_BACKEND_URL}${selectedMedia?.file_url}`}
                  alt={selectedMedia?.alt_text}
                  className="w-full h-full object-contain"
                />
              </div>
            )}
            <div className="space-y-2">
              <Label>Title</Label>
              <Input
                value={editForm.title}
                onChange={(e) =>
                  setEditForm({ ...editForm, title: e.target.value })
                }
              />
            </div>
            <div className="space-y-2">
              <Label>Alt Text</Label>
              <Input
                value={editForm.alt_text}
                onChange={(e) =>
                  setEditForm({ ...editForm, alt_text: e.target.value })
                }
              />
            </div>
            <div className="space-y-2">
              <Label>Description</Label>
              <Textarea
                value={editForm.description}
                onChange={(e) =>
                  setEditForm({ ...editForm, description: e.target.value })
                }
                rows={3}
              />
            </div>
            <div className="space-y-2">
              <Label>URL</Label>
              <div className="flex gap-2">
                <Input
                  value={`${process.env.REACT_APP_BACKEND_URL}${selectedMedia?.file_url}`}
                  readOnly
                  className="flex-1"
                />
                <Button
                  variant="outline"
                  onClick={() => copyUrl(selectedMedia?.file_url)}
                >
                  <Copy className="h-4 w-4" />
                </Button>
              </div>
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setEditDialog(false)}>
              Cancel
            </Button>
            <Button onClick={handleUpdate}>Save Changes</Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Delete Confirmation */}
      <AlertDialog open={deleteDialog} onOpenChange={setDeleteDialog}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Delete Media?</AlertDialogTitle>
            <AlertDialogDescription>
              This will permanently delete "{mediaToDelete?.original_filename}".
              This action cannot be undone.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction
              onClick={handleDelete}
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
            >
              Delete
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
};

export default MediaManager;
