"use client";

import { useState, useCallback } from "react";
import { useTranslations, useLocale } from "next-intl";
import { formatDateToYMD, parseDateYMD } from "@/lib/date-utils";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Checkbox } from "@/components/ui/checkbox";
import { Datepicker } from "@/components/datepicker/datepicker";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import {
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
} from "@/components/ui/collapsible";
import { Filter, Search, ChevronDown } from "lucide-react";
import { cn } from "@/lib/utils";

export interface FilterOption {
  id: string | number;
  label: string;
  count?: number;
}

export interface FilterGroup {
  id: string;
  label: string;
  searchable?: boolean;
  searchPlaceholder?: string;
  options: FilterOption[];
  collapsible?: boolean;
  defaultExpanded?: boolean;
}

export interface FilterDateField {
  id: string;
  label: string;
  placeholder?: string;
}

export interface FilterConfig {
  groups?: FilterGroup[];
  dateFields?: FilterDateField[];
}

export interface FilterValues {
  [key: string]: (string | number)[] | { [fieldId: string]: string } | undefined;
  dates?: {
    [fieldId: string]: string;
  };
}

interface FilterDropdownProps {
  config: FilterConfig;
  value?: FilterValues;
  onChange?: (values: FilterValues) => void;
  onApply?: (values: FilterValues) => void;
  triggerLabel?: string;
  applyLabel?: string;
  clearLabel?: string;
  className?: string;
}

export function FilterDropdown({
  config,
  value = {},
  onChange,
  onApply,
  triggerLabel,
  applyLabel,
  clearLabel,
  className,
}: FilterDropdownProps) {
  const t = useTranslations();
  const locale = useLocale() as "ar" | "en";
  const [isOpen, setIsOpen] = useState(false);
  const [localValues, setLocalValues] = useState<FilterValues>(value);
  const [searchQueries, setSearchQueries] = useState<Record<string, string>>({});
  const [dateValues, setDateValues] = useState<Record<string, Date | null>>({});

  // Helper to parse date string (YYYY-MM-DD) to local Date
  const parseDate = (dateStr: string | undefined): Date | null => {
    return parseDateYMD(dateStr);
  };

  // Helper to format Date to YYYY-MM-DD using local date parts
  const formatDateToString = (date: Date | null): string => {
    return formatDateToYMD(date);
  };

  // Check if any filters are active
  const hasActiveFilters = Object.keys(localValues).some((key) => {
    if (key === "dates") {
      return Object.values(localValues.dates || {}).some((v) => v);
    }
    const value = localValues[key];
    return Array.isArray(value) && value.length > 0;
  });

  // Handle checkbox toggle
  const handleToggleOption = useCallback(
    (groupId: string, optionId: string | number) => {
      setLocalValues((prev) => {
        const prevValue = prev[groupId];
        const currentGroupValues = Array.isArray(prevValue) ? prevValue : [];
        const isChecked = currentGroupValues.includes(optionId);

        const newValues = {
          ...prev,
          [groupId]: isChecked
            ? currentGroupValues.filter((id) => id !== optionId)
            : [...currentGroupValues, optionId],
        };

        onChange?.(newValues);
        return newValues;
      });
    },
    [onChange]
  );

  // Handle date change
  const handleDateChange = useCallback(
    (fieldId: string, date: Date | null) => {
      setDateValues((prev) => ({
        ...prev,
        [fieldId]: date,
      }));

      const value = formatDateToString(date);
      setLocalValues((prev) => {
        const newValues = {
          ...prev,
          dates: {
            ...(prev.dates || {}),
            [fieldId]: value,
          },
        };

        onChange?.(newValues);
        return newValues;
      });
    },
    [onChange]
  );

  // Handle clear filters
  const handleClear = useCallback(() => {
    const clearedValues: FilterValues = {};
    setLocalValues(clearedValues);
    onChange?.(clearedValues);
  }, [onChange]);

  // Handle apply filters
  const handleApply = useCallback(() => {
    onApply?.(localValues);
    setIsOpen(false);
  }, [localValues, onApply]);

  // Get filtered options based on search
  const getFilteredOptions = (group: FilterGroup) => {
    const query = searchQueries[group.id]?.toLowerCase() || "";
    if (!query) return group.options;

    return group.options.filter((option) =>
      option.label.toLowerCase().includes(query)
    );
  };

  // Count active selections in a group
  const getActiveCount = (groupId: string) => {
    const value = localValues[groupId];
    return Array.isArray(value) ? value.length : 0;
  };

  return (
    <Popover open={isOpen} onOpenChange={setIsOpen}>
      <PopoverTrigger asChild>
        <Button
          variant="outline"
          className={cn(
            "h-10 gap-2 border-border hover:bg-muted",
            hasActiveFilters && "border-primary",
            className
          )}
        >
          <Filter className="size-4" />
          <span>{triggerLabel || t("common.filter")}</span>
          {hasActiveFilters && (
            <span className="flex h-5 w-5 items-center justify-center rounded-full bg-primary text-[10px] font-semibold text-primary-foreground">
              {Object.entries(localValues).reduce((sum, [key, val]) => {
                if (key === "dates") return sum;
                if (Array.isArray(val)) return sum + val.length;
                return sum;
              }, 0)}
            </span>
          )}
          <ChevronDown className="size-3 opacity-50" />
        </Button>
      </PopoverTrigger>

      <PopoverContent
        className="w-80 p-0"
        align="start"
        side="bottom"
        sideOffset={8}
      >
        <div className="flex flex-col max-h-[500px]">
          {/* Filter Groups */}
          {config.groups && config.groups.length > 0 && (
            <div className="flex-1 overflow-y-auto">
              {config.groups.map((group) => {
                const filteredOptions = getFilteredOptions(group);
                const activeCount = getActiveCount(group.id);

                return (
                  <div key={group.id} className="border-b border-border last:border-0">
                    <div className="p-4">
                      {/* Group Label */}
                      <h4 className="text-sm font-semibold text-foreground mb-3">
                        {group.label}
                        {activeCount > 0 && (
                          <span className="text-xs text-muted-foreground ms-2">
                            ({activeCount})
                          </span>
                        )}
                      </h4>

                      {/* Search Input */}
                      {group.searchable && (
                        <div className="relative mb-3">
                          <Input
                            type="text"
                            placeholder={group.searchPlaceholder || t("common.search")}
                            value={searchQueries[group.id] || ""}
                            onChange={(e) =>
                              setSearchQueries((prev) => ({
                                ...prev,
                                [group.id]: e.target.value,
                              }))
                            }
                            className="h-9 pe-9 text-sm"
                          />
                          <Search className="absolute end-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground" />
                        </div>
                      )}

                      {/* Options List */}
                      {group.collapsible ? (
                        <Collapsible defaultOpen={group.defaultExpanded}>
                          <div className="space-y-2 mb-2">
                            {filteredOptions.slice(0, 3).map((option) => (
                              <label
                                key={option.id}
                                className="flex items-center justify-between gap-2 cursor-pointer hover:bg-muted/50 rounded-md p-2 -m-2"
                              >
                                <div className="flex items-center gap-2 flex-1">
                                  <Checkbox
                                    checked={
                                      Array.isArray(localValues[group.id])
                                        ? (localValues[group.id] as (string | number)[]).includes(option.id)
                                        : false
                                    }
                                    onCheckedChange={() =>
                                      handleToggleOption(group.id, option.id)
                                    }
                                  />
                                  <span className="text-sm text-foreground">
                                    {option.label}
                                  </span>
                                </div>
                                {option.count !== undefined && (
                                  <span className="text-xs text-muted-foreground">
                                    ({option.count})
                                  </span>
                                )}
                              </label>
                            ))}
                          </div>

                          {filteredOptions.length > 3 && (
                            <>
                              <CollapsibleContent>
                                <div className="space-y-2 mb-2">
                                  {filteredOptions.slice(3).map((option) => (
                                    <label
                                      key={option.id}
                                      className="flex items-center justify-between gap-2 cursor-pointer hover:bg-muted/50 rounded-md p-2 -m-2"
                                    >
                                      <div className="flex items-center gap-2 flex-1">
                                        <Checkbox
                                          checked={
                                            Array.isArray(localValues[group.id])
                                              ? (localValues[group.id] as (string | number)[]).includes(option.id)
                                              : false
                                          }
                                          onCheckedChange={() =>
                                            handleToggleOption(group.id, option.id)
                                          }
                                        />
                                        <span className="text-sm text-foreground">
                                          {option.label}
                                        </span>
                                      </div>
                                      {option.count !== undefined && (
                                        <span className="text-xs text-muted-foreground">
                                          ({option.count})
                                        </span>
                                      )}
                                    </label>
                                  ))}
                                </div>
                              </CollapsibleContent>

                              <CollapsibleTrigger asChild>
                                <Button
                                  variant="ghost"
                                  size="sm"
                                  className="h-8 w-full justify-center gap-1 text-xs text-primary hover:text-primary hover:bg-primary/10"
                                >
                                  <span>{t("common.showMore")}</span>
                                  <ChevronDown className="size-3" />
                                </Button>
                              </CollapsibleTrigger>
                            </>
                          )}
                        </Collapsible>
                      ) : (
                        <div className="space-y-2">
                          {filteredOptions.map((option) => (
                            <label
                              key={option.id}
                              className="flex items-center justify-between gap-2 cursor-pointer hover:bg-muted/50 rounded-md p-2 -m-2"
                            >
                              <div className="flex items-center gap-2 flex-1">
                                <Checkbox
                                  checked={
                                    Array.isArray(localValues[group.id])
                                      ? (localValues[group.id] as (string | number)[]).includes(option.id)
                                      : false
                                  }
                                  onCheckedChange={() =>
                                    handleToggleOption(group.id, option.id)
                                  }
                                />
                                <span className="text-sm text-foreground">
                                  {option.label}
                                </span>
                              </div>
                              {option.count !== undefined && (
                                <span className="text-xs text-muted-foreground">
                                  ({option.count})
                                </span>
                              )}
                            </label>
                          ))}
                        </div>
                      )}
                    </div>
                  </div>
                );
              })}
            </div>
          )}

          {/* Date Fields */}
          {config.dateFields && config.dateFields.length > 0 && (
            <div className="border-t border-border">
              {config.dateFields.map((field) => (
                <div key={field.id} className="p-4">
                  <label className="text-sm font-semibold text-foreground mb-2 block">
                    {field.label}
                  </label>
                  <Datepicker
                    value={dateValues[field.id] || parseDate(localValues.dates?.[field.id])}
                    onChange={(date) => handleDateChange(field.id, date)}
                    locale={locale}
                    mode="single"
                    showShortcuts={false}
                    className="w-full"
                  />
                </div>
              ))}
            </div>
          )}

          {/* Footer Actions */}
          <div className="border-t border-border p-4 flex items-center gap-3">
            <Button
              variant="ghost"
              size="sm"
              onClick={handleClear}
              disabled={!hasActiveFilters}
              className="flex-1 h-9"
            >
              {clearLabel || t("common.clearFilters")}
            </Button>
            <Button
              variant="default"
              size="sm"
              onClick={handleApply}
              className="flex-1 h-9"
            >
              {applyLabel || t("common.applyFilters")}
            </Button>
          </div>
        </div>
      </PopoverContent>
    </Popover>
  );
}
