"use client";

import { useState, useEffect, useRef, useCallback } from "react";
import Link from "next/link";
import { useRouter, useSearchParams } from "next/navigation";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Flame, Clock, ChefHat, Search, Sparkles, Wand2, ArrowRight, Shuffle, Users } 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";
import { FollowButton } from "@/components/social/follow-button";

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;
  avgRating: number | null;
  ratingCount: number;
};

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

type PersonResult = {
  id: string;
  name: string;
  username: string | null;
  avatarUrl: string | null;
  bio: string | null;
};

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

const SURPRISE_IDEA_PROMPTS = [
  "use only 5 ingredients",
  "no oven required",
  "one-pot meal",
  "ready in 20 minutes or less",
  "budget-friendly student meal",
  "impressive but secretly easy dinner party dish",
  "leftover-friendly comfort food",
  "kid-friendly weeknight dinner",
  "high-protein post-workout meal",
  "cozy soup for a rainy day",
];


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;
  popularTags: string[];
};

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

  const [inputValue, setInputValue] = useState(initialQuery);
  const [query, setQuery] = useState(initialQuery);
  const [difficulty, setDifficulty] = useState("any");
  const [recipeType, setRecipeType] = useState("any");
  const [maxMins, setMaxMins] = useState("");
  const [selectedTags, setSelectedTags] = useState<Set<string>>(new Set());
  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 [peopleResults, setPeopleResults] = useState<PersonResult[]>([]);
  const [peopleLoading, setPeopleLoading] = 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, tags: string[], type = "any", 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 (type && type !== "any") params.set("recipeType", type);
        if (maxM) params.set("maxMins", maxM);
        if (tags.length > 0) params.set("tags", tags.join(","));
        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);
      }
    },
    []
  );

  const fetchPeople = useCallback(async (q: string) => {
    if (q.trim().length < 2) {
      setPeopleResults([]);
      return;
    }
    setPeopleLoading(true);
    try {
      const res = await fetch(`/api/v1/users/search?q=${encodeURIComponent(q.trim())}`);
      if (!res.ok) return;
      const data = (await res.json()) as { users: PersonResult[] };
      setPeopleResults(data.users);
    } finally {
      setPeopleLoading(false);
    }
  }, []);

  useEffect(() => {
    if (initialQuery) {
      fetchResults(initialQuery, "any", "", 0, [], "any");
      fetchPeople(initialQuery);
    }
    // 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, [...selectedTags], recipeType);
      fetchPeople(value);
    }, 300);
  };

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

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

  const handleRecipeTypeChange = (value: string | null) => {
    const v = value ?? "any";
    setRecipeType(v);
    fetchResults(query, difficulty, maxMins, 0, [...selectedTags], v);
  };

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

  const toggleTag = (tag: string) => {
    setSelectedTags((prev) => {
      const next = new Set(prev);
      if (next.has(tag)) next.delete(tag);
      else next.add(tag);
      fetchResults(query, difficulty, maxMins, 0, [...next], recipeType);
      return next;
    });
  };

  const hasQuery = query.trim().length > 0;
  const hasMore = results.length < total;
  const hasNoResults = hasQuery && !loading && !peopleLoading && results.length === 0 && peopleResults.length === 0;

  return (
    <div className="max-w-5xl mx-auto space-y-6">
      <div className="flex items-center justify-between">
        <h1 className="text-3xl font-bold">{t("title")}</h1>
      </div>

      <div className="space-y-10">
      {/* Search bar — one query finds both recipes and people */}
      <div className="space-y-3">
        <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>

            <Select value={recipeType} onValueChange={handleRecipeTypeChange}>
              <SelectTrigger className="w-40">
                <SelectValue placeholder={t("anyType")} />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="any">{t("anyType")}</SelectItem>
                <SelectItem value="dish">{tRecipe("recipeType.dish")}</SelectItem>
                <SelectItem value="drink">{tRecipe("recipeType.drink")}</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>
        )}

        {hasQuery && popularTags.length > 0 && (
          <div className="flex flex-wrap items-center gap-1.5">
            {popularTags.map((tag) => (
              <button key={tag} onClick={() => toggleTag(tag)}>
                <Badge variant={selectedTags.has(tag) ? "default" : "outline"} className="cursor-pointer">
                  {tag}
                </Badge>
              </button>
            ))}
          </div>
        )}
      </div>

      {/* People results */}
      {hasQuery && (peopleLoading || peopleResults.length > 0) && (
        <section className="space-y-3">
          <div className="flex items-center gap-2">
            <Users className="h-4 w-4 text-muted-foreground" />
            <h2 className="text-sm font-semibold uppercase tracking-wide text-muted-foreground">{t("peopleHeading")}</h2>
          </div>
          {peopleLoading ? (
            <p className="text-sm text-muted-foreground">{tPeople("searching")}</p>
          ) : (
            <div className="space-y-2">
              {peopleResults.map((person) => (
                <div key={person.id} className="flex items-center gap-3 rounded-lg border p-3">
                  <Link href={`/u/${person.username}`} className="flex items-center gap-3 flex-1 min-w-0">
                    <Avatar className="h-10 w-10 shrink-0">
                      {person.avatarUrl && <AvatarImage src={person.avatarUrl} alt={person.name} />}
                      <AvatarFallback>{person.name.slice(0, 2).toUpperCase()}</AvatarFallback>
                    </Avatar>
                    <div className="min-w-0">
                      <p className="font-medium text-sm truncate">{person.name}</p>
                      <p className="text-xs text-muted-foreground truncate">@{person.username}</p>
                    </div>
                  </Link>
                  {person.username && (
                    <FollowButton targetUserId={person.id} targetUsername={person.username} />
                  )}
                </div>
              ))}
            </div>
          )}
        </section>
      )}

      {/* Recipe search results */}
      {hasQuery && loading && (
        <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg: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>
      )}

      {hasNoResults && (
        <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="flex items-center gap-2">
            <ChefHat className="h-4 w-4 text-muted-foreground" />
            <h2 className="text-sm font-semibold uppercase tracking-wide text-muted-foreground">{t("recipesHeading")}</h2>
          </div>
          <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg: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, [...selectedTags], recipeType, 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 flex-1 min-w-0"
              />
              <Button
                type="submit"
                disabled={ideasLoading}
                className="shrink-0 bg-violet-600 text-white hover:bg-violet-700 dark:bg-violet-500 dark:hover:bg-violet-400"
              >
                {ideasLoading ? (
                  <span className="flex items-center gap-2"><Wand2 className="h-4 w-4 animate-pulse" /> <span className="hidden sm:inline">{t("generating")}</span></span>
                ) : (
                  <span className="flex items-center gap-2"><Wand2 className="h-4 w-4" /> <span className="hidden sm:inline">{t("getIdeas")}</span></span>
                )}
              </Button>
              <Button
                type="button"
                variant="outline"
                disabled={ideasLoading}
                onClick={() => {
                  const idx = Math.floor(Math.random() * SURPRISE_IDEA_PROMPTS.length);
                  const surprisePrompt = SURPRISE_IDEA_PROMPTS[idx]!;
                  setIdeasPrompt(surprisePrompt);
                  fetchIdeas(surprisePrompt);
                }}
                className="shrink-0 bg-background/80 border-violet-300 text-violet-700 hover:bg-background hover:text-violet-800 dark:border-violet-700 dark:text-violet-300 dark:hover:text-violet-200"
              >
                <span className="flex items-center gap-2"><Shuffle className="h-4 w-4" /> <span className="hidden sm:inline">{t("surpriseMe")}</span></span>
              </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-64">
                    <SearchResultCard recipe={recipe} />
                  </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 md:grid-cols-3 lg:grid-cols-4 gap-4">
                {recent.map((recipe) => (
                  <SearchResultCard key={recipe.id} recipe={recipe} />
                ))}
              </div>
            )}
          </section>
        </>
      )}
      </div>
    </div>
  );
}
