import { useState, useRef } from "react";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Star, Video, Upload, Camera, CheckCircle2, Play, Square, Loader2, Sparkles } from "lucide-react";
import { toast } from "sonner";
import { useStore } from "@/lib/store";

interface VideoReviewModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  productId: string;
  productName: string;
  orderId: string;
  onSuccess?: () => void;
}

export function VideoReviewModal({
  open,
  onOpenChange,
  productId,
  productName,
  orderId,
  onSuccess,
}: VideoReviewModalProps) {
  const { user } = useStore();
  const [rating, setRating] = useState(5);
  const [title, setTitle] = useState("");
  const [comment, setComment] = useState("");
  const [videoUrl, setVideoUrl] = useState("");
  const [isRecording, setIsRecording] = useState(false);
  const [recordingTime, setRecordingTime] = useState(0);
  const [uploading, setUploading] = useState(false);
  const [submitting, setSubmitting] = useState(false);

  const videoPreviewRef = useRef<HTMLVideoElement | null>(null);
  const mediaRecorderRef = useRef<MediaRecorder | null>(null);
  const recordedChunksRef = useRef<Blob[]>([]);
  const timerRef = useRef<any>(null);

  // Start webcam recording
  const startRecording = async () => {
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
      if (videoPreviewRef.current) {
        videoPreviewRef.current.srcObject = stream;
        videoPreviewRef.current.play();
      }

      recordedChunksRef.current = [];
      const recorder = new MediaRecorder(stream);
      mediaRecorderRef.current = recorder;

      recorder.ondataavailable = (e) => {
        if (e.data.size > 0) recordedChunksRef.current.push(e.data);
      };

      recorder.onstop = async () => {
        const blob = new Blob(recordedChunksRef.current, { type: "video/webm" });
        
        // Check 20MB limit for recorded video
        const MAX_SIZE_BYTES = 20 * 1024 * 1024;
        if (blob.size > MAX_SIZE_BYTES) {
          const mbSize = (blob.size / (1024 * 1024)).toFixed(1);
          toast.error(`Recorded video is ${mbSize}MB, exceeding the 20MB maximum limit. Please record a shorter video.`);
          setVideoUrl("");
          return;
        }

        // Upload recorded blob to server for permanent URL
        const uploadedUrl = await uploadVideoFile(blob, `webcam_review_${Date.now()}.webm`);
        if (uploadedUrl) {
          setVideoUrl(uploadedUrl);
        }

        // Stop stream tracks
        stream.getTracks().forEach((track) => track.stop());
        if (videoPreviewRef.current) {
          videoPreviewRef.current.srcObject = null;
        }
      };

      recorder.start();
      setIsRecording(true);
      setRecordingTime(0);

      timerRef.current = setInterval(() => {
        setRecordingTime((t) => t + 1);
      }, 1000);
    } catch (err: any) {
      toast.error("Camera permission denied or camera unavailable.");
    }
  };

  const stopRecording = () => {
    if (mediaRecorderRef.current && isRecording) {
      mediaRecorderRef.current.stop();
      setIsRecording(false);
      if (timerRef.current) clearInterval(timerRef.current);
    }
  };

  const uploadVideoFile = async (fileOrBlob: Blob, filename: string): Promise<string | null> => {
    setUploading(true);
    try {
      const formData = new FormData();
      formData.append("file", fileOrBlob, filename);

      const res = await fetch("/api/upload.php", {
        method: "POST",
        body: formData,
      });
      const data = await res.json();
      if (data.success && data.url) {
        toast.success("Video uploaded to server successfully!");
        return data.url;
      } else {
        toast.error(data.error || "Failed to upload video to server.");
        return null;
      }
    } catch {
      toast.error("Network error while uploading video.");
      return null;
    } finally {
      setUploading(false);
    }
  };

  const handleFileUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    if (!file.type.startsWith("video/")) {
      toast.error("Please upload a valid video file.");
      return;
    }

    // Check 20MB limit (20 * 1024 * 1024 bytes)
    const MAX_SIZE_BYTES = 20 * 1024 * 1024;
    if (file.size > MAX_SIZE_BYTES) {
      const mbSize = (file.size / (1024 * 1024)).toFixed(1);
      toast.error(`Video file is ${mbSize}MB, exceeding the 20MB maximum limit.`);
      e.target.value = "";
      return;
    }

    const uploadedUrl = await uploadVideoFile(file, file.name);
    if (uploadedUrl) {
      setVideoUrl(uploadedUrl);
    }
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!title.trim() || !comment.trim()) {
      toast.error("Please fill out the review title and comment.");
      return;
    }

    setSubmitting(true);
    try {
      const response = await fetch("/api/reviews.php", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          product_id: productId,
          order_id: orderId,
          user_email: user?.email || "customer@example.com",
          user_name: user?.name || "Verified Buyer",
          rating,
          title,
          comment,
          video_url: videoUrl || "https://assets.mixkit.co/videos/preview/mixkit-unboxing-a-new-smartphone-41484-large.mp4",
        }),
      });

      const data = await response.json();
      if (data.success) {
        toast.success("Thank you! Your video review has been submitted and is pending admin approval before appearing in the store.");
        onOpenChange(false);
        if (onSuccess) onSuccess();
      } else {
        toast.error("Failed to post review. Please try again.");
      }
    } catch (err) {
      toast.error("Error submitting review.");
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-[540px] p-6 max-h-[90vh] overflow-y-auto">
        <DialogHeader>
          <div className="flex items-center gap-2 text-orange-500 text-xs font-bold uppercase tracking-wider">
            <Sparkles className="w-4 h-4" /> Verified Customer Review
          </div>
          <DialogTitle className="text-xl font-bold">Create Video Review</DialogTitle>
          <DialogDescription className="text-xs text-neutral-500">
            Share your unboxing and product experience for <span className="font-semibold text-neutral-800">{productName}</span>.
          </DialogDescription>
        </DialogHeader>

        <form onSubmit={handleSubmit} className="space-y-4 pt-2">
          {/* Star Rating */}
          <div>
            <label className="text-xs font-semibold text-neutral-700 block mb-1.5">Rating</label>
            <div className="flex items-center gap-1.5">
              {[1, 2, 3, 4, 5].map((star) => (
                <button
                  type="button"
                  key={star}
                  onClick={() => setRating(star)}
                  className="p-1 hover:scale-110 transition-transform"
                >
                  <Star
                    className={`w-7 h-7 ${star <= rating ? "text-amber-400 fill-amber-400" : "text-neutral-300"}`}
                  />
                </button>
              ))}
              <span className="ml-2 text-xs font-bold text-neutral-600">{rating} out of 5 Stars</span>
            </div>
          </div>

          {/* Video Preview & Capture Box */}
          <div>
            <label className="text-xs font-semibold text-neutral-700 flex items-center justify-between mb-1.5">
              <span className="flex items-center gap-1">
                <Video className="w-4 h-4 text-orange-500" /> Video Recording or Upload
              </span>
              <span className="text-[11px] text-orange-600 font-semibold bg-orange-50 px-1.5 py-0.5 rounded border border-orange-200">Max size: 20MB</span>
            </label>

            <div className="border-2 border-dashed border-neutral-300 rounded-xl p-4 bg-neutral-50 flex flex-col items-center justify-center min-h-[200px] relative overflow-hidden">
              {isRecording ? (
                <div className="w-full text-center space-y-3">
                  <video ref={videoPreviewRef} className="w-full h-44 object-cover rounded-lg bg-black" muted />
                  <div className="flex items-center justify-center gap-3">
                    <span className="inline-flex items-center gap-1.5 text-xs text-red-600 font-bold animate-pulse">
                      <span className="w-2.5 h-2.5 bg-red-600 rounded-full" /> Recording... 00:0{recordingTime}s
                    </span>
                    <Button type="button" variant="destructive" size="sm" onClick={stopRecording} className="gap-1">
                      <Square className="w-3.5 h-3.5" /> Stop Recording
                    </Button>
                  </div>
                </div>
              ) : videoUrl ? (
                <div className="w-full space-y-2">
                  <video src={videoUrl} controls className="w-full h-48 object-cover rounded-lg bg-black" />
                  <div className="flex justify-between items-center text-xs">
                    <span className="text-emerald-600 font-medium flex items-center gap-1">
                      <CheckCircle2 className="w-4 h-4" /> Video Attached
                    </span>
                    <button
                      type="button"
                      onClick={() => setVideoUrl("")}
                      className="text-red-500 hover:underline"
                    >
                      Remove video
                    </button>
                  </div>
                </div>
              ) : (
                <div className="text-center space-y-3 py-2">
                  <div className="w-12 h-12 rounded-full bg-orange-100 flex items-center justify-center mx-auto text-orange-500">
                    <Camera className="w-6 h-6" />
                  </div>
                  <div>
                    <p className="text-xs font-semibold text-neutral-800">Record video or select file</p>
                    <p className="text-[11px] text-neutral-500 mt-0.5">Show how your package looks after delivery!</p>
                  </div>

                  <div className="flex items-center justify-center gap-2 pt-1">
                    <Button
                      type="button"
                      variant="outline"
                      size="sm"
                      onClick={startRecording}
                      className="gap-1.5 border-orange-400 text-orange-600 hover:bg-orange-50 text-xs"
                    >
                      <Camera className="w-3.5 h-3.5" /> Record Webcam
                    </Button>
                    <label className="cursor-pointer inline-flex items-center gap-1.5 px-3 py-1.5 rounded-md bg-white border border-neutral-300 hover:bg-neutral-100 text-xs font-medium text-neutral-700 shadow-sm">
                      <Upload className="w-3.5 h-3.5" /> Upload File
                      <input type="file" accept="video/*" onChange={handleFileUpload} className="hidden" />
                    </label>
                  </div>
                </div>
              )}
            </div>
          </div>

          {/* Review Title */}
          <div className="space-y-1">
            <label className="text-xs font-semibold text-neutral-700">Headline</label>
            <Input
              value={title}
              onChange={(e) => setTitle(e.target.value)}
              placeholder="e.g. Excellent delivery quality & authentic product!"
              required
              className="text-xs"
            />
          </div>

          {/* Comment */}
          <div className="space-y-1">
            <label className="text-xs font-semibold text-neutral-700">Detailed Review</label>
            <textarea
              value={comment}
              onChange={(e) => setComment(e.target.value)}
              placeholder="Write your review here. Did it meet your expectations?"
              rows={3}
              required
              className="w-full p-2.5 text-xs rounded-md border border-neutral-300 focus:outline-none focus:ring-2 focus:ring-orange-500"
            />
          </div>

          <div className="flex gap-2 pt-2">
            <Button
              type="button"
              variant="outline"
              onClick={() => onOpenChange(false)}
              className="flex-1 text-xs"
            >
              Cancel
            </Button>
            <Button
              type="submit"
              disabled={submitting}
              className="flex-1 text-xs bg-orange-500 hover:bg-orange-600 font-semibold"
            >
              {submitting ? <Loader2 className="w-4 h-4 animate-spin" /> : "Post Video Review"}
            </Button>
          </div>
        </form>
      </DialogContent>
    </Dialog>
  );
}
