"use client";

import { useState, useEffect, useRef, useCallback } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import Link from "next/link";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Flame, Clock, ChefHat, Search, Sparkles, Wand2, ArrowRight } from "lucide-react";
import { useTranslations } from "next-intl";
import type { RecipeResult as ExploreRecipeResult } from "@/app/(app)/explore/page";
import { SearchResultCard } from "@/components/recipe/search-result-card";

const DIFFICULTY_COLORS: Record<string, string> = {
  easy: "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200",
  medium: "bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200",
  hard: "bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200",
};

type SearchRecipeResult = {
  id: string;
  title: string;
  description: string | null;
  difficulty: string | null;
  prepMins: number | null;
  cookMins: number | null;
  authorName: string | null;
};

type SearchResponse = {
  data: SearchRecipeResult[];
  total: number;
  limit: number;
  offset: number;
};

type RecipeIdea = {
  title: string;
  description: string;
  tags: string[];
  difficulty: "easy" | "medium" | "hard";
  totalMins?: number;
};


function HorizontalScroll({ children }: { children: React.ReactNode }) {
  return (
    <div className="flex gap-4 overflow-x-auto pb-2 -mx-4 px-4 snap-x snap-mandatory">
      {children}
    </div>
  );
}

type Props = {
  trending: ExploreRecipeResult[];
  recent: ExploreRecipeResult[];
  initialQuery: string;
};

export function ExplorePageContent({ trending, recent, initialQuery }: Props) {
  const router = useRouter();
  const searchParams = useSearchParams();
  const t = useTranslations("explore");
  const tCommon = useTranslations("common");
  const tRecipe = useTranslations("recipe");

  const [inputValue, setInputValue] = useState(initialQuery);
  const [query, setQuery] = useState(initialQuery);
  const [difficulty, setDifficulty] = useState("any");
  const [maxMins, setMaxMins] = useState("");
  const [results, setResults] = useState<SearchRecipeResult[]>([]);
  const [total, setTotal] = useState(0);
  const [offset, setOffset] = useState(0);
  const [loading, setLoading] = useState(false);
  const [loadingMore, setLoadingMore] = useState(false);

  const [ideasPrompt, setIdeasPrompt] = useState("");
  const [ideas, setIdeas] = useState<RecipeIdea[]>([]);
  const [ideasLoading, setIdeasLoading] = useState(false);
  const [generatingId, setGeneratingId] = useState<string | null>(null);

  const inputRef = useRef<HTMLInputElement>(null);
  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  const fetchResults = useCallback(
    async (q: string, diff: string, maxM: string, off: number, append = false) => {
      if (!q.trim()) {
        setResults([]);
        setTotal(0);
        setOffset(0);
        return;
      }
      if (off === 0) setLoading(true);
      else setLoadingMore(true);
      try {
        const params = new URLSearchParams({ q, limit: "20", offset: String(off) });
        if (diff && diff !== "any") params.set("difficulty", diff);
        if (maxM) params.set("maxMins", maxM);
        const res = await fetch(`/api/v1/search?${params}`);
        if (!res.ok) return;
        const json = await res.json() as SearchResponse;
        if (append) setResults((prev) => [...prev, ...json.data]);
        else setResults(json.data);
        setTotal(json.total);
        setOffset(off + json.data.length);
      } finally {
        setLoading(false);
        setLoadingMore(false);
      }
    },
    []
  );

  useEffect(() => {
    if (initialQuery) fetchResults(initialQuery, "any", "", 0);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const updateUrl = useCallback(
    (q: string) => {
      const params = new URLSearchParams(searchParams.toString());
      if (q) params.set("q", q);
      else params.delete("q");
      router.replace(`/explore?${params}`, { scroll: false });
    },
    [router, searchParams]
  );

  const fetchIdeas = useCallback(async (prompt: string) => {
    setIdeasLoading(true);
    setIdeas([]);
    try {
      const res = await fetch("/api/v1/ai/recipe-ideas", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ prompt }),
      });
      if (!res.ok) return;
      const data = await res.json() as RecipeIdea[];
      setIdeas(data);
    } finally {
      setIdeasLoading(false);
    }
  }, []);

  const generateFromIdea = useCallback(async (idea: RecipeIdea) => {
    const key = idea.title;
    setGeneratingId(key);
    try {
      const res = await fetch("/api/v1/ai/generate-from-idea", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ title: idea.title }),
      });
      if (!res.ok) return;
      const { id } = await res.json() as { id: string };
      router.push(`/recipes/${id}`);
    } finally {
      setGeneratingId(null);
    }
  }, [router]);

  const handleInputChange = (value: string) => {
    setInputValue(value);
    if (debounceRef.current) clearTimeout(debounceRef.current);
    debounceRef.current = setTimeout(() => {
      setQuery(value);
      updateUrl(value);
      fetchResults(value, difficulty, maxMins, 0);
    }, 300);
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (debounceRef.current) clearTimeout(debounceRef.current);
    setQuery(inputValue);
    updateUrl(inputValue);
    fetchResults(inputValue, difficulty, maxMins, 0);
  };

  const handleDifficultyChange = (value: string | null) => {
    const v = value ?? "any";
    setDifficulty(v);
    fetchResults(query, v, maxMins, 0);
  };

  const handleMaxMinsChange = (value: string) => {
    setMaxMins(value);
    if (debounceRef.current) clearTimeout(debounceRef.current);
    debounceRef.current = setTimeout(() => {
      fetchResults(query, difficulty, value, 0);
    }, 300);
  };

  const hasQuery = query.trim().length > 0;
  const hasMore = results.length < total;

  return (
    <div className="max-w-5xl mx-auto space-y-10">
      {/* Search bar */}
      <div className="space-y-3">
        <div className="flex items-center justify-between">
          <h1 className="text-3xl font-bold">{t("title")}</h1>
          <Link href="/people" className="text-sm text-muted-foreground hover:text-foreground underline underline-offset-4">
            Find people
          </Link>
        </div>
        <form onSubmit={handleSubmit} className="relative">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-muted-foreground pointer-events-none" />
          <Input
            ref={inputRef}
            value={inputValue}
            onChange={(e) => handleInputChange(e.target.value)}
            placeholder={t("searchPlaceholder")}
            className="pl-10 h-12 text-base"
            autoFocus={!!initialQuery}
          />
        </form>

        {hasQuery && (
          <div className="flex flex-wrap items-center gap-3">
            <Select value={difficulty} onValueChange={handleDifficultyChange}>
              <SelectTrigger className="w-40">
                <SelectValue placeholder={tCommon("difficulty")} />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="any">{t("anyDifficulty")}</SelectItem>
                <SelectItem value="easy">{tRecipe("difficulty.easy")}</SelectItem>
                <SelectItem value="medium">{tRecipe("difficulty.medium")}</SelectItem>
                <SelectItem value="hard">{tRecipe("difficulty.hard")}</SelectItem>
              </SelectContent>
            </Select>
            <Input
              type="number"
              min={1}
              placeholder={t("maxMinutes")}
              value={maxMins}
              onChange={(e) => handleMaxMinsChange(e.target.value)}
              className="w-36"
            />
            {!loading && (
              <span className="text-sm text-muted-foreground ml-auto">
                {t(total === 1 ? "resultsFoundSingular" : "resultsFoundPlural", { count: total })}
              </span>
            )}
          </div>
        )}
      </div>

      {/* Search results */}
      {hasQuery && loading && (
        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
          {Array.from({ length: 8 }).map((_, i) => (
            <div key={i} className="rounded-lg border bg-card p-4 space-y-3">
              <div className="h-5 bg-muted rounded animate-pulse" />
              <div className="h-3 bg-muted rounded animate-pulse w-3/4" />
              <div className="h-3 bg-muted rounded animate-pulse w-1/2" />
            </div>
          ))}
        </div>
      )}

      {hasQuery && !loading && results.length === 0 && (
        <div className="flex flex-col items-center justify-center py-24 text-muted-foreground">
          <ChefHat className="h-12 w-12 mb-4 opacity-30" />
          <p className="text-lg font-medium">{t("noResultsTitle", { query })}</p>
          <p className="text-sm mt-1">{t("noResultsHint")}</p>
        </div>
      )}

      {hasQuery && !loading && results.length > 0 && (
        <>
          <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
            {results.map((recipe) => (
              <SearchResultCard key={recipe.id} recipe={recipe} />
            ))}
          </div>
          {hasMore && (
            <div className="flex justify-center pt-4">
              <Button
                variant="outline"
                onClick={() => fetchResults(query, difficulty, maxMins, offset, true)}
                disabled={loadingMore}
                className="min-w-32"
              >
                {loadingMore ? tCommon("loading") : t("loadMore")}
              </Button>
            </div>
          )}
        </>
      )}

      {/* Explore sections — shown when no query */}
      {!hasQuery && (
        <>
          {/* AI Recipe Ideas */}
          <section className="rounded-xl border bg-gradient-to-br from-violet-50 to-indigo-50 dark:from-violet-950/30 dark:to-indigo-950/30 p-6 space-y-4">
            <div className="flex items-center gap-2">
              <Sparkles className="h-5 w-5 text-violet-500" />
              <h2 className="text-xl font-semibold">{t("recipeIdeas")}</h2>
            </div>
            <p className="text-sm text-muted-foreground">{t("recipeIdeasHint")}</p>
            <form
              onSubmit={(e) => {
                e.preventDefault();
                fetchIdeas(ideasPrompt);
              }}
              className="flex gap-2"
            >
              <Input
                value={ideasPrompt}
                onChange={(e) => setIdeasPrompt(e.target.value)}
                placeholder={t("aiSearchPlaceholder")}
                className="bg-background"
              />
              <Button type="submit" disabled={ideasLoading} variant="secondary" className="shrink-0">
                {ideasLoading ? (
                  <span className="flex items-center gap-2"><Wand2 className="h-4 w-4 animate-pulse" /> {t("generating")}</span>
                ) : (
                  <span className="flex items-center gap-2"><Wand2 className="h-4 w-4" /> {t("getIdeas")}</span>
                )}
              </Button>
              <Button
                type="button"
                variant="ghost"
                disabled={ideasLoading}
                onClick={() => { setIdeasPrompt(""); fetchIdeas(""); }}
                className="shrink-0"
              >
                {t("surpriseMe")}
              </Button>
            </form>

            {ideasLoading && (
              <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 pt-2">
                {Array.from({ length: 6 }).map((_, i) => (
                  <div key={i} className="rounded-lg border bg-background p-4 space-y-2">
                    <div className="h-4 bg-muted rounded animate-pulse" />
                    <div className="h-3 bg-muted rounded animate-pulse w-5/6" />
                    <div className="h-3 bg-muted rounded animate-pulse w-2/3" />
                  </div>
                ))}
              </div>
            )}

            {!ideasLoading && ideas.length > 0 && (
              <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 pt-2">
                {ideas.map((idea) => (
                  <div key={idea.title} className="rounded-lg border bg-background p-4 space-y-2 flex flex-col">
                    <div className="flex items-start justify-between gap-2">
                      <h3 className="font-medium text-sm leading-snug flex-1">{idea.title}</h3>
                      <Badge
                        variant="secondary"
                        className={`shrink-0 capitalize text-xs ${DIFFICULTY_COLORS[idea.difficulty] ?? ""}`}
                      >
                        {tRecipe(`difficulty.${idea.difficulty}`)}
                      </Badge>
                    </div>
                    <p className="text-xs text-muted-foreground line-clamp-2 flex-1">{idea.description}</p>
                    <div className="flex flex-wrap gap-1">
                      {idea.tags.map((tag) => (
                        <Badge key={tag} variant="outline" className="text-xs">{tag}</Badge>
                      ))}
                      {idea.totalMins && (
                        <Badge variant="outline" className="text-xs flex items-center gap-1">
                          <Clock className="h-3 w-3" />{tRecipe("total", { mins: idea.totalMins })}
                        </Badge>
                      )}
                    </div>
                    <Button
                      size="sm"
                      className="w-full mt-auto"
                      disabled={generatingId !== null}
                      onClick={() => generateFromIdea(idea)}
                    >
                      {generatingId === idea.title ? (
                        <span className="flex items-center gap-2"><Wand2 className="h-3.5 w-3.5 animate-pulse" /> {t("generating")}</span>
                      ) : (
                        <span className="flex items-center gap-2"><ArrowRight className="h-3.5 w-3.5" /> {t("generateFullRecipe")}</span>
                      )}
                    </Button>
                  </div>
                ))}
              </div>
            )}
          </section>

          <section>
            <div className="flex items-center gap-2 mb-4">
              <Flame className="h-5 w-5 text-orange-500" />
              <h2 className="text-xl font-semibold">{t("trendingThisWeek")}</h2>
            </div>
            {trending.length === 0 ? (
              <p className="text-muted-foreground text-sm py-8 text-center">
                {t("noTrending")}
              </p>
            ) : (
              <HorizontalScroll>
                {trending.map((recipe) => (
                  <div key={recipe.id} className="snap-start shrink-0 w-56">
                    <SearchResultCard recipe={recipe} className="min-w-[200px]" />
                  </div>
                ))}
              </HorizontalScroll>
            )}
          </section>

          <section>
            <div className="flex items-center gap-2 mb-4">
              <Clock className="h-5 w-5 text-blue-500" />
              <h2 className="text-xl font-semibold">{t("recentlyAdded")}</h2>
            </div>
            {recent.length === 0 ? (
              <p className="text-muted-foreground text-sm py-8 text-center">
                {t("noRecent")}
              </p>
            ) : (
              <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
                {recent.map((recipe) => (
                  <SearchResultCard key={recipe.id} recipe={recipe} />
                ))}
              </div>
            )}
          </section>
        </>
      )}
    </div>
  );
}
