import { useQuery, useMutation } from "@tanstack/react-query";
import { Media, insertMediaSchema } from "@shared/schema";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { useToast } from "@/hooks/use-toast";
import { apiRequest, queryClient } from "@/lib/queryClient";
import { Loader2, Plus, Edit, Trash2 } from "lucide-react";
import { useState } from "react";
import { Textarea } from "@/components/ui/textarea";
import { AspectRatio } from "@/components/ui/aspect-ratio";
import { format } from "date-fns";

interface LiveSession {
  id: number;
  sessionTitle: string;
  sessionTitleAr: string;
  liveStreamUrl: string;
}

export default function MediaPage() {
  const { toast } = useToast();
  const [isAdding, setIsAdding] = useState(false);
  const [selectedType, setSelectedType] = useState<string>("all");
  const [editingMedia, setEditingMedia] = useState<Media | null>(null);
  const [mediaToDelete, setMediaToDelete] = useState<Media | null>(null);

  const form = useForm({
    resolver: zodResolver(insertMediaSchema),
    defaultValues: {
      type: "image",
      title: "",
      titleAr: "",
      description: "",
      descriptionAr: "",
      url: "",
      thumbnail: "",
    },
  });

  // Fetch live sessions for the dropdown - moved after form definition
  const { data: liveSessions } = useQuery<{ sessions: LiveSession[] }>({
    queryKey: ["/api/sessions/live-streams"],
    enabled: form.watch("type") === "video"
  });

  const { data: media, isLoading } = useQuery<Media[]>({
    queryKey: ["/api/media", selectedType],
    queryFn: async () => {
      const url = selectedType === "all"
        ? "/api/media"
        : `/api/media?type=${selectedType}`;
      const res = await apiRequest("GET", url);
      return res.json();
    },
  });

  // Reset form when switching between add/edit modes
  const resetForm = (mediaItem?: Media) => {
    if (mediaItem) {
      form.reset({
        type: mediaItem.type,
        title: mediaItem.title,
        titleAr: mediaItem.titleAr,
        description: mediaItem.description,
        descriptionAr: mediaItem.descriptionAr,
        url: mediaItem.url,
        thumbnail: mediaItem.thumbnail || "",
      });
    } else {
      form.reset({
        type: "image",
        title: "",
        titleAr: "",
        description: "",
        descriptionAr: "",
        url: "",
        thumbnail: "",
      });
    }
  };

  const createMediaMutation = useMutation({
    mutationFn: async (data: any) => {
      const res = await apiRequest("POST", "/api/media", data);
      return res.json();
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["/api/media"] });
      toast({
        title: "Media added",
        description: "The media item has been added successfully.",
      });
      setIsAdding(false);
      form.reset();
    },
    onError: (error: Error) => {
      toast({
        title: "Error",
        description: error.message,
        variant: "destructive",
      });
    },
  });

  const updateMediaMutation = useMutation({
    mutationFn: async (data: any) => {
      if (!editingMedia?.id) throw new Error("No media ID provided");
      const res = await apiRequest("PATCH", `/api/media/${editingMedia.id}`, data);
      return res.json();
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["/api/media"] });
      toast({
        title: "Media updated",
        description: "The media item has been updated successfully.",
      });
      setEditingMedia(null);
      form.reset();
    },
    onError: (error: Error) => {
      toast({
        title: "Error",
        description: error.message,
        variant: "destructive",
      });
    },
  });

  const deleteMediaMutation = useMutation({
    mutationFn: async (mediaId: number) => {
      await apiRequest("DELETE", `/api/media/${mediaId}`);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["/api/media"] });
      toast({
        title: "Media deleted",
        description: "The media item has been deleted successfully.",
      });
      setMediaToDelete(null);
    },
    onError: (error: Error) => {
      toast({
        title: "Error",
        description: error.message,
        variant: "destructive",
      });
    },
  });

  if (isLoading) {
    return (
      <div className="flex justify-center">
        <Loader2 className="h-8 w-8 animate-spin" />
      </div>
    );
  }

  return (
    <div className="container mx-auto py-8 space-y-8">
      <div className="flex justify-between items-center">
        <h1 className="text-3xl font-bold">Media Management</h1>
        <div className="flex items-center gap-4">
          <Select
            value={selectedType}
            onValueChange={setSelectedType}
          >
            <SelectTrigger className="w-[180px]">
              <SelectValue placeholder="Filter by type" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All Media</SelectItem>
              <SelectItem value="image">Images</SelectItem>
              <SelectItem value="video">Videos</SelectItem>
            </SelectContent>
          </Select>
          <Button
            onClick={() => {
              setIsAdding(true);
              setEditingMedia(null);
              resetForm();
            }}
            disabled={isAdding || editingMedia !== null}
          >
            <Plus className="h-4 w-4 mr-2" />
            Add Media
          </Button>
        </div>
      </div>

      {(isAdding || editingMedia) && (
        <Card className="mb-8">
          <CardHeader>
            <CardTitle>{editingMedia ? "Edit Media" : "Add Media"}</CardTitle>
          </CardHeader>
          <CardContent>
            <Form {...form}>
              <form
                onSubmit={form.handleSubmit((data) =>
                  editingMedia
                    ? updateMediaMutation.mutate(data)
                    : createMediaMutation.mutate(data)
                )}
                className="space-y-6"
              >
                <div className="grid md:grid-cols-2 gap-6">
                  <FormField
                    control={form.control}
                    name="type"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Type</FormLabel>
                        <Select
                          onValueChange={(value) => {
                            field.onChange(value);
                            // Reset url field when switching types
                            form.setValue("url", "");
                          }}
                          defaultValue={field.value}
                        >
                          <FormControl>
                            <SelectTrigger>
                              <SelectValue placeholder="Select type" />
                            </SelectTrigger>
                          </FormControl>
                          <SelectContent>
                            <SelectItem value="image">Image</SelectItem>
                            <SelectItem value="video">Video</SelectItem>
                          </SelectContent>
                        </Select>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                  <FormField
                    control={form.control}
                    name="title"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Title (English)</FormLabel>
                        <FormControl>
                          <Input {...field} />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                  <FormField
                    control={form.control}
                    name="titleAr"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Title (Arabic)</FormLabel>
                        <FormControl>
                          <Input {...field} dir="rtl" />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                  <FormField
                    control={form.control}
                    name="description"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Description (English)</FormLabel>
                        <FormControl>
                          <Textarea {...field} />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                  <FormField
                    control={form.control}
                    name="descriptionAr"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Description (Arabic)</FormLabel>
                        <FormControl>
                          <Textarea {...field} dir="rtl" />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                  <FormField
                    control={form.control}
                    name="url"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>
                          {form.watch("type") === "image" ? "Image Upload" : "Video Source"}
                        </FormLabel>
                        <FormControl>
                          {form.watch("type") === "image" ? (
                            <div className="flex items-center space-x-2">
                              <Input
                                type="file"
                                accept="image/*"
                                onChange={async (e) => {
                                  try {
                                    const file = e.target.files?.[0];
                                    if (file) {
                                      const formData = new FormData();
                                      formData.append("file", file);

                                      const res = await fetch("/api/upload", {
                                        method: "POST",
                                        body: formData,
                                      });

                                      if (!res.ok) {
                                        const errorData = await res.json();
                                        throw new Error(errorData.details || `Upload failed: ${res.status}`);
                                      }

                                      const { url } = await res.json();
                                      field.onChange(url);
                                      form.setValue("url", url, {
                                        shouldDirty: true,
                                        shouldValidate: true,
                                        shouldTouch: true
                                      });

                                      toast({
                                        title: "Upload successful",
                                        description: "Media image has been uploaded.",
                                      });
                                    }
                                  } catch (error) {
                                    console.error("Upload error:", error);
                                    toast({
                                      title: "Upload failed",
                                      description: error instanceof Error ? error.message : "Failed to upload image",
                                      variant: "destructive",
                                    });
                                  }
                                }}
                              />
                              {field.value && (
                                <img
                                  src={field.value}
                                  alt="Media preview"
                                  className="w-10 h-10 rounded object-cover"
                                />
                              )}
                            </div>
                          ) : (
                            <Select
                              value={field.value}
                              onValueChange={field.onChange}
                            >
                              <SelectTrigger>
                                <SelectValue placeholder="Select a live stream" />
                              </SelectTrigger>
                              <SelectContent>
                                {liveSessions?.sessions?.map((session) => (
                                  <SelectItem key={session.id} value={session.liveStreamUrl}>
                                    {session.sessionTitle}
                                  </SelectItem>
                                ))}
                              </SelectContent>
                            </Select>
                          )}
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                  {form.watch("type") === "video" && (
                    <FormField
                      control={form.control}
                      name="thumbnail"
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel>Video Thumbnail (Optional)</FormLabel>
                          <FormControl>
                            <div className="flex items-center space-x-2">
                              <Input
                                type="file"
                                accept="image/*"
                                onChange={async (e) => {
                                  try {
                                    const file = e.target.files?.[0];
                                    if (file) {
                                      const formData = new FormData();
                                      formData.append("file", file);

                                      const res = await fetch("/api/upload", {
                                        method: "POST",
                                        body: formData,
                                      });

                                      if (!res.ok) {
                                        const errorData = await res.json();
                                        throw new Error(errorData.details || `Upload failed: ${res.status}`);
                                      }

                                      const { url } = await res.json();
                                      field.onChange(url);
                                      form.setValue("thumbnail", url, {
                                        shouldDirty: true,
                                        shouldValidate: true,
                                        shouldTouch: true
                                      });

                                      toast({
                                        title: "Upload successful",
                                        description: "Thumbnail has been uploaded.",
                                      });
                                    }
                                  } catch (error) {
                                    console.error("Upload error:", error);
                                    toast({
                                      title: "Upload failed",
                                      description: error instanceof Error ? error.message : "Failed to upload thumbnail",
                                      variant: "destructive",
                                    });
                                  }
                                }}
                              />
                              {field.value && (
                                <img
                                  src={field.value}
                                  alt="Thumbnail preview"
                                  className="w-10 h-10 rounded object-cover"
                                />
                              )}
                            </div>
                          </FormControl>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                  )}
                </div>
                <div className="flex justify-end gap-4">
                  <Button
                    type="button"
                    variant="outline"
                    onClick={() => {
                      setIsAdding(false);
                      setEditingMedia(null);
                      form.reset();
                    }}
                  >
                    Cancel
                  </Button>
                  <Button
                    type="submit"
                    disabled={createMediaMutation.isPending || updateMediaMutation.isPending}
                  >
                    {(createMediaMutation.isPending || updateMediaMutation.isPending) && (
                      <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                    )}
                    {editingMedia ? "Update Media" : "Add Media"}
                  </Button>
                </div>
              </form>
            </Form>
          </CardContent>
        </Card>
      )}

      <div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
        {media?.map((item) => (
          <Card key={item.id} className="flex flex-col">
            <CardContent className="p-6 flex-1">
              <div className="flex justify-between items-start mb-4">
                <div className="flex-1">
                  <h3 className="font-semibold text-lg mb-1">{item.title}</h3>
                  <p className="text-sm text-muted-foreground mb-2" dir="rtl">
                    {item.titleAr}
                  </p>
                  {item.description && (
                    <p className="text-sm mb-2">{item.description}</p>
                  )}
                  {item.descriptionAr && (
                    <p className="text-sm text-muted-foreground mb-4" dir="rtl">
                      {item.descriptionAr}
                    </p>
                  )}
                </div>
                <div className="flex gap-2 ml-4">
                  <Button
                    variant="ghost"
                    size="icon"
                    onClick={() => {
                      setEditingMedia(item);
                      setIsAdding(false);
                      resetForm(item);
                    }}
                  >
                    <Edit className="h-4 w-4" />
                  </Button>
                  <AlertDialog>
                    <AlertDialogTrigger asChild>
                      <Button
                        variant="ghost"
                        size="icon"
                        className="text-destructive"
                        onClick={() => setMediaToDelete(item)}
                      >
                        <Trash2 className="h-4 w-4" />
                      </Button>
                    </AlertDialogTrigger>
                    <AlertDialogContent>
                      <AlertDialogHeader>
                        <AlertDialogTitle>Delete Media</AlertDialogTitle>
                        <AlertDialogDescription>
                          Are you sure you want to delete this media item? This action cannot be undone.
                        </AlertDialogDescription>
                      </AlertDialogHeader>
                      <AlertDialogFooter>
                        <AlertDialogCancel onClick={() => setMediaToDelete(null)}>
                          Cancel
                        </AlertDialogCancel>
                        <AlertDialogAction
                          onClick={() => item.id && deleteMediaMutation.mutate(item.id)}
                          className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
                        >
                          {deleteMediaMutation.isPending ? (
                            <Loader2 className="h-4 w-4 animate-spin" />
                          ) : (
                            "Delete"
                          )}
                        </AlertDialogAction>
                      </AlertDialogFooter>
                    </AlertDialogContent>
                  </AlertDialog>
                </div>
              </div>
              <AspectRatio ratio={16 / 9} className="mb-4 bg-muted rounded-lg overflow-hidden">
                {item.type === "image" ? (
                  <img
                    src={item.url}
                    alt={item.title}
                    className="object-cover w-full h-full"
                  />
                ) : (
                  <iframe
                    src={item.url}
                    title={item.title}
                    className="w-full h-full"
                    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
                    allowFullScreen
                  />
                )}
              </AspectRatio>
              <div className="text-sm text-muted-foreground">
                {format(new Date(item.createdAt), "PPP")}
              </div>
            </CardContent>
          </Card>
        ))}
      </div>
    </div>
  );
}