"use client";

import { Datepicker } from "@/components/datepicker/datepicker";
import type { DateRange } from "@/components/datepicker/preset-shortcuts";
import { FilterIcon } from "@/components/icons/dashboard";
import { Button } from "@/components/ui/button";
import {
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
} from "@/components/ui/collapsible";
import { Input } from "@/components/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import type { Locale } from "@/lib/date-utils";
import { cn } from "@/lib/utils";
import { ChevronDown, Search, X } from "lucide-react";
import { useLocale, useTranslations } from "next-intl";
import { useCallback, useState } from "react";

// Filter field types
export interface SelectFilterField {
  type: "select";
  id: string;
  label: string;
  placeholder: string;
  options: { value: string; label: string }[];
}

export interface TextFilterField {
  type: "text";
  id: string;
  label: string;
  placeholder: string;
}

export interface DateFilterField {
  type: "date";
  id: string;
  label: string;
  placeholder?: string;
}

export interface DateRangeFilterField {
  type: "dateRange";
  id: string;
  label: string;
  placeholder?: string;
}

export type FilterField = SelectFilterField | TextFilterField | DateFilterField | DateRangeFilterField;

// Filter values type
export interface FilterValues {
  [key: string]: string | Date | DateRange | null;
}

// Applied filter for chips display
export interface AppliedFilter {
  id: string;
  label: string;
  value: string;
}

interface FilterBarProps {
  // Search configuration
  searchPlaceholder?: string;
  searchValue?: string;
  onSearchChange?: (value: string) => void;
  onSearch?: (value: string) => void;
  showSearch?: boolean;

  // Filter fields configuration
  filterFields?: FilterField[];

  // Filter state
  pendingFilters?: FilterValues;
  appliedFilters?: AppliedFilter[];
  onPendingFilterChange?: (id: string, value: string | Date | DateRange | null) => void;
  onApplyFilters?: () => void;
  onClearFilters?: () => void;
  onRemoveAppliedFilter?: (id: string) => void;

  // Labels customization
  searchButtonLabel?: string;
  filterButtonLabel?: string;
  applyButtonLabel?: string;
  cancelButtonLabel?: string;

  // Styling
  className?: string;
}

export function FilterBar({
  // Search props
  searchPlaceholder,
  searchValue: controlledSearchValue,
  onSearchChange,
  onSearch,
  showSearch = true,

  // Filter props
  filterFields = [],
  pendingFilters = {},
  appliedFilters = [],
  onPendingFilterChange,
  onApplyFilters,
  onClearFilters,
  onRemoveAppliedFilter,

  // Labels
  searchButtonLabel,
  filterButtonLabel,
  applyButtonLabel,
  cancelButtonLabel,

  // Styling
  className,
}: FilterBarProps) {
  const t = useTranslations();
  const locale = useLocale() as Locale;
  const [isFilterOpen, setIsFilterOpen] = useState(false);
  const [internalSearchValue, setInternalSearchValue] = useState("");

  // Use controlled or internal search value
  const searchValue = controlledSearchValue ?? internalSearchValue;

  const handleSearchInputChange = useCallback(
    (value: string) => {
      if (onSearchChange) {
        onSearchChange(value);
      } else {
        setInternalSearchValue(value);
      }
    },
    [onSearchChange]
  );

  const handleSearch = useCallback(() => {
    onSearch?.(searchValue);
  }, [onSearch, searchValue]);

  const handleKeyDown = useCallback(
    (e: React.KeyboardEvent) => {
      if (e.key === "Enter") {
        handleSearch();
      }
    },
    [handleSearch]
  );

  const handleApplyFilters = useCallback(() => {
    onApplyFilters?.();
    setIsFilterOpen(false);
  }, [onApplyFilters]);

  const handleClearFilters = useCallback(() => {
    onClearFilters?.();
    setIsFilterOpen(false);
  }, [onClearFilters]);

  const hasFilterFields = filterFields.length > 0;
  const appliedFiltersCount = appliedFilters.length;

  return (
    <Collapsible
      className={cn("", className)}
      open={isFilterOpen}
      onOpenChange={setIsFilterOpen}
    >
      <div>
        {/* Top Filter Bar */}
        <div className="flex flex-col sm:flex-row items-stretch sm:items-center gap-4 p-4">
          {/* Search Input */}
          {showSearch && (
            <>
              <div className="relative w-full sm:w-100 order-1 sm:order-0">
                <Input
                  type="text"
                  placeholder={searchPlaceholder || t("common.searchPlaceholder")}
                  value={searchValue}
                  onChange={(e) => handleSearchInputChange(e.target.value)}
                  onKeyDown={handleKeyDown}
                  className="h-10 pe-10"
                />
                <Search className="absolute end-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
              </div>

              {/* Search Button */}
              <Button
                onClick={handleSearch}
                className="h-10 w-full sm:w-24.5 order-2 sm:order-0"
              >
                {searchButtonLabel || t("common.search")}
              </Button>
            </>
          )}

          {/* Filter Toggle Button */}
          {hasFilterFields && (
            <CollapsibleTrigger asChild>
              <Button
                variant="outline"
                className={cn(
                  "h-10 w-full sm:w-30.75 gap-2 order-3 sm:order-0",
                  appliedFiltersCount > 0 && "border-primary",
                )}
              >
                <FilterIcon className="h-5 w-5" />
                <span>{filterButtonLabel || t("common.filter")}</span>

                <ChevronDown
                  className={cn(
                    "h-4 w-4 transition-transform",
                    isFilterOpen && "rotate-180"
                  )}
                />
              </Button>
            </CollapsibleTrigger>
          )}

          {/* Applied Filter Chips */}
          {appliedFilters.map((filter) => (
            <button
              key={filter.id}
              onClick={() => onRemoveAppliedFilter?.(filter.id)}
              title={filter.label}
              className="order-4 sm:order-0 inline-flex max-w-[18rem] items-center gap-1.5 rounded-full border border-border bg-muted px-3 py-1.5 text-sm font-medium text-foreground shadow-sm transition-colors hover:bg-muted/80"
            >
              <span className="min-w-0 truncate">{filter.label}</span>
              <X className="h-3.5 w-3.5 shrink-0" />
            </button>
          ))}
        </div>

        {/* Expanded Filter Section */}
        {hasFilterFields && (
          <CollapsibleContent>
            <div className="border-t border-border px-3 py-4">
              <div className="flex flex-col sm:flex-row items-stretch sm:items-end justify-between gap-6 w-full">
                {/* Render filter fields */}
                <div className="flex flex-wrap items-end gap-4 sm:gap-6 flex-1">
                  {filterFields.map((field) => (
                    <div
                      key={field.id}
                      className="flex flex-col gap-2 min-w-[200px]"
                    >
                      <label className="text-sm font-medium text-foreground">
                        {field.label}
                      </label>

                      {field.type === "select" && (
                        <Select
                          value={(pendingFilters[field.id] as string) || ""}
                          onValueChange={(value) =>
                            onPendingFilterChange?.(field.id, value)
                          }
                        >
                          <SelectTrigger className="h-10">
                            <SelectValue placeholder={field.placeholder} />
                          </SelectTrigger>
                          <SelectContent>
                            {field.options.map((option) => (
                              <SelectItem key={option.value} value={option.value}>
                                {option.label}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                      )}

                      {field.type === "text" && (
                        <Input
                          value={(pendingFilters[field.id] as string) || ""}
                          onChange={(event) =>
                            onPendingFilterChange?.(field.id, event.target.value)
                          }
                          placeholder={field.placeholder}
                          className="h-10"
                        />
                      )}

                      {field.type === "date" && (
                        <Datepicker
                          value={(pendingFilters[field.id] as Date) || null}
                          onChange={(date) =>
                            onPendingFilterChange?.(field.id, date)
                          }
                          mode="single"
                          showShortcuts={false}
                          locale={locale}
                        />
                      )}

                      {field.type === "dateRange" && (
                        <Datepicker
                          rangeValue={(pendingFilters[field.id] as DateRange) || null}
                          onRangeChange={(range) =>
                            onPendingFilterChange?.(field.id, range)
                          }
                          mode="range"
                          showShortcuts={false}
                          locale={locale}
                        />
                      )}
                    </div>
                  ))}
                </div>

                {/* Filter Actions */}
                <div className="flex items-center gap-3 pt-2 sm:pt-0 shrink-0">
                  <Button onClick={handleApplyFilters} className="h-10 min-w-[100px]">
                    {applyButtonLabel || t("common.filter")}
                  </Button>
                  <Button
                    variant="outline"
                    onClick={handleClearFilters}
                    className="h-10 min-w-[100px] border-destructive text-destructive hover:bg-destructive hover:text-white"
                  >
                    {cancelButtonLabel || t("common.cancel")}
                  </Button>
                </div>
              </div>
            </div>
          </CollapsibleContent>
        )}
      </div>
    </Collapsible>
  );
}

// Hook for managing filter state
export function useFilterBar<T extends FilterValues>(initialFilters: T = {} as T) {
  const [pendingFilters, setPendingFilters] = useState<T>(initialFilters);
  const [appliedFilters, setAppliedFilters] = useState<T>(initialFilters);
  const [searchValue, setSearchValue] = useState("");
  const [appliedSearch, setAppliedSearch] = useState("");

  const handlePendingFilterChange = useCallback(
    (id: string, value: string | Date | DateRange | null) => {
      setPendingFilters((prev) => ({
        ...prev,
        [id]: value,
      }));
    },
    []
  );

  const handleApplyFilters = useCallback(() => {
    setAppliedFilters(pendingFilters);
  }, [pendingFilters]);

  const handleClearFilters = useCallback(() => {
    setPendingFilters(initialFilters);
  }, [initialFilters]);

  const handleRemoveAppliedFilter = useCallback(
    (id: string) => {
      setAppliedFilters((prev) => ({
        ...prev,
        [id]: initialFilters[id],
      }));
      setPendingFilters((prev) => ({
        ...prev,
        [id]: initialFilters[id],
      }));
    },
    [initialFilters]
  );

  const handleSearch = useCallback((value: string) => {
    setAppliedSearch(value);
  }, []);

  return {
    // Search state
    searchValue,
    setSearchValue,
    appliedSearch,
    handleSearch,

    // Filter state
    pendingFilters,
    appliedFilters,
    handlePendingFilterChange,
    handleApplyFilters,
    handleClearFilters,
    handleRemoveAppliedFilter,
  };
}
