"use client";

import { useState, useEffect, useRef, useCallback } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Search, ChefHat } from "lucide-react";
import { SearchResultCard, type SearchResultRecipe } from "@/components/recipe/search-result-card";

type RecipeResult = SearchResultRecipe;

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

export function SearchPageContent({ initialQuery }: { initialQuery: string }) {
  const router = useRouter();
  const searchParams = useSearchParams();

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

  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: SearchResponse = await res.json();
        if (append) {
          setResults((prev) => [...prev, ...json.data]);
        } else {
          setResults(json.data);
        }
        setTotal(json.total);
        setOffset(off + json.data.length);
      } finally {
        setLoading(false);
        setLoadingMore(false);
      }
    },
    []
  );

  // Auto-focus input on mount
  useEffect(() => {
    inputRef.current?.focus();
  }, []);

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

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

  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 handleFilterChange = (newDiff: string, newMaxMins: string) => {
    fetchResults(query, newDiff, newMaxMins, 0);
  };

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

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

  const handleLoadMore = () => {
    fetchResults(query, difficulty, maxMins, offset, true);
  };

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

  return (
    <div className="max-w-5xl mx-auto space-y-6">
      <div>
        <h1 className="text-3xl font-bold mb-6">Search Recipes</h1>

        {/* Search input */}
        <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="Search for recipes..."
            className="pl-10 h-12 text-base"
          />
        </form>

        {/* Filter bar */}
        <div className="mt-3 flex flex-wrap items-center gap-3">
          <Select value={difficulty} onValueChange={handleDifficultyChange}>
            <SelectTrigger className="w-40">
              <SelectValue placeholder="Difficulty" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="any">Any difficulty</SelectItem>
              <SelectItem value="easy">Easy</SelectItem>
              <SelectItem value="medium">Medium</SelectItem>
              <SelectItem value="hard">Hard</SelectItem>
            </SelectContent>
          </Select>

          <div className="flex items-center gap-2">
            <Input
              type="number"
              min={1}
              placeholder="Max minutes"
              value={maxMins}
              onChange={(e) => handleMaxMinsChange(e.target.value)}
              className="w-36"
            />
          </div>

          {hasQuery && !loading && (
            <span className="text-sm text-muted-foreground ml-auto">
              {total} {total === 1 ? "recipe" : "recipes"} found
            </span>
          )}
        </div>
      </div>

      {/* States */}
      {!hasQuery && (
        <div className="flex flex-col items-center justify-center py-24 text-muted-foreground">
          <Search className="h-12 w-12 mb-4 opacity-30" />
          <p className="text-lg">Search for recipes...</p>
          <p className="text-sm mt-1">Try &ldquo;pasta&rdquo;, &ldquo;vegan dessert&rdquo;, or &ldquo;quick dinner&rdquo;</p>
        </div>
      )}

      {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>
      )}

      {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">No recipes found for &ldquo;{query}&rdquo;</p>
          <p className="text-sm mt-1">Try different keywords or remove filters</p>
        </div>
      )}

      {!loading && results.length > 0 && (
        <>
          <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={handleLoadMore}
                disabled={loadingMore}
                className="min-w-32"
              >
                {loadingMore ? "Loading..." : "Load more"}
              </Button>
            </div>
          )}
        </>
      )}
    </div>
  );
}
