"use client";

import { useState, useEffect, useRef, useMemo } from "react";
import Image from "next/image";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Switch } from "@/components/ui/switch";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import {
  Plus,
  Trash2,
  ImageIcon,
  FolderPlus,
  Lock,
  Video,
  Star,
  ChevronUp,
  ChevronDown,
  Eye,
  EyeOff,
} from "lucide-react";
import {
  loadGallery,
  createAlbum,
  addPhoto,
  addVideo,
  deletePhoto,
  deleteVideo,
  deleteAlbum,
  setAlbumPublic,
  togglePhotoOnProfile,
  toggleVideoOnProfile,
  reorderProfileMedia,
  type GalleryAlbum,
  type GalleryPhoto,
  type GalleryVideo,
} from "@/lib/gallery-store";
import {
  MAX_PHOTOS_PER_USER,
  MAX_VIDEOS_PER_USER,
  MAX_ALBUMS_PER_USER,
  MAX_PHOTO_SIZE_MB,
  MAX_VIDEO_DURATION_SEC,
  MAX_PROFILE_MEDIA_SLOTS,
} from "@/lib/limits";
import { getProfileMediaItems, countProfilePinned } from "@/lib/profile-media";
import { PhotoCropModal } from "@/components/PhotoCropModal";
import { useAuth } from "@/lib/auth/context";
import { useAccess } from "@/components/Providers";
import { GuestUpgradeBanner } from "@/components/GuestUpgradeBanner";
import { cn } from "@/lib/utils";

interface MediaGalleryManagerProps {
  onVerifyClick?: () => void;
}

export function MediaGalleryManager({ onVerifyClick }: MediaGalleryManagerProps) {
  const { user } = useAuth();
  const { capabilities, blurExplicit } = useAccess();
  const [albums, setAlbums] = useState<GalleryAlbum[]>([]);
  const [photos, setPhotos] = useState<GalleryPhoto[]>([]);
  const [videos, setVideos] = useState<GalleryVideo[]>([]);
  const [activeAlbum, setActiveAlbum] = useState<string>("main");
  const [newAlbumName, setNewAlbumName] = useState("");
  const [showNewAlbum, setShowNewAlbum] = useState(false);
  const [message, setMessage] = useState("");
  const [loading, setLoading] = useState(true);
  const [cropFile, setCropFile] = useState<File | null>(null);
  const [cropOpen, setCropOpen] = useState(false);
  const photoRef = useRef<HTMLInputElement>(null);
  const videoRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    let cancelled = false;
    (async () => {
      const data = await loadGallery(user?.id);
      if (!cancelled) {
        setAlbums(data.albums);
        setPhotos(data.photos);
        setVideos(data.videos);
        setLoading(false);
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [user?.id]);

  const refresh = async () => {
    const data = await loadGallery(user?.id);
    setAlbums(data.albums);
    setPhotos(data.photos);
    setVideos(data.videos);
    setLoading(false);
  };

  const activeAlbumMeta = albums.find((a) => a.id === activeAlbum);
  const albumPhotos = photos.filter((p) =>
    activeAlbum === "main" ? !p.album_id || p.album_id === "main" : p.album_id === activeAlbum
  );
  const albumVideos = videos.filter((v) =>
    activeAlbum === "main" ? !v.album_id || v.album_id === "main" : v.album_id === activeAlbum
  );

  const profileItems = useMemo(
    () => getProfileMediaItems(photos, videos),
    [photos, videos]
  );
  const pinnedCount = countProfilePinned(photos, videos);

  const handlePhotoPick = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    if (file.size > MAX_PHOTO_SIZE_MB * 1024 * 1024) {
      setMessage(`Max file size is ${MAX_PHOTO_SIZE_MB}MB.`);
      return;
    }
    setCropFile(file);
    setCropOpen(true);
    if (photoRef.current) photoRef.current.value = "";
  };

  const handleCropConfirm = async (file: File) => {
    const { error } = await addPhoto(file, activeAlbum, user?.id);
    if (error) setMessage(error);
    else {
      setMessage("Photo added!");
      await refresh();
    }
  };

  const handleVideoUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    const { error } = await addVideo(file, activeAlbum, user?.id);
    if (error) setMessage(error);
    else {
      setMessage("Video added!");
      await refresh();
    }
    if (videoRef.current) videoRef.current.value = "";
  };

  const handleCreateAlbum = async () => {
    const { album, error } = await createAlbum(newAlbumName, user?.id);
    if (error) setMessage(error);
    else {
      setNewAlbumName("");
      setShowNewAlbum(false);
      if (album) setActiveAlbum(album.id);
      await refresh();
    }
  };

  const moveProfileItem = async (index: number, dir: -1 | 1) => {
    const next = [...profileItems];
    const target = index + dir;
    if (target < 0 || target >= next.length) return;
    [next[index], next[target]] = [next[target], next[index]];
    await reorderProfileMedia(
      next.map((m) => ({ id: m.id, type: m.type })),
      user?.id
    );
    await refresh();
  };

  const handleToggleProfile = async (
    id: string,
    type: "photo" | "video",
    currentlyOn: boolean
  ) => {
    const { error } =
      type === "photo"
        ? await togglePhotoOnProfile(id, !currentlyOn, user?.id)
        : await toggleVideoOnProfile(id, !currentlyOn, user?.id);
    if (error) setMessage(error);
    else await refresh();
  };

  if (!capabilities.canUploadPhotos) {
    return <GuestUpgradeBanner reason="media" />;
  }

  if (loading) {
    return <p className="text-sm text-muted-foreground">Loading gallery...</p>;
  }

  return (
    <>
      <Card>
        <CardHeader className="pb-3">
          <div className="flex items-center justify-between gap-2">
            <CardTitle className="text-lg flex items-center gap-2">
              <ImageIcon className="h-5 w-5 text-primary" />
              Photos & Videos
            </CardTitle>
            <Badge variant="pill" className="text-[10px] shrink-0">
              {photos.length}/{MAX_PHOTOS_PER_USER} · {videos.length}/{MAX_VIDEOS_PER_USER} vid
            </Badge>
          </div>
          {blurExplicit && (
            <button
              type="button"
              onClick={onVerifyClick}
              className="flex items-center gap-2 text-xs text-amber-400 hover:underline mt-1"
            >
              <Lock className="h-3 w-3" />
              ID verification required to view nude media in your state
            </button>
          )}
        </CardHeader>

        <CardContent className="space-y-5">
          {/* Profile preview strip */}
          <div className="rounded-xl border border-primary/20 bg-pulse-midnight/40 p-3 space-y-2">
            <div className="flex items-center justify-between">
              <Label className="text-sm">Public profile preview</Label>
              <span className="text-[10px] text-muted-foreground">
                {pinnedCount}/{MAX_PROFILE_MEDIA_SLOTS} slots
              </span>
            </div>
            <p className="text-[10px] text-muted-foreground">
              Tap ★ to pin. Reorder with arrows. Others see these first.
            </p>
            <div className="flex gap-2 overflow-x-auto scrollbar-none">
              {profileItems.map((item, i) => (
                <div key={item.id} className="relative shrink-0 w-16">
                  <div className="relative w-16 h-16 rounded-lg overflow-hidden border-2 border-primary/50">
                    {item.type === "video" ? (
                      <div className="w-full h-full bg-black flex items-center justify-center">
                        <Video className="h-5 w-5 text-primary" />
                      </div>
                    ) : (
                      <Image
                        src={item.url}
                        alt=""
                        fill
                        className="object-cover"
                        unoptimized={item.url.startsWith("data:")}
                      />
                    )}
                  </div>
                  <div className="flex justify-center gap-0.5 mt-1">
                    <button
                      type="button"
                      className="p-0.5 text-primary"
                      onClick={() => moveProfileItem(i, -1)}
                      disabled={i === 0}
                    >
                      <ChevronUp className="h-3 w-3" />
                    </button>
                    <button
                      type="button"
                      className="p-0.5 text-primary"
                      onClick={() => moveProfileItem(i, 1)}
                      disabled={i === profileItems.length - 1}
                    >
                      <ChevronDown className="h-3 w-3" />
                    </button>
                  </div>
                </div>
              ))}
              {profileItems.length === 0 && (
                <p className="text-xs text-muted-foreground py-4">Add media below — first 5 auto-pin.</p>
              )}
            </div>
          </div>

          <Tabs value={activeAlbum} onValueChange={setActiveAlbum}>
            <div className="flex items-center gap-2 overflow-x-auto pb-1">
              <TabsList className="h-auto flex-wrap justify-start">
                {albums.map((a) => (
                  <TabsTrigger key={a.id} value={a.id} className="text-xs gap-1">
                    {a.name}
                    {!a.is_default && (
                      <button
                        type="button"
                        className="ml-1 opacity-50 hover:opacity-100"
                        onClick={(e) => {
                          e.stopPropagation();
                          deleteAlbum(a.id, user?.id).then(refresh);
                        }}
                      >
                        <Trash2 className="h-3 w-3" />
                      </button>
                    )}
                  </TabsTrigger>
                ))}
              </TabsList>
              {albums.length < MAX_ALBUMS_PER_USER && (
                <Button
                  variant="pill"
                  size="sm"
                  className="shrink-0 h-8 text-xs"
                  onClick={() => setShowNewAlbum(true)}
                >
                  <FolderPlus className="h-3 w-3 mr-1" />
                  Album
                </Button>
              )}
            </div>
          </Tabs>

          {activeAlbumMeta && !activeAlbumMeta.is_default && (
            <div className="flex items-center justify-between rounded-lg border border-border px-3 py-2">
              <div className="flex items-center gap-2 text-sm">
                {activeAlbumMeta.is_public ? (
                  <Eye className="h-4 w-4 text-primary" />
                ) : (
                  <EyeOff className="h-4 w-4 text-muted-foreground" />
                )}
                <span>Album visible to others</span>
              </div>
              <Switch
                checked={activeAlbumMeta.is_public}
                onCheckedChange={(v) =>
                  setAlbumPublic(activeAlbum, v, user?.id).then(refresh)
                }
              />
            </div>
          )}

          {showNewAlbum && (
            <div className="flex gap-2">
              <Input
                placeholder="Album name"
                value={newAlbumName}
                onChange={(e) => setNewAlbumName(e.target.value)}
                className="flex-1"
              />
              <Button variant="horny" size="sm" onClick={handleCreateAlbum}>
                Create
              </Button>
              <Button variant="ghost" size="sm" onClick={() => setShowNewAlbum(false)}>
                Cancel
              </Button>
            </div>
          )}

          <div className="grid grid-cols-3 sm:grid-cols-4 gap-2">
            {albumPhotos.map((photo) => {
              const onProfile = photo.show_on_profile;
              return (
                <div
                  key={photo.id}
                  className={cn(
                    "relative aspect-square rounded-lg overflow-hidden group border-2",
                    onProfile ? "border-primary/60" : "border-transparent",
                    blurExplicit && photo.is_explicit && "id-blur"
                  )}
                >
                  <Image
                    src={photo.url}
                    alt=""
                    fill
                    className="object-cover explicit-content"
                    unoptimized={photo.url.startsWith("data:")}
                  />
                  <div className="absolute top-1 left-1 flex gap-0.5">
                    <button
                      type="button"
                      onClick={() => handleToggleProfile(photo.id, "photo", onProfile)}
                      className={cn(
                        "p-1 rounded-full bg-black/60",
                        onProfile ? "text-primary" : "text-white/70"
                      )}
                    >
                      <Star className="h-3 w-3" fill={onProfile ? "currentColor" : "none"} />
                    </button>
                  </div>
                  <button
                    type="button"
                    onClick={() => deletePhoto(photo.id, user?.id).then(refresh)}
                    className="absolute top-1 right-1 p-1 rounded-full bg-black/60 opacity-0 group-hover:opacity-100 transition-opacity"
                  >
                    <Trash2 className="h-3 w-3 text-white" />
                  </button>
                </div>
              );
            })}

            {albumVideos.map((video) => {
              const onProfile = video.show_on_profile;
              return (
                <div
                  key={video.id}
                  className={cn(
                    "relative aspect-square rounded-lg overflow-hidden border-2 bg-black flex flex-col items-center justify-center",
                    onProfile ? "border-primary/60" : "border-pulse-violet/40"
                  )}
                >
                  <Video className="h-8 w-8 text-primary mb-1" />
                  <span className="text-[10px] text-muted-foreground">
                    {video.duration_sec ? `${Math.round(video.duration_sec)}s` : "video"}
                  </span>
                  <button
                    type="button"
                    onClick={() => handleToggleProfile(video.id, "video", onProfile)}
                    className={cn(
                      "absolute top-1 left-1 p-1 rounded-full bg-black/60",
                      onProfile ? "text-primary" : "text-white/70"
                    )}
                  >
                    <Star className="h-3 w-3" fill={onProfile ? "currentColor" : "none"} />
                  </button>
                  <button
                    type="button"
                    onClick={() => deleteVideo(video.id, user?.id).then(refresh)}
                    className="absolute top-1 right-1 p-1 rounded-full bg-black/60"
                  >
                    <Trash2 className="h-3 w-3 text-white" />
                  </button>
                </div>
              );
            })}

            {photos.length < MAX_PHOTOS_PER_USER && (
              <button
                type="button"
                onClick={() => photoRef.current?.click()}
                className="aspect-square rounded-lg border-2 border-dashed border-border flex flex-col items-center justify-center gap-1 hover:border-primary/50 transition-colors touch-manipulation"
              >
                <Plus className="h-6 w-6 text-muted-foreground" />
                <span className="text-[10px] text-muted-foreground">Photo</span>
              </button>
            )}

            {videos.length < MAX_VIDEOS_PER_USER && (
              <button
                type="button"
                onClick={() => videoRef.current?.click()}
                className="aspect-square rounded-lg border-2 border-dashed border-pulse-violet/30 flex flex-col items-center justify-center gap-1 hover:border-primary/50 transition-colors touch-manipulation"
              >
                <Video className="h-6 w-6 text-muted-foreground" />
                <span className="text-[10px] text-muted-foreground">Video ≤{MAX_VIDEO_DURATION_SEC}s</span>
              </button>
            )}
          </div>

          <input
            ref={photoRef}
            type="file"
            accept="image/jpeg,image/png,image/webp,image/heic"
            className="hidden"
            onChange={handlePhotoPick}
          />
          <input
            ref={videoRef}
            type="file"
            accept="video/mp4,video/webm,video/quicktime"
            className="hidden"
            onChange={handleVideoUpload}
          />

          {message && (
            <p
              className={`text-xs text-center ${message.includes("Maximum") || message.includes("Max") || message.includes("must") ? "text-destructive" : "text-green-400"}`}
            >
              {message}
            </p>
          )}

          <p className="text-[10px] text-muted-foreground text-center leading-relaxed">
            {MAX_PHOTOS_PER_USER} photos · {MAX_VIDEOS_PER_USER} videos (≤{MAX_VIDEO_DURATION_SEC}s) ·{" "}
            {MAX_ALBUMS_PER_USER} albums. Photos auto-optimized on upload. Crop before saving.
          </p>
        </CardContent>
      </Card>

      <PhotoCropModal
        file={cropFile}
        open={cropOpen}
        onClose={() => {
          setCropOpen(false);
          setCropFile(null);
        }}
        onConfirm={handleCropConfirm}
      />
    </>
  );
}

/** @deprecated */
export function PhotoGalleryManager(props: MediaGalleryManagerProps) {
  return <MediaGalleryManager {...props} />;
}