"use client";

import { useState, useCallback } from "react";
import { Trash2, Globe, Lock, Link2, X, Check, ListChecks } from "lucide-react";
import { Button, buttonVariants } from "@/components/ui/button";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { toast } from "sonner";
import { getPublicUrl } from "@/lib/storage";
import { Badge } from "@/components/ui/badge";
import { Clock, Users } from "lucide-react";
import Link from "next/link";
import { cn } from "@/lib/utils";

type Recipe = {
  id: string;
  title: string;
  description: string | null;
  baseServings: number;
  prepMins: number | null;
  cookMins: number | null;
  difficulty: "easy" | "medium" | "hard" | null;
  visibility: "private" | "unlisted" | "public";
  updatedAt: Date;
  photos?: Array<{ storageKey: string; isCover: boolean }>;
};

const DIFFICULTY_COLOR = { easy: "default", medium: "secondary", hard: "destructive" } as const;
const VISIBILITY_ICON = { private: Lock, unlisted: Link2, public: Globe };

function SelectableRecipeCard({
  recipe,
  selected,
  selectMode,
  onToggle,
}: {
  recipe: Recipe;
  selected: boolean;
  selectMode: boolean;
  onToggle: (id: string) => void;
}) {
  const cover = recipe.photos?.find((p) => p.isCover) ?? recipe.photos?.[0];
  const totalMins = (recipe.prepMins ?? 0) + (recipe.cookMins ?? 0);
  const VisibilityIcon = VISIBILITY_ICON[recipe.visibility];

  const inner = (
    <div
      className={cn(
        "group relative overflow-hidden rounded-xl border bg-card flex flex-col h-full transition-all duration-200",
        selectMode && "cursor-pointer select-none",
        selected
          ? "ring-2 ring-primary border-primary shadow-lg shadow-primary/10"
          : selectMode
          ? "hover:border-muted-foreground/40"
          : "hover:shadow-md hover:border-muted-foreground/30"
      )}
    >
      {/* Cover image */}
      <div className="relative aspect-video overflow-hidden bg-muted shrink-0">
        {cover ? (
          <img
            src={getPublicUrl(cover.storageKey)}
            alt={recipe.title}
            className={cn(
              "w-full h-full object-cover transition-transform duration-300",
              !selectMode && "group-hover:scale-105",
              selectMode && selected && "brightness-75"
            )}
          />
        ) : (
          <div className={cn(
            "w-full h-full flex items-center justify-center text-4xl transition-opacity",
            selectMode && !selected && "opacity-60"
          )}>
            🍽️
          </div>
        )}

        {/* Selection overlay tint */}
        {selectMode && selected && (
          <div className="absolute inset-0 bg-primary/20" />
        )}

        {/* Checkbox */}
        {selectMode ? (
          <div className={cn(
            "absolute top-2.5 left-2.5 h-6 w-6 rounded-full border-2 flex items-center justify-center transition-all duration-150 shadow-sm",
            selected
              ? "bg-primary border-primary"
              : "bg-black/30 border-white/70 group-hover:border-white"
          )}>
            {selected && <Check className="h-3.5 w-3.5 text-primary-foreground stroke-[3]" />}
          </div>
        ) : null}
      </div>

      {/* Body */}
      <div className="flex flex-col flex-1 p-3 gap-1">
        <h3 className={cn(
          "font-semibold leading-tight line-clamp-2 text-sm transition-colors",
          !selectMode && "group-hover:text-primary"
        )}>
          {recipe.title}
        </h3>
        {recipe.description && (
          <p className="text-xs text-muted-foreground line-clamp-2 leading-relaxed">
            {recipe.description}
          </p>
        )}
      </div>

      {/* Footer */}
      <div className="px-3 pb-3 flex items-center justify-between text-xs text-muted-foreground">
        <div className="flex items-center gap-2.5">
          <span className="flex items-center gap-1">
            <Users className="h-3 w-3" />
            {recipe.baseServings}
          </span>
          {totalMins > 0 && (
            <span className="flex items-center gap-1">
              <Clock className="h-3 w-3" />
              {totalMins}m
            </span>
          )}
          {recipe.difficulty && (
            <Badge variant={DIFFICULTY_COLOR[recipe.difficulty]} className="text-xs h-4 px-1.5">
              {recipe.difficulty}
            </Badge>
          )}
        </div>
        <VisibilityIcon className="h-3 w-3 shrink-0" />
      </div>
    </div>
  );

  if (selectMode) {
    return (
      <div
        onClick={() => onToggle(recipe.id)}
        role="checkbox"
        aria-checked={selected}
        className="h-full"
      >
        {inner}
      </div>
    );
  }

  return (
    <Link href={`/recipes/${recipe.id}`} className="h-full block">
      {inner}
    </Link>
  );
}

export function RecipesGrid({ recipes: initialRecipes }: { recipes: Recipe[] }) {
  const [recipes, setRecipes] = useState(initialRecipes);
  const [selectMode, setSelectMode] = useState(false);
  const [selected, setSelected] = useState<Set<string>>(new Set());
  const [busy, setBusy] = useState(false);

  const toggleSelect = useCallback((id: string) => {
    setSelected((prev) => {
      const next = new Set(prev);
      next.has(id) ? next.delete(id) : next.add(id);
      return next;
    });
  }, []);

  const toggleAll = () => {
    setSelected((prev) =>
      prev.size === recipes.length ? new Set() : new Set(recipes.map((r) => r.id))
    );
  };

  const exitSelect = () => {
    setSelectMode(false);
    setSelected(new Set());
  };

  async function bulkDelete() {
    if (!confirm(`Delete ${selected.size} recipe${selected.size !== 1 ? "s" : ""}? This cannot be undone.`)) return;
    setBusy(true);
    try {
      const res = await fetch("/api/v1/recipes/bulk", {
        method: "DELETE",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ ids: [...selected] }),
      });
      if (!res.ok) throw new Error("Delete failed");
      setRecipes((prev) => prev.filter((r) => !selected.has(r.id)));
      toast.success(`${selected.size} recipe${selected.size !== 1 ? "s" : ""} deleted`);
      exitSelect();
    } catch {
      toast.error("Delete failed");
    } finally {
      setBusy(false);
    }
  }

  async function bulkSetVisibility(visibility: "private" | "unlisted" | "public") {
    setBusy(true);
    try {
      const res = await fetch("/api/v1/recipes/bulk", {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ ids: [...selected], visibility }),
      });
      if (!res.ok) throw new Error("Update failed");
      setRecipes((prev) =>
        prev.map((r) => selected.has(r.id) ? { ...r, visibility } : r)
      );
      toast.success(`${selected.size} recipe${selected.size !== 1 ? "s" : ""} set to ${visibility}`);
      exitSelect();
    } catch {
      toast.error("Update failed");
    } finally {
      setBusy(false);
    }
  }

  if (recipes.length === 0) return null;

  const allSelected = selected.size === recipes.length;

  return (
    <div className="space-y-4">
      {/* Toolbar */}
      <div className="flex items-center justify-between min-h-[36px]">
        {selectMode ? (
          <div className="flex items-center gap-3">
            <button
              onClick={toggleAll}
              className="text-sm font-medium text-primary hover:underline"
            >
              {allSelected ? "Deselect all" : "Select all"}
            </button>
            <span className="text-sm text-muted-foreground">
              {selected.size > 0
                ? `${selected.size} selected`
                : "Click cards to select"}
            </span>
          </div>
        ) : (
          <div />
        )}
        <Button
          variant={selectMode ? "ghost" : "ghost"}
          size="sm"
          onClick={selectMode ? exitSelect : () => setSelectMode(true)}
          className={cn("gap-1.5", selectMode && "text-muted-foreground")}
        >
          {selectMode ? (
            <><X className="h-4 w-4" />Cancel</>
          ) : (
            <><ListChecks className="h-4 w-4" />Select</>
          )}
        </Button>
      </div>

      {/* Grid */}
      <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 items-start">
        {recipes.map((recipe) => (
          <SelectableRecipeCard
            key={recipe.id}
            recipe={recipe}
            selected={selected.has(recipe.id)}
            selectMode={selectMode}
            onToggle={toggleSelect}
          />
        ))}
      </div>

      {/* Floating bulk action bar */}
      {selectMode && selected.size > 0 && (
        <div className="fixed bottom-8 left-1/2 -translate-x-1/2 z-50 animate-in slide-in-from-bottom-4 duration-200">
          <div className="flex items-center gap-2 bg-popover border shadow-2xl rounded-2xl px-5 py-3">
            <span className="text-sm font-semibold tabular-nums mr-1">
              {selected.size} selected
            </span>
            <div className="w-px h-5 bg-border mx-1" />
            <DropdownMenu>
              <DropdownMenuTrigger
                disabled={busy}
                className={buttonVariants({ variant: "ghost", size: "sm" }) + " gap-1.5"}
              >
                <Globe className="h-4 w-4" />
                Visibility
              </DropdownMenuTrigger>
              <DropdownMenuContent align="center" side="top">
                <DropdownMenuItem onClick={() => { void bulkSetVisibility("public"); }}>
                  <Globe className="h-4 w-4 mr-2 text-green-500" /> Make public
                </DropdownMenuItem>
                <DropdownMenuItem onClick={() => { void bulkSetVisibility("unlisted"); }}>
                  <Link2 className="h-4 w-4 mr-2 text-yellow-500" /> Make unlisted
                </DropdownMenuItem>
                <DropdownMenuItem onClick={() => { void bulkSetVisibility("private"); }}>
                  <Lock className="h-4 w-4 mr-2 text-muted-foreground" /> Make private
                </DropdownMenuItem>
              </DropdownMenuContent>
            </DropdownMenu>
            <Button
              variant="destructive"
              size="sm"
              onClick={() => { void bulkDelete(); }}
              disabled={busy}
              className="gap-1.5"
            >
              <Trash2 className="h-4 w-4" />
              Delete
            </Button>
          </div>
        </div>
      )}
    </div>
  );
}
