"use client";

import { useState, useTransition } from "react";
import Link from "next/link";
import { useRouter, usePathname } from "next/navigation";
import { PlusCircle, Sparkles, Link2, Search, X, SlidersHorizontal, ArrowUpDown } from "lucide-react";
import { useTranslations } from "next-intl";
import { Button, buttonVariants } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuGroup,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { AiGenerateDialog } from "./ai-generate-dialog";
import { UrlImportDialog } from "./url-import-dialog";
import { UpgradeDialog } from "@/components/premium/upgrade-dialog";
import { ProBadge } from "@/components/premium/pro-badge";

function TagFilterInput({ value, onChange }: { value: string; onChange: (v: string) => void }) {
  const [local, setLocal] = useState(value);
  const t = useTranslations("recipes");
  return (
    <input
      value={local}
      onChange={(e) => setLocal(e.target.value)}
      onKeyDown={(e) => {
        // Stop the dropdown menu's own keydown handling (roving focus / type-ahead
        // search) from intercepting keystrokes meant for this plain text input.
        e.stopPropagation();
        if (e.key === "Enter") onChange(local);
      }}
      onClick={(e) => e.stopPropagation()}
      onBlur={() => onChange(local)}
      placeholder={t("filterByTag")}
      className="w-full h-7 px-2 text-sm rounded-md border border-input bg-background focus:outline-none focus:ring-1 focus:ring-ring"
    />
  );
}
import { cn } from "@/lib/utils";

const SORT_KEYS: Record<string, string> = {
  updated_desc: "sortRecentlyUpdated",
  updated_asc: "sortOldestUpdated",
  created_desc: "sortNewestFirst",
  created_asc: "sortOldestFirst",
  title_asc: "sortTitleAZ",
  title_desc: "sortTitleZA",
};

const VISIBILITY_KEYS: Record<string, string> = {
  "": "all",
  private: "private",
  followers: "followers",
  unlisted: "unlisted",
  public: "public",
};

const DIFFICULTY_KEYS: Record<string, string> = {
  "": "anyDifficulty",
  easy: "easy",
  medium: "medium",
  hard: "hard",
};

const BATCH_COOK_KEYS: Record<string, string> = {
  "": "all",
  "1": "batchCookOnly",
  "0": "batchCookExclude",
};

const RECIPE_TYPE_KEYS: Record<string, string> = {
  "": "all",
  dish: "dish",
  drink: "drink",
};

export function RecipesHeader({
  count,
  initialQuery = "",
  initialSort = "updated_desc",
  initialVisibility = "",
  initialDifficulty = "",
  initialTag = "",
  initialBatchCook = "",
  initialRecipeType = "",
  sharedUrl,
  importUrlAvailable = true,
  importUrlLocked = false,
  importPhotoAvailable = true,
  importPhotoLocked = false,
}: {
  count: number;
  initialQuery?: string;
  initialSort?: string;
  initialVisibility?: string;
  initialDifficulty?: string;
  initialTag?: string;
  initialBatchCook?: string;
  initialRecipeType?: string;
  /** A link shared into the installed PWA via the OS share sheet (Web Share
   * Target, Chromium/Android only) — see manifest.ts's share_target and
   * page.tsx's read of the `url`/`text` params it's redirected here with.
   * Auto-opens the import dialog pre-filled instead of requiring the user
   * to paste the link again. */
  sharedUrl?: string;
  /** Tier feature flag (recipe_import_url) disabled for every tier — hides
   * the button and dialog entirely, since there's no upgrade path. */
  importUrlAvailable?: boolean;
  /** Available on some tier but not the viewer's — button still shows
   * (with a "Pro" upsell) and opens an upgrade prompt instead of the
   * import dialog. */
  importUrlLocked?: boolean;
  /** Same idea, for the AI-generate dialog's Photo tab (recipe_import_photo). */
  importPhotoAvailable?: boolean;
  importPhotoLocked?: boolean;
}) {
  const router = useRouter();
  const pathname = usePathname();
  const t = useTranslations("recipes");
  const tRecipe = useTranslations("recipe");
  const [aiOpen, setAiOpen] = useState(false);
  const [urlOpen, setUrlOpen] = useState(!!sharedUrl && !importUrlLocked);
  const [upgradeOpen, setUpgradeOpen] = useState(false);
  const [query, setQuery] = useState(initialQuery);
  const [, startTransition] = useTransition();

  function pushParams(overrides: Record<string, string>) {
    const params = new URLSearchParams();
    const current = {
      q: query,
      sort: initialSort,
      visibility: initialVisibility,
      difficulty: initialDifficulty,
      tag: initialTag,
      batchCook: initialBatchCook,
      recipeType: initialRecipeType,
      ...overrides,
    };
    if (current.q?.trim()) params.set("q", current.q.trim());
    if (current.sort && current.sort !== "updated_desc") params.set("sort", current.sort);
    if (current.visibility) params.set("visibility", current.visibility);
    if (current.difficulty) params.set("difficulty", current.difficulty);
    if (current.tag?.trim()) params.set("tag", current.tag.trim());
    if (current.batchCook) params.set("batchCook", current.batchCook);
    if (current.recipeType) params.set("recipeType", current.recipeType);
    startTransition(() => router.push(`${pathname}?${params.toString()}`));
  }

  function handleSearch(value: string) {
    setQuery(value);
    pushParams({ q: value });
  }

  const activeFilterCount = [initialVisibility, initialDifficulty, initialTag, initialBatchCook, initialRecipeType].filter(Boolean).length;
  const sortChanged = initialSort !== "updated_desc";

  return (
    <>
      <div className="space-y-3 sm:space-y-4">
        <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between sm:gap-3">
          <div>
            <h1 className="text-2xl sm:text-3xl font-bold tracking-tight">{t("title")}</h1>
            <p className="text-muted-foreground text-sm sm:text-base mt-0.5 sm:mt-1">
              {count === 0
                ? t("subtitle")
                : t(count !== 1 ? "resultPlural" : "resultSingular", { count })}
            </p>
          </div>
          <div className="flex flex-wrap items-center gap-2">
            <Button size="sm" className="gap-1.5" onClick={() => setAiOpen(true)}>
              <Sparkles className="h-4 w-4" />
              {t("generate")}
            </Button>
            {importUrlAvailable && (
              <Button
                variant="outline"
                size="sm"
                className="gap-1.5"
                onClick={() => (importUrlLocked ? setUpgradeOpen(true) : setUrlOpen(true))}
              >
                <Link2 className="h-4 w-4" />
                {t("importUrl")}
                {importUrlLocked && <ProBadge />}
              </Button>
            )}
            <Link href="/recipes/new" className={cn(buttonVariants({ variant: "ghost", size: "sm" }), "gap-1.5")}>
              <PlusCircle className="h-4 w-4" />
              <span className="hidden sm:inline">{t("new")}</span>
            </Link>
          </div>
        </div>

        <div className="flex flex-wrap gap-2">
          {/* Search — shares the row with Sort/Filter even on mobile now that
              those are icon-only there, instead of forcing a whole row to itself. */}
          <div className="relative flex-1 min-w-[120px] sm:min-w-[200px] sm:max-w-sm">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground pointer-events-none" />
            <Input
              value={query}
              onChange={(e) => handleSearch(e.target.value)}
              placeholder={t("search")}
              className="pl-9 pr-9"
            />
            {query && (
              <button
                onClick={() => handleSearch("")}
                className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
              >
                <X className="h-4 w-4" />
              </button>
            )}
          </div>

          {/* Sort */}
          <DropdownMenu>
            <DropdownMenuTrigger
              className={cn(
                buttonVariants({ variant: sortChanged ? "secondary" : "outline", size: "sm" }),
                "gap-1.5 shrink-0"
              )}
            >
              <ArrowUpDown className="h-4 w-4" />
              <span className="hidden sm:inline">{SORT_KEYS[initialSort] ? t(SORT_KEYS[initialSort]) : t("sort")}</span>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="start">
              <DropdownMenuGroup>
                <DropdownMenuLabel>{t("sortBy")}</DropdownMenuLabel>
                <DropdownMenuSeparator />
                {Object.entries(SORT_KEYS).map(([value, key]) => (
                  <DropdownMenuItem
                    key={value}
                    onClick={() => pushParams({ sort: value })}
                    className={cn(initialSort === value && "font-medium text-primary")}
                  >
                    {t(key)}
                  </DropdownMenuItem>
                ))}
              </DropdownMenuGroup>
            </DropdownMenuContent>
          </DropdownMenu>

          {/* Filters */}
          <DropdownMenu>
            <DropdownMenuTrigger
              className={cn(
                buttonVariants({ variant: activeFilterCount > 0 ? "secondary" : "outline", size: "sm" }),
                "gap-1.5 shrink-0"
              )}
            >
              <SlidersHorizontal className="h-4 w-4" />
              <span className="hidden sm:inline">{t("filter")}</span>
              {activeFilterCount > 0 && (
                <Badge variant="secondary" className="ml-1 h-4 min-w-4 px-1 text-xs">
                  {activeFilterCount}
                </Badge>
              )}
            </DropdownMenuTrigger>
            <DropdownMenuContent align="start" className="w-48">
              <DropdownMenuGroup>
                <DropdownMenuLabel>{t("visibilityLabel")}</DropdownMenuLabel>
                {Object.entries(VISIBILITY_KEYS).map(([value, key]) => (
                  <DropdownMenuItem
                    key={value}
                    closeOnClick={false}
                    onClick={() => pushParams({ visibility: value })}
                    className={cn(initialVisibility === value && "font-medium text-primary")}
                  >
                    {value === "" ? t(key) : tRecipe(`visibility.${key}`)}
                  </DropdownMenuItem>
                ))}
              </DropdownMenuGroup>
              <DropdownMenuSeparator />
              <DropdownMenuGroup>
                <DropdownMenuLabel>{t("difficultyLabel")}</DropdownMenuLabel>
                {Object.entries(DIFFICULTY_KEYS).map(([value, key]) => (
                  <DropdownMenuItem
                    key={value}
                    closeOnClick={false}
                    onClick={() => pushParams({ difficulty: value })}
                    className={cn(initialDifficulty === value && "font-medium text-primary")}
                  >
                    {value === "" ? t(key) : tRecipe(`difficulty.${key}`)}
                  </DropdownMenuItem>
                ))}
              </DropdownMenuGroup>
              <DropdownMenuSeparator />
              <DropdownMenuGroup>
                <DropdownMenuLabel>{t("tagLabel")}</DropdownMenuLabel>
                <div className="px-2 py-1">
                  <TagFilterInput
                    value={initialTag}
                    onChange={(v) => pushParams({ tag: v })}
                  />
                </div>
              </DropdownMenuGroup>
              <DropdownMenuSeparator />
              <DropdownMenuGroup>
                <DropdownMenuLabel>{t("batchCookLabel")}</DropdownMenuLabel>
                {Object.entries(BATCH_COOK_KEYS).map(([value, key]) => (
                  <DropdownMenuItem
                    key={value}
                    closeOnClick={false}
                    onClick={() => pushParams({ batchCook: value })}
                    className={cn(initialBatchCook === value && "font-medium text-primary")}
                  >
                    {t(key)}
                  </DropdownMenuItem>
                ))}
              </DropdownMenuGroup>
              <DropdownMenuSeparator />
              <DropdownMenuGroup>
                <DropdownMenuLabel>{t("recipeTypeLabel")}</DropdownMenuLabel>
                {Object.entries(RECIPE_TYPE_KEYS).map(([value, key]) => (
                  <DropdownMenuItem
                    key={value}
                    closeOnClick={false}
                    onClick={() => pushParams({ recipeType: value })}
                    className={cn(initialRecipeType === value && "font-medium text-primary")}
                  >
                    {value === "" ? t(key) : tRecipe(`recipeType.${key}`)}
                  </DropdownMenuItem>
                ))}
              </DropdownMenuGroup>
              {activeFilterCount > 0 && (
                <>
                  <DropdownMenuSeparator />
                  <DropdownMenuGroup>
                    <DropdownMenuItem
                      onClick={() => pushParams({ visibility: "", difficulty: "", tag: "", batchCook: "", recipeType: "" })}
                      className="text-muted-foreground"
                    >
                      <X className="h-3 w-3 mr-1.5" /> {t("clearFilters")}
                    </DropdownMenuItem>
                  </DropdownMenuGroup>
                </>
              )}
            </DropdownMenuContent>
          </DropdownMenu>
        </div>
      </div>

      <AiGenerateDialog
        open={aiOpen}
        onOpenChange={setAiOpen}
        photoTabAvailable={importPhotoAvailable}
        photoTabLocked={importPhotoLocked}
      />
      <UrlImportDialog open={urlOpen} onOpenChange={setUrlOpen} initialUrl={sharedUrl} autoImport={!!sharedUrl && !importUrlLocked} />
      <UpgradeDialog
        open={upgradeOpen}
        onOpenChange={setUpgradeOpen}
        featureKey="recipe_import_url"
        featureLabel="Import from URL"
      />
    </>
  );
}
