import React, { useState, useCallback, useRef, useEffect } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { useTranslation } from "react-i18next";
import { useAuth } from "../../auth/AuthContext";
import { createPost, uploadPostMedia, getCurrentLocation } from "../../api/client";

const CATEGORIES = [
  { id: "general", icon: "fa-circle-dot", label: "General", color: "from-slate-500 to-zinc-500" },
  { id: "news", icon: "fa-newspaper", label: "News", color: "from-blue-500 to-cyan-500" },
  { id: "sports", icon: "fa-futbol", label: "Sports", color: "from-orange-500 to-amber-500" },
  { id: "entertainment", icon: "fa-film", label: "Entertainment", color: "from-pink-500 to-rose-500" },
  { id: "technology", icon: "fa-microchip", label: "Tech", color: "from-emerald-500 to-teal-500" },
  { id: "politics", icon: "fa-landmark", label: "Politics", color: "from-purple-500 to-indigo-500" },
  { id: "traffic", icon: "fa-car", label: "Traffic", color: "from-yellow-500 to-amber-500" },
  { id: "weather", icon: "fa-cloud-sun", label: "Weather", color: "from-sky-500 to-blue-500" },
];

export default function PostComposer({ onClose, onPostCreated }) {
  const { t } = useTranslation();
  const { token, username, isAuthenticated } = useAuth();
  const fileInputRef = useRef(null);
  const videoInputRef = useRef(null);

  // Form state
  const [content, setContent] = useState("");
  const [category, setCategory] = useState("general");
  const [media, setMedia] = useState([]); // { file, preview, type, uploading, url }
  const [location, setLocation] = useState(null); // { lat, lng }
  const [locationName, setLocationName] = useState("");
  const [isGettingLocation, setIsGettingLocation] = useState(false);
  const [posting, setPosting] = useState(false);
  const [error, setError] = useState("");
  const [step, setStep] = useState("compose"); // compose, category, preview

  // Close on escape
  useEffect(() => {
    const handleKey = (e) => {
      if (e.key === "Escape") onClose?.();
    };
    window.addEventListener("keydown", handleKey);
    return () => window.removeEventListener("keydown", handleKey);
  }, [onClose]);

  // Get current location
  const handleGetLocation = useCallback(async () => {
    setIsGettingLocation(true);
    setError("");
    const result = await getCurrentLocation();
    setIsGettingLocation(false);

    if (result.ok) {
      setLocation({ lat: result.lat, lng: result.lng });
      // Try to get location name via reverse geocoding
      try {
        const res = await fetch(
          `https://nominatim.openstreetmap.org/reverse?lat=${result.lat}&lon=${result.lng}&format=json`
        );
        const data = await res.json();
        const name = data.address?.city || data.address?.town || data.address?.village || data.display_name?.split(",")[0];
        setLocationName(name || `${result.lat.toFixed(4)}, ${result.lng.toFixed(4)}`);
      } catch {
        setLocationName(`${result.lat.toFixed(4)}, ${result.lng.toFixed(4)}`);
      }
    } else {
      setError(result.error || "Could not get location");
    }
  }, []);

  // Handle file selection
  const handleFileSelect = useCallback((e, type = "image") => {
    const files = Array.from(e.target.files || []);
    if (files.length === 0) return;

    const newMedia = files.map((file) => ({
      file,
      preview: URL.createObjectURL(file),
      type: file.type.startsWith("video/") ? "video" : "image",
      uploading: false,
      url: null,
    }));

    setMedia((prev) => [...prev, ...newMedia].slice(0, 4)); // Max 4 media items
    e.target.value = "";
  }, []);

  // Remove media item
  const removeMedia = useCallback((index) => {
    setMedia((prev) => {
      const item = prev[index];
      if (item?.preview) URL.revokeObjectURL(item.preview);
      return prev.filter((_, i) => i !== index);
    });
  }, []);

  // Upload all media
  const uploadAllMedia = useCallback(async () => {
    const uploaded = [];
    for (let i = 0; i < media.length; i++) {
      const item = media[i];
      if (item.url) {
        uploaded.push(item);
        continue;
      }

      setMedia((prev) =>
        prev.map((m, idx) => (idx === i ? { ...m, uploading: true } : m))
      );

      const result = await uploadPostMedia(item.file, { type: item.type });

      if (result.ok) {
        const updatedItem = { ...item, uploading: false, url: result.url, thumbnail_url: result.thumbnail_url };
        uploaded.push(updatedItem);
        setMedia((prev) =>
          prev.map((m, idx) => (idx === i ? updatedItem : m))
        );
      } else {
        setMedia((prev) =>
          prev.map((m, idx) => (idx === i ? { ...m, uploading: false, error: result.error } : m))
        );
        throw new Error(result.error || "Upload failed");
      }
    }
    return uploaded;
  }, [media]);

  // Submit post
  const handleSubmit = useCallback(async () => {
    if (!content.trim() && media.length === 0) {
      setError("Please add some content or media");
      return;
    }

    setPosting(true);
    setError("");

    try {
      // Upload media first if any
      let uploadedMedia = [];
      if (media.length > 0) {
        uploadedMedia = await uploadAllMedia();
      }

      // Build post payload
      const payload = {
        title: content.slice(0, 100) || "New Post",
        snippet: content,
        content: content,
        category: category.toUpperCase(),
        content_type: uploadedMedia.length > 0
          ? (uploadedMedia[0].type === "video" ? "video" : "image")
          : "text",
      };

      // Add location if available
      if (location) {
        payload.latitude = location.lat;
        payload.longitude = location.lng;
        payload.location_name = locationName || "";
      }

      // Add media URLs
      if (uploadedMedia.length > 0) {
        const firstMedia = uploadedMedia[0];
        if (firstMedia.type === "video") {
          payload.video_url = firstMedia.url;
          payload.thumbnail_url = firstMedia.thumbnail_url;
        } else {
          payload.image_url = firstMedia.url;
        }

        if (uploadedMedia.length > 1) {
          payload.media = uploadedMedia.map((m) => ({
            url: m.url,
            type: m.type,
            thumbnail_url: m.thumbnail_url,
          }));
        }
      }

      const result = await createPost(payload, token);

      if (result && (result.id || result._id)) {
        onPostCreated?.(result);
        onClose?.();
      } else {
        throw new Error("Failed to create post");
      }
    } catch (err) {
      setError(err.message || "Failed to create post");
    } finally {
      setPosting(false);
    }
  }, [content, media, category, location, locationName, token, uploadAllMedia, onPostCreated, onClose]);

  // Cleanup previews on unmount
  useEffect(() => {
    return () => {
      media.forEach((m) => {
        if (m.preview) URL.revokeObjectURL(m.preview);
      });
    };
  }, []);

  if (!token) {
    return (
      <motion.div
        className="fixed inset-0 z-[1100] flex items-center justify-center p-4 bg-black/80 backdrop-blur-sm"
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        exit={{ opacity: 0 }}
        onClick={onClose}
      >
        <motion.div
          className="bg-surface-900 rounded-3xl p-8 max-w-sm text-center border border-white/10"
          initial={{ scale: 0.9, y: 20 }}
          animate={{ scale: 1, y: 0 }}
          onClick={(e) => e.stopPropagation()}
        >
          <i className="fa-solid fa-lock text-4xl text-surface-500 mb-4" />
          <h2 className="text-xl font-bold text-surface-100 mb-2">Login Required</h2>
          <p className="text-surface-400 mb-6">You need to be logged in to create posts.</p>
          <button
            className="px-6 py-3 rounded-xl bg-gradient-to-r from-blue-500 to-cyan-500 text-white font-bold"
            onClick={onClose}
          >
            Close
          </button>
        </motion.div>
      </motion.div>
    );
  }

  return (
    <motion.div
      className="fixed inset-0 z-[1100] flex items-end sm:items-center justify-center bg-black/80 backdrop-blur-sm"
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      exit={{ opacity: 0 }}
      onClick={onClose}
    >
      <motion.div
        className="w-full sm:max-w-lg max-h-[90vh] overflow-hidden rounded-t-3xl sm:rounded-3xl
                   bg-gradient-to-b from-surface-800 to-surface-900
                   border border-white/10 shadow-2xl"
        initial={{ y: "100%", opacity: 0 }}
        animate={{ y: 0, opacity: 1 }}
        exit={{ y: "100%", opacity: 0 }}
        transition={{ type: "spring", damping: 25, stiffness: 300 }}
        onClick={(e) => e.stopPropagation()}
      >
        {/* Header */}
        <div className="flex items-center justify-between px-5 py-4 border-b border-white/10">
          <button
            className="text-surface-400 hover:text-surface-200 transition-colors"
            onClick={onClose}
          >
            Cancel
          </button>
          <h2 className="text-lg font-bold text-surface-100">Create Post</h2>
          <motion.button
            className={`px-4 py-2 rounded-full font-bold text-sm transition-all
                       ${content.trim() || media.length > 0
                         ? "bg-gradient-to-r from-blue-500 to-cyan-500 text-white"
                         : "bg-surface-700 text-surface-500 cursor-not-allowed"
                       }`}
            whileHover={content.trim() || media.length > 0 ? { scale: 1.05 } : {}}
            whileTap={content.trim() || media.length > 0 ? { scale: 0.95 } : {}}
            disabled={posting || (!content.trim() && media.length === 0)}
            onClick={handleSubmit}
          >
            {posting ? (
              <i className="fa-solid fa-spinner fa-spin" />
            ) : (
              "Post"
            )}
          </motion.button>
        </div>

        {/* Content */}
        <div className="p-4 overflow-y-auto max-h-[calc(90vh-140px)]">
          {/* User info */}
          <div className="flex items-center gap-3 mb-4">
            <div className="w-12 h-12 rounded-full bg-gradient-to-br from-blue-500 to-cyan-500 flex items-center justify-center text-white text-lg font-bold">
              {username?.charAt(0)?.toUpperCase() || "U"}
            </div>
            <div>
              <p className="font-bold text-surface-100">{username || "You"}</p>
              <button
                className="flex items-center gap-1 text-xs text-accent hover:text-accent/80"
                onClick={() => setStep(step === "category" ? "compose" : "category")}
              >
                <i className={`fa-solid ${CATEGORIES.find(c => c.id === category)?.icon || "fa-circle-dot"}`} />
                <span>{CATEGORIES.find(c => c.id === category)?.label || "Category"}</span>
                <i className="fa-solid fa-chevron-down text-[10px]" />
              </button>
            </div>
          </div>

          {/* Category selector */}
          <AnimatePresence>
            {step === "category" && (
              <motion.div
                className="mb-4 p-3 rounded-2xl bg-surface-800/50 border border-white/5"
                initial={{ height: 0, opacity: 0 }}
                animate={{ height: "auto", opacity: 1 }}
                exit={{ height: 0, opacity: 0 }}
              >
                <p className="text-xs text-surface-500 mb-2 uppercase tracking-wide">Select Category</p>
                <div className="grid grid-cols-4 gap-2">
                  {CATEGORIES.map((cat) => (
                    <motion.button
                      key={cat.id}
                      className={`flex flex-col items-center gap-1 p-3 rounded-xl transition-all
                                 ${category === cat.id
                                   ? `bg-gradient-to-br ${cat.color} text-white`
                                   : "bg-surface-700/50 text-surface-400 hover:bg-surface-700"
                                 }`}
                      whileTap={{ scale: 0.95 }}
                      onClick={() => {
                        setCategory(cat.id);
                        setStep("compose");
                      }}
                    >
                      <i className={`fa-solid ${cat.icon} text-lg`} />
                      <span className="text-[10px] font-medium">{cat.label}</span>
                    </motion.button>
                  ))}
                </div>
              </motion.div>
            )}
          </AnimatePresence>

          {/* Text input */}
          <textarea
            className="w-full min-h-[120px] p-0 bg-transparent text-surface-100 text-lg
                       placeholder:text-surface-500 resize-none focus:outline-none"
            placeholder="What's happening?"
            value={content}
            onChange={(e) => setContent(e.target.value)}
            autoFocus
          />

          {/* Media preview */}
          {media.length > 0 && (
            <div className={`grid gap-2 mb-4 ${media.length === 1 ? "grid-cols-1" : "grid-cols-2"}`}>
              {media.map((item, index) => (
                <div key={index} className="relative rounded-2xl overflow-hidden bg-surface-800 aspect-video">
                  {item.type === "video" ? (
                    <video
                      src={item.preview}
                      className="w-full h-full object-cover"
                      controls={false}
                      muted
                    />
                  ) : (
                    <img
                      src={item.preview}
                      alt=""
                      className="w-full h-full object-cover"
                    />
                  )}
                  {item.uploading && (
                    <div className="absolute inset-0 bg-black/60 flex items-center justify-center">
                      <i className="fa-solid fa-spinner fa-spin text-2xl text-white" />
                    </div>
                  )}
                  <button
                    className="absolute top-2 right-2 w-8 h-8 rounded-full bg-black/60 text-white
                               flex items-center justify-center hover:bg-red-500 transition-colors"
                    onClick={() => removeMedia(index)}
                  >
                    <i className="fa-solid fa-times" />
                  </button>
                  {item.type === "video" && (
                    <div className="absolute bottom-2 left-2 px-2 py-1 rounded bg-black/60 text-white text-xs">
                      <i className="fa-solid fa-video mr-1" />
                      Video
                    </div>
                  )}
                </div>
              ))}
            </div>
          )}

          {/* Location */}
          {location && (
            <div className="flex items-center gap-2 mb-4 px-3 py-2 rounded-xl bg-surface-800/50 border border-white/5">
              <i className="fa-solid fa-location-dot text-accent" />
              <span className="text-sm text-surface-300 flex-1">{locationName}</span>
              <button
                className="text-surface-500 hover:text-red-400"
                onClick={() => {
                  setLocation(null);
                  setLocationName("");
                }}
              >
                <i className="fa-solid fa-times" />
              </button>
            </div>
          )}

          {/* Error */}
          {error && (
            <div className="mb-4 px-4 py-3 rounded-xl bg-red-500/10 border border-red-500/30 text-red-400 text-sm">
              <i className="fa-solid fa-exclamation-triangle mr-2" />
              {error}
            </div>
          )}
        </div>

        {/* Actions bar */}
        <div className="flex items-center gap-2 px-4 py-3 border-t border-white/10 bg-surface-900/50">
          {/* Photo */}
          <motion.button
            className="w-11 h-11 rounded-full bg-surface-800 text-green-400 flex items-center justify-center
                       hover:bg-green-500/20 transition-colors"
            whileTap={{ scale: 0.9 }}
            onClick={() => fileInputRef.current?.click()}
            disabled={media.length >= 4}
          >
            <i className="fa-solid fa-image" />
          </motion.button>
          <input
            ref={fileInputRef}
            type="file"
            accept="image/*"
            multiple
            className="hidden"
            onChange={(e) => handleFileSelect(e, "image")}
          />

          {/* Video */}
          <motion.button
            className="w-11 h-11 rounded-full bg-surface-800 text-blue-400 flex items-center justify-center
                       hover:bg-blue-500/20 transition-colors"
            whileTap={{ scale: 0.9 }}
            onClick={() => videoInputRef.current?.click()}
            disabled={media.length >= 4}
          >
            <i className="fa-solid fa-video" />
          </motion.button>
          <input
            ref={videoInputRef}
            type="file"
            accept="video/*"
            className="hidden"
            onChange={(e) => handleFileSelect(e, "video")}
          />

          {/* Location */}
          <motion.button
            className={`w-11 h-11 rounded-full flex items-center justify-center transition-colors
                       ${location
                         ? "bg-accent/20 text-accent"
                         : "bg-surface-800 text-orange-400 hover:bg-orange-500/20"
                       }`}
            whileTap={{ scale: 0.9 }}
            onClick={handleGetLocation}
            disabled={isGettingLocation}
          >
            {isGettingLocation ? (
              <i className="fa-solid fa-spinner fa-spin" />
            ) : (
              <i className="fa-solid fa-location-dot" />
            )}
          </motion.button>

          {/* Live (future feature) */}
          <motion.button
            className="w-11 h-11 rounded-full bg-surface-800 text-red-400 flex items-center justify-center
                       hover:bg-red-500/20 transition-colors"
            whileTap={{ scale: 0.9 }}
            onClick={() => {
              // Dispatch event to open LiveKit broadcast
              window.dispatchEvent(new CustomEvent("livekit-broadcast-open"));
              onClose?.();
            }}
          >
            <i className="fa-solid fa-broadcast-tower" />
          </motion.button>

          <div className="flex-1" />

          {/* Character count */}
          <span className={`text-xs ${content.length > 500 ? "text-red-400" : "text-surface-500"}`}>
            {content.length}/500
          </span>
        </div>
      </motion.div>
    </motion.div>
  );
}

// Floating Action Button for creating posts - triggers the map's create post flow
export function CreatePostFAB() {
  const handleClick = () => {
    // Dispatch event to open the map's post creation modal
    window.dispatchEvent(new CustomEvent("sw:openMapPostCreator"));
  };

  return (
    <motion.button
      className="fixed bottom-4 left-4 z-[998] px-4 py-3 rounded-full
                 text-white text-sm font-semibold
                 flex items-center gap-2
                 border border-surface-600/30 backdrop-blur-xl"
      style={{
        background: "linear-gradient(135deg, rgba(30, 58, 138, 0.9), rgba(59, 130, 246, 0.85))",
        boxShadow: "0 4px 16px rgba(0, 0, 0, 0.3)",
      }}
      whileHover={{ scale: 1.05, y: -2, boxShadow: "0 6px 20px rgba(59, 130, 246, 0.4)" }}
      whileTap={{ scale: 0.95 }}
      onClick={handleClick}
      initial={{ scale: 0, opacity: 0 }}
      animate={{ scale: 1, opacity: 1 }}
      transition={{ type: "spring", delay: 0.5 }}
    >
      <i className="fa-solid fa-plus text-lg" />
      <span className="hidden sm:inline">Post</span>
    </motion.button>
  );
}
