import * as React from "react";
import { Search, X } from "lucide-react";
import { useTranslation } from "react-i18next";

import EthiopianDatePickerModal, {
  convertEthiopianToGregorian,
} from "@/shared/common/form/fields/AmharicDatePicker";
import { Badge } from "@/shared/common/ui/badge";
import { Button } from "@/shared/common/ui/button";
import { Input } from "@/shared/common/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/shared/common/ui/select";
import { FilterParams, FilterValue } from "@/shared/utils/filterParams";
import i18n from "@/i18n";

export type CombinedFilterField =
  | {
      key: string;
      label: string;
      type: "text";
    }
  | {
      key: string;
      label: string;
      type: "dateRange";
      fromKey: string;
      toKey: string;
    };

type CombinedFilterBarProps = {
  fields: CombinedFilterField[];
  filters: Partial<FilterParams>;
  setFilter: (key: string, value: FilterValue) => void;
  setFilters: (filters: Partial<FilterParams>) => void;
  removeFilter: (key: string) => void;
  removeFilters: (keys: string[]) => void;
  onFilterChange?: () => void;
  className?: string;
  onLiveSearch?: (key: string, value: string) => void;
};

type ActiveFilterChip = {
  key: string;
  label: string;
  value: string;
  remove: () => void;
};

export function CombinedFilterBar({
  fields,
  filters,
  setFilter,
  setFilters,
  removeFilter,
  removeFilters,
  onFilterChange,
  className,
  onLiveSearch,
}: CombinedFilterBarProps) {
  const { t } = useTranslation();
  const [selectedFilterKey, setSelectedFilterKey] = React.useState(
    fields[0]?.key ?? "",
  );
  const [inputValue, setInputValue] = React.useState("");
  const [fromDate, setFromDate] = React.useState("");
  const [toDate, setToDate] = React.useState("");
  const [fromDateDisplay, setFromDateDisplay] = React.useState("");
  const [toDateDisplay, setToDateDisplay] = React.useState("");
  const [showFromPicker, setShowFromPicker] = React.useState(false);
  const [showToPicker, setShowToPicker] = React.useState(false);
  const lang = i18n.language;

  const isFilterActive = React.useCallback(
    (field: CombinedFilterField) => {
      if (field.type === "dateRange") {
        return Boolean(filters[field.fromKey] || filters[field.toKey]);
      }

      return Boolean(filters[field.key]);
    },
    [filters],
  );

  const availableFields = React.useMemo(
    () => fields.filter((field) => !isFilterActive(field)),
    [fields, isFilterActive],
  );

  const selectedFilter = React.useMemo(
    () => availableFields.find((field) => field.key === selectedFilterKey),
    [availableFields, selectedFilterKey],
  );

  React.useEffect(() => {
    if (selectedFilter || availableFields.length === 0) return;

    setSelectedFilterKey(availableFields[0].key);
    clearDraftValues();
  }, [availableFields, selectedFilter]);

  React.useEffect(() => {
    if (!selectedFilter || selectedFilter.type === "dateRange") return;

    const value = inputValue.trim();

    if (value.length < 2) {
      onLiveSearch?.(selectedFilter.key, ""); // clear when too short
      return;
    }

    const handler = setTimeout(() => {
      onLiveSearch?.(selectedFilter.key, value);
    }, 500);

    return () => clearTimeout(handler);
  }, [inputValue, selectedFilter]);
  const clearDraftValues = () => {
    setInputValue("");
    setFromDate("");
    setToDate("");
    setFromDateDisplay("");
    setToDateDisplay("");
    onLiveSearch?.("", "");
  };

  const addFilter = React.useCallback(() => {
    if (!selectedFilter) return;

    if (selectedFilter.type === "dateRange") {
      if (!fromDate && !toDate) return;

      setFilters({
        [selectedFilter.fromKey]: fromDate,
        [selectedFilter.toKey]: toDate,
      });
      clearDraftValues();
      onFilterChange?.();
      return;
    }

    const value = inputValue.trim();
    if (!value) return;

    setFilter(selectedFilter.key, value);
    clearDraftValues();
    onFilterChange?.();
  }, [
    fromDate,
    inputValue,
    onFilterChange,
    selectedFilter,
    setFilter,
    setFilters,
    toDate,
  ]);

  const chips = React.useMemo<ActiveFilterChip[]>(
    () =>
      fields.reduce<ActiveFilterChip[]>((items, field) => {
        if (field.type === "dateRange") {
          const from = filters[field.fromKey];
          const to = filters[field.toKey];
          if (!from && !to) return items;

          items.push({
            key: field.key,
            label: field.label,
            value: [
              from ? `${t("common.from", "From")}: ${from}` : "",
              to ? `${t("common.to", "To")}: ${to}` : "",
            ]
              .filter(Boolean)
              .join(" - "),
            remove: () => removeFilters([field.fromKey, field.toKey]),
          });
          return items;
        }

        const value = filters[field.key];
        if (!value) return items;

        items.push({
          key: field.key,
          label: field.label,
          value: String(value),
          remove: () => removeFilter(field.key),
        });
        return items;
      }, []),
    [fields, filters, removeFilter, removeFilters, t],
  );

  const handleRemove = (remove: () => void) => {
    remove();
    onFilterChange?.();
  };

  return (
    <div className={className ?? "flex w-full min-w-0 flex-col gap-2"}>
      <div className="flex w-full min-w-0 flex-col flex-wrap items-stretch gap-2 sm:flex-row sm:items-center">
        <Select
          value={selectedFilter?.key ?? ""}
          onValueChange={(value) => {
            setSelectedFilterKey(value);
            clearDraftValues();
          }}
          disabled={availableFields.length === 0}>
          <SelectTrigger className="w-full sm:w-[200px]">
            <SelectValue placeholder={t("userRecord.Filter by")} />
          </SelectTrigger>
          <SelectContent>
            {availableFields.map((field) => (
              <SelectItem key={field.key} value={field.key}>
                {field.label}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>

        {selectedFilter?.type === "dateRange" ? (
          <div className="flex flex-col sm:flex-row gap-2">
            {lang.startsWith("en") ? (
              <>
                <label className="mt-2">From: </label>
                <Input
                  type="date"
                  value={fromDate}
                  onChange={(event) => setFromDate(event.target.value)}
                  onKeyDown={(event) => {
                    if (event.key === "Enter") addFilter();
                  }}
                  className="w-[150px]"
                />
                <label className="mt-2">To: </label>
                <Input
                  type="date"
                  value={toDate}
                  onChange={(event) => setToDate(event.target.value)}
                  onKeyDown={(event) => {
                    if (event.key === "Enter") addFilter();
                  }}
                  min={fromDate}
                  className="w-[150px]"
                />
              </>
            ) : (
              <div className="flex flex-wrap items-center gap-3">
                <div className="relative">
                  <label className="font-medium mr-2">ከ:</label>
                  <input
                    type="text"
                    value={fromDateDisplay}
                    readOnly
                    onClick={() => setShowFromPicker((prev) => !prev)}
                    className="border border-gray-300 dark:border-gray-700 rounded-md px-2 py-1.5 w-40 bg-white dark:bg-gray-800 cursor-pointer"
                    placeholder="ቀን ይምረጡ"
                  />
                  {showFromPicker && (
                    <div className="absolute z-50 mt-1 bg-white dark:bg-gray-800 shadow-lg rounded-md p-2">
                      <EthiopianDatePickerModal
                        value={fromDate}
                        onChange={(ethiopianDate: string) => {
                          const gregorianDate =
                            convertEthiopianToGregorian(ethiopianDate);
                          const formatted = gregorianDate
                            .toISOString()
                            .split("T")[0];
                          setFromDate(formatted);
                          setFromDateDisplay(ethiopianDate);
                          setShowFromPicker(false);
                        }}
                      />
                    </div>
                  )}
                </div>

                <div className="relative">
                  <label className="font-medium mr-2">እስከ:</label>
                  <input
                    type="text"
                    value={toDateDisplay}
                    readOnly
                    onClick={() => setShowToPicker((prev) => !prev)}
                    className="border border-gray-300 dark:border-gray-700 rounded-md px-2 py-1.5 w-40 bg-white dark:bg-gray-800 cursor-pointer"
                    placeholder="ቀን ይምረጡ"
                  />
                  {showToPicker && (
                    <div className="absolute z-50 mt-1 bg-white dark:bg-gray-800 shadow-lg rounded-md p-2">
                      <EthiopianDatePickerModal
                        value={toDate}
                        onChange={(ethiopianDate: string) => {
                          const gregorianDate =
                            convertEthiopianToGregorian(ethiopianDate);
                          const formatted = gregorianDate
                            .toISOString()
                            .split("T")[0];
                          setToDate(formatted);
                          setToDateDisplay(ethiopianDate);
                          setShowToPicker(false);
                        }}
                      />
                    </div>
                  )}
                </div>
              </div>
            )}
          </div>
        ) : (
          <div className="relative w-full sm:w-[200px]">
            <Input
              type="text"
              className="pl-8"
              placeholder={`${t("userRecord.Search")} ${
                selectedFilter?.label.toLowerCase() ?? ""
              }`}
              value={inputValue}
              onChange={(event) => setInputValue(event.target.value)}
              onKeyDown={(event) => {
                if (event.key === "Enter") addFilter();
              }}
              disabled={!selectedFilter}
            />
            <Search className="absolute left-2 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-500" />
          </div>
        )}

        <Button
          type="button"
          variant="outline"
          className="w-full shrink-0 sm:w-auto"
          onClick={addFilter}
          disabled={
            !selectedFilter ||
            (selectedFilter.type === "dateRange"
              ? !fromDate && !toDate
              : !inputValue.trim())
          }>
          {t("common.add", "Add Filter")}
        </Button>
      </div>

      {chips.length > 0 && (
        <div className="flex flex-wrap items-center gap-2">
          {chips.map((filter) => (
            <Badge
              key={filter.key}
              variant="outline"
              className="flex items-center gap-1 rounded-md px-2 py-1 text-sm">
              <span className="font-medium">{filter.label}:</span>
              <span>{filter.value}</span>
              <button
                type="button"
                onClick={() => handleRemove(filter.remove)}
                className="ml-1 rounded-sm p-0.5 hover:bg-gray-100 dark:hover:bg-gray-800"
                aria-label={`${t("common.remove", "Remove")} ${filter.label}`}>
                <X className="h-3.5 w-3.5" />
              </button>
            </Badge>
          ))}
        </div>
      )}
    </div>
  );
}
