'use client';

import React, { useEffect, useState } from 'react';
import { SidebarProvider, SidebarInset } from '@/components/ui/sidebar';
import { AppSidebar } from '@/components/app-sidebar';
import { SiteHeader } from '@/components/site-header';
import { useRouter } from 'next/navigation';
import { toast } from 'sonner';
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
} from '@/components/ui/card';
import {
  Field,
  FieldGroup,
  FieldLabel,
  FieldDescription,
} from '@/components/ui/field';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table';
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from '@/components/ui/alert-dialog';
import { Trash2Icon, Edit2, Check, X } from 'lucide-react';
import {
  DndContext,
  PointerSensor,
  useSensor,
  useSensors,
  closestCenter,
} from '@dnd-kit/core';
import {
  arrayMove,
  SortableContext,
  verticalListSortingStrategy,
  useSortable,
} from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';

type Course = { id: string; title: string; code?: string };
type Playlist = { id: string; title: string; courseId: string };

function PlaylistsUI() {
  const router = useRouter();
  const [courses, setCourses] = useState<Course[]>([]);
  const [playlists, setPlaylists] = useState<Playlist[]>([]);
  const [loading, setLoading] = useState(false);
  const [playlistTitle, setPlaylistTitle] = useState('');
  const [playlistCourseId, setPlaylistCourseId] = useState('');
  const [additionalCourseIds, setAdditionalCourseIds] = useState<string[]>([]);
  const [deletingId, setDeletingId] = useState<string | null>(null);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [editingTitle, setEditingTitle] = useState('');
  const [savingEditId, setSavingEditId] = useState<string | null>(null);

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

  async function fetchData() {
    try {
      const res = await fetch('/api/admin/meta');
      if (res.ok) {
        const json = await res.json();
        setCourses(json.courses || []);
        setPlaylists(json.playlists || []);
        if (!playlistCourseId && json.courses?.[0]) {
          setPlaylistCourseId(json.courses[0].id);
        }
      }
    } catch (err) {
      console.error('Failed to fetch data', err);
      toast.error('Failed to fetch data');
    }
  }

  async function createPlaylist(e: React.FormEvent) {
    e.preventDefault();
    if (!playlistCourseId) {
      toast.error('Pick a primary course first');
      return;
    }
    setLoading(true);
    try {
      const res = await fetch('/api/admin/create-playlist', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          title: playlistTitle,
          courseId: playlistCourseId,
          additionalCourseIds,
        }),
      });
      if (res.ok) {
        toast.success('Playlist created');
        setPlaylistTitle('');
        setAdditionalCourseIds([]);
        await fetchData();
        router.refresh();
      } else {
        const txt = await res.text();
        toast.error('Failed to create playlist: ' + txt);
      }
    } catch (err: any) {
      toast.error('Error: ' + String(err.message ?? err));
    } finally {
      setLoading(false);
    }
  }

  async function deletePlaylist(playlistId: string) {
    setDeletingId(playlistId);
    try {
      const res = await fetch(`/api/admin/delete-playlist`, {
        method: 'DELETE',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ playlistId }),
      });
      if (res.ok) {
        toast.success('Playlist deleted');
        await fetchData();
        router.refresh();
      } else {
        const txt = await res.text();
        toast.error('Failed to delete playlist: ' + txt);
      }
    } catch (err: any) {
      toast.error('Error: ' + String(err.message ?? err));
    } finally {
      setDeletingId(null);
    }
  }

  async function updatePlaylistTitle(playlistId: string, newTitle: string) {
    if (!newTitle.trim()) {
      toast.error('Title cannot be empty');
      return;
    }

    setSavingEditId(playlistId);
    try {
      const res = await fetch(`/api/admin/update-playlist`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ playlistId, title: newTitle }),
      });
      if (res.ok) {
        toast.success('Playlist updated');
        setEditingId(null);
        setEditingTitle('');
        await fetchData();
        router.refresh();
      } else {
        const txt = await res.text();
        toast.error('Failed to update playlist: ' + txt);
      }
    } catch (err: any) {
      toast.error('Error: ' + String(err.message ?? err));
    } finally {
      setSavingEditId(null);
    }
  }

    // Organizer state & helpers
    const [selectedPlaylistId, setSelectedPlaylistId] = useState<string>('');
    const [videos, setVideos] = useState<Array<{ id: string; title: string; thumbnail?: string; index: number; durationSec?: number }>>([]);
    const sensors = useSensors(useSensor(PointerSensor));

    function SortableItem({ id, title, thumbnail }: { id: string; title: string; thumbnail?: string }) {
      const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id });
      const style = {
        transform: CSS.Transform.toString(transform),
        transition,
      } as React.CSSProperties;

      return (
        <div ref={setNodeRef} style={style} className="w-40 p-2">
          <div className="cursor-move" {...attributes} {...listeners}>
            {thumbnail ? (
              <img src={thumbnail} alt={title} className="w-full h-24 object-cover rounded" />
            ) : (
              <div className="w-full h-24 bg-muted rounded flex items-center justify-center">No image</div>
            )}
            <div className="text-sm mt-2 truncate">{title}</div>
          </div>
        </div>
      );
    }

    async function fetchPlaylistVideos(playlistId: string) {
      if (!playlistId) return;
      try {
        const res = await fetch(`/api/admin/playlist-videos?playlistId=${playlistId}`);
        if (res.ok) {
          const data = await res.json();
          setVideos(data || []);
        } else {
          toast.error('Failed to load playlist videos');
        }
      } catch (err) {
        console.error('Failed to fetch playlist videos', err);
        toast.error('Failed to load playlist videos');
      }
    }

    async function handleDragEnd(e: any) {
      const { active, over } = e;
      if (!over || active.id === over.id) return;
      const oldIndex = videos.findIndex((v) => v.id === active.id);
      const newIndex = videos.findIndex((v) => v.id === over.id);
      if (oldIndex === -1 || newIndex === -1) return;
      const newOrder = arrayMove(videos, oldIndex, newIndex);
      setVideos(newOrder.map((v, idx) => ({ ...v, index: idx })));

      // Persist order
      try {
        const orderedIds = newOrder.map((v) => v.id);
        const res = await fetch('/api/admin/reorder-videos', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ playlistId: selectedPlaylistId, orderedIds }),
        });
        if (!res.ok) {
          toast.error('Failed to save new order');
          // refetch to revert
          await fetchPlaylistVideos(selectedPlaylistId);
        } else {
          toast.success('Order saved');
        }
      } catch (err) {
        console.error('Failed to save order', err);
        toast.error('Failed to save new order');
        await fetchPlaylistVideos(selectedPlaylistId);
      }
    }

  const getCourseTitle = (courseId: string) => {
    return courses.find((c) => c.id === courseId)?.title || 'Unknown Course';
  };

  return (
    <div className="flex flex-col gap-6 py-4 md:gap-6 md:py-6 px-4 lg:px-16">
      <Card>
        <CardHeader>
          <CardTitle>Create Playlist</CardTitle>
        </CardHeader>
        <CardContent>
          <form onSubmit={createPlaylist}>
            <FieldGroup>
              <Field>
                <FieldLabel htmlFor="playlistTitle">Playlist title</FieldLabel>
                <FieldDescription>
                  e.g. Character Rigging Basics
                </FieldDescription>
                <Input
                  id="playlistTitle"
                  required
                  value={playlistTitle}
                  onChange={(e) => setPlaylistTitle(e.target.value)}
                  placeholder="Playlist title"
                />
              </Field>

              <Field>
                <FieldLabel htmlFor="playlistCourse">Assign to course (primary)</FieldLabel>
                <FieldDescription>
                  Select the main course. The playlist will always be accessible from here.
                </FieldDescription>
                <Select
                  value={playlistCourseId}
                  onValueChange={(val) => setPlaylistCourseId(val)}
                >
                  <SelectTrigger aria-label="Choose Primary Course">
                    <SelectValue placeholder="Choose Primary Course" />
                  </SelectTrigger>
                  <SelectContent>
                    {courses.map((c) => (
                      <SelectItem key={c.id} value={c.id}>
                        {c.title} {c.code ? `| ${c.code}` : ''}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </Field>

              <Field>
                <FieldLabel>Assign to additional courses (optional)</FieldLabel>
                <FieldDescription>
                  Select other courses where this playlist should appear.
                </FieldDescription>
                <div className="space-y-2 mt-2">
                  {courses
                    .filter((c) => c.id !== playlistCourseId)
                    .map((c) => (
                      <label key={c.id} className="flex items-center gap-2 text-sm">
                        <input
                          type="checkbox"
                          checked={additionalCourseIds.includes(c.id)}
                          onChange={(e) => {
                            if (e.target.checked) {
                              setAdditionalCourseIds([...additionalCourseIds, c.id]);
                            } else {
                              setAdditionalCourseIds(additionalCourseIds.filter((id) => id !== c.id));
                            }
                          }}
                          className="w-4 h-4"
                        />
                        <span>
                          {c.title} {c.code ? `| ${c.code}` : ''}
                        </span>
                      </label>
                    ))}
                </div>
              </Field>

              <Field>
                <Button type="submit" disabled={loading || !playlistCourseId}>
                  Create playlist
                </Button>
              </Field>
            </FieldGroup>
          </form>
        </CardContent>
      </Card>

      <Card>
        <CardHeader>
          <CardTitle>Organize Playlist</CardTitle>
        </CardHeader>
        <CardContent>
          <div className="grid grid-cols-1 gap-4 md:grid-cols-2 items-end">
            <div>
              <Field>
                <FieldLabel htmlFor="organizePlaylist">Select playlist</FieldLabel>
                <Select
                  value={selectedPlaylistId}
                  onValueChange={(val) => {
                    setSelectedPlaylistId(val);
                    fetchPlaylistVideos(val);
                  }}
                >
                  <SelectTrigger aria-label="Choose playlist">
                    <SelectValue placeholder="Choose playlist to organize" />
                  </SelectTrigger>
                  <SelectContent>
                    {playlists.map((p) => (
                      <SelectItem key={p.id} value={p.id}>
                        {p.title}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </Field>
            </div>
          </div>

          <div className="mt-4">
            {videos.length === 0 ? (
              <div className="text-center py-6 text-muted-foreground">No videos loaded</div>
            ) : (
              <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
                <SortableContext items={videos.map((v) => v.id)} strategy={verticalListSortingStrategy}>
                  <div className="flex gap-4 overflow-auto py-2">
                    {videos.map((v) => (
                      <SortableItem key={v.id} id={v.id} title={v.title} thumbnail={v.thumbnail} />
                    ))}
                  </div>
                </SortableContext>
              </DndContext>
            )}
          </div>
        </CardContent>
      </Card>

      <Card>
        <CardHeader>
          <CardTitle>Playlists</CardTitle>
        </CardHeader>
        <CardContent>
          {playlists.length === 0 ? (
            <div className="text-center py-8 text-muted-foreground">
              No playlists yet
            </div>
          ) : (
            <div className="overflow-x-auto">
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>Title</TableHead>
                    <TableHead>Course</TableHead>
                    <TableHead className="text-right">Actions</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {playlists.map((playlist) => (
                    <TableRow key={playlist.id}>
                      <TableCell className="font-medium">
                        {editingId === playlist.id ? (
                          <div className="flex gap-2 items-center">
                            <Input
                              value={editingTitle}
                              onChange={(e) => setEditingTitle(e.target.value)}
                              className="h-8"
                              autoFocus
                              onKeyDown={(e) => {
                                if (e.key === 'Enter') {
                                  updatePlaylistTitle(playlist.id, editingTitle);
                                }
                                if (e.key === 'Escape') {
                                  setEditingId(null);
                                  setEditingTitle('');
                                }
                              }}
                            />
                            <Button
                              variant="ghost"
                              size="sm"
                              onClick={() => updatePlaylistTitle(playlist.id, editingTitle)}
                              disabled={savingEditId === playlist.id}
                            >
                              <Check className="w-4 h-4" />
                            </Button>
                            <Button
                              variant="ghost"
                              size="sm"
                              onClick={() => {
                                setEditingId(null);
                                setEditingTitle('');
                              }}
                              disabled={savingEditId === playlist.id}
                            >
                              <X className="w-4 h-4" />
                            </Button>
                          </div>
                        ) : (
                          <div className="flex gap-2 items-center">
                            <span>{playlist.title}</span>
                            <Button
                              variant="ghost"
                              size="sm"
                              onClick={() => {
                                setEditingId(playlist.id);
                                setEditingTitle(playlist.title);
                              }}
                            >
                              <Edit2 className="w-4 h-4" />
                            </Button>
                          </div>
                        )}
                      </TableCell>
                      <TableCell>{getCourseTitle(playlist.courseId)}</TableCell>
                      <TableCell className="text-right">
                        <AlertDialog>
                          <AlertDialogTrigger asChild>
                            <Button
                              variant="ghost"
                              size="sm"
                              disabled={deletingId === playlist.id || editingId === playlist.id}
                            >
                              <Trash2Icon className="w-4 h-4" />
                            </Button>
                          </AlertDialogTrigger>
                          <AlertDialogContent>
                            <AlertDialogHeader>
                              <AlertDialogTitle>Delete Playlist</AlertDialogTitle>
                              <AlertDialogDescription>
                                Are you sure? This will delete the playlist and all
                                associated videos.
                              </AlertDialogDescription>
                            </AlertDialogHeader>
                            <div className="flex gap-2 justify-end">
                              <AlertDialogCancel>Cancel</AlertDialogCancel>
                              <AlertDialogAction
                                onClick={() => deletePlaylist(playlist.id)}
                              >
                                Delete
                              </AlertDialogAction>
                            </div>
                          </AlertDialogContent>
                        </AlertDialog>
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </div>
          )}
        </CardContent>
      </Card>
    </div>
  );
}

export default function PlaylistsAdminClient() {
  return (
    <SidebarProvider
      style={
        {
          '--sidebar-width': 'calc(var(--spacing) * 72)',
          '--header-height': 'calc(var(--spacing) * 12)',
        } as React.CSSProperties
      }
    >
      <AppSidebar variant="inset" />
      <SidebarInset>
        <SiteHeader />
        <div className="flex flex-1 flex-col">
          <div className="@container/main flex flex-1 flex-col gap-2">
            <PlaylistsUI />
          </div>
        </div>
      </SidebarInset>
    </SidebarProvider>
  );
}
