"use client";

import {
  Box,
  TextField,
  MenuItem,
  Button,
  Drawer,
  FormControl,
  Select,
  Typography,
  Stack,
  debounce,
} from "@mui/material";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import SearchIcon from "@mui/icons-material/Search";
import RefreshIcon from "@mui/icons-material/Refresh";
import { useDispatch, useSelector } from "react-redux";
import { useState, useEffect, useMemo } from "react";
import { ISearchLabel } from "../DataTable/types";
import { AppDispatch } from "@/app/redux/store";
import {
  updateFilter,
  clearFilters,
  FilterValue,
} from "@/app/redux/advanedSearch/advancedSearchSlice";
import { selectFilters } from "@/app/redux/advanedSearch/selectors";
import { normalizeValue, defaultOperatorForField } from "./utils/utils";
import { selectConditionOperators } from "@/app/redux/metadata/selectors";

// -----------------------------------------------------
// COMPONENT
// -----------------------------------------------------

export default function AdvancedSearch({ labels }: { labels: ISearchLabel[] }) {
  const dispatch = useDispatch<AppDispatch>();
  const filters = useSelector(selectFilters);

  const [open, setOpen] = useState(false);

  // Local form state for UI (synced with Redux)
  const [formValues, setFormValues] = useState<Record<string, string>>({});
  const [operators, setOperators] = useState<Record<string, string>>({});
  const conditionOperators = useSelector(selectConditionOperators);

  console.log("[conditionOperators]", conditionOperators);
  // -----------------------------------------------------
  // SYNC REDUX FILTERS TO LOCAL STATE ON LOAD
  // -----------------------------------------------------
  useEffect(() => {
    const values: Record<string, string> = {};
    const ops: Record<string, string> = {};

    labels.forEach(({ field, type }) => {
      const filter = filters[field];

      if (filter) {
        if (typeof filter === "string") {
          // Simple string filter
          values[field] = filter;
          ops[field] = defaultOperatorForField(field, type);
        } else {
          // FilterValue object with operator and value
          values[field] = filter.value;
          ops[field] = filter.operator;
        }
      }

      // Handle date ranges
      const startKey = `${field}_start`;
      const endKey = `${field}_end`;
      const startFilter = filters[startKey];
      const endFilter = filters[endKey];

      if (startFilter && typeof startFilter === "string") {
        values[startKey] = startFilter;
      }
      if (endFilter && typeof endFilter === "string") {
        values[endKey] = endFilter;
      }
    });

    setFormValues(values);
    setOperators(ops);
  }, [filters, labels]);

  // -----------------------------------------------------
  // DEBOUNCED FILTER UPDATE
  // -----------------------------------------------------
  const debouncedUpdateFilter = useMemo(
    () =>
      debounce(
        (field: string, value: string | undefined, operator?: string) => {
          if (!value || value === "") {
            dispatch(updateFilter({ field, value: undefined }));
            return;
          }

          const safeValue = normalizeValue(value);
          if (!safeValue) {
            dispatch(updateFilter({ field, value: undefined }));
            return;
          }

          // For text/select fields, use FilterValue with operator
          const filterValue: FilterValue = {
            operator: operator ?? defaultOperatorForField(field, "text"),
            value: safeValue,
          };

          dispatch(updateFilter({ field, value: filterValue }));
        },
        300
      ),
    [dispatch]
  );

  // -----------------------------------------------------
  // handlers
  // -----------------------------------------------------

  const updateField = (field: string, value: string) => {
    setFormValues(prev => ({ ...prev, [field]: value }));
    const operator = operators[field] ?? defaultOperatorForField(field, "text");
    debouncedUpdateFilter(field, value, operator);
  };

  const updateOperator = (field: string, op: string) => {
    setOperators(prev => ({ ...prev, [field]: op }));

    // If value exists, update filter immediately with new operator
    const currentValue = formValues[field];
    if (currentValue) {
      const safeValue = normalizeValue(currentValue);
      if (safeValue) {
        dispatch(
          updateFilter({
            field,
            value: { operator: op, value: safeValue },
          })
        );
      }
    }
  };

  const updateDateRange = (
    field: string,
    start: string | undefined,
    end: string | undefined
  ) => {
    if (start) {
      dispatch(updateFilter({ field: `${field}_start`, value: start }));
    } else {
      dispatch(updateFilter({ field: `${field}_start`, value: undefined }));
    }

    if (end) {
      dispatch(updateFilter({ field: `${field}_end`, value: end }));
    } else {
      dispatch(updateFilter({ field: `${field}_end`, value: undefined }));
    }
  };

  const resetForm = () => {
    setFormValues({});
    setOperators({});
    dispatch(clearFilters());
  };

  // -----------------------------------------------------
  // render
  // -----------------------------------------------------
  return (
    <Box sx={{ width: "185px" }}>
      <Button
        sx={{
          borderRadius: "8px",
          textTransform: "none",
          backgroundColor: "#f5f5f5",
          color: "#555",
          padding: "6px 12px",
          boxShadow: "inset 0 0 0 1px #ddd",
          fontWeight: 400,
          fontSize: "16px",
          "&:hover": { backgroundColor: "#e0e0e0" },
        }}
        startIcon={<SearchIcon />}
        onClick={() => setOpen(true)}
      >
        Advanced Search
      </Button>

      <Drawer anchor="right" open={open} onClose={() => setOpen(false)}>
        <Box sx={{ width: 400 }} p={2}>
          <LocalizationProvider dateAdapter={AdapterDateFns}>
            <Box
              sx={{ display: "flex", justifyContent: "space-between", mb: 2 }}
            >
              <Typography variant="h6">Search</Typography>

              <Box display="flex" gap={2}>
                <Button
                  variant="contained"
                  startIcon={<SearchIcon />}
                  onClick={() => {
                    // Apply all current form values to Redux
                    labels.forEach(({ field, type }) => {
                      const val = formValues[field];
                      if (!val) return;

                      if (type === "select" || type === "text") {
                        const operator =
                          operators[field] ??
                          defaultOperatorForField(field, type);
                        const safeValue = normalizeValue(val);
                        if (safeValue) {
                          dispatch(
                            updateFilter({
                              field,
                              value: { operator, value: safeValue },
                            })
                          );
                        }
                      }
                    });
                  }}
                >
                  Apply
                </Button>

                <Button
                  variant="outlined"
                  startIcon={<RefreshIcon />}
                  onClick={resetForm}
                />
              </Box>
            </Box>

            <Stack spacing={2}>
              {labels.map(({ label, field, type, options }) => (
                <Box key={field}>
                  <Typography variant="body2" fontWeight={600} mb={0.5}>
                    {label}
                  </Typography>

                  {/* TEXT FIELDS */}
                  {type === "text" && (
                    <>
                      {/* AMOUNT WITH OPERATOR */}
                      {field === "Amount" ? (
                        <Box sx={{ display: "flex", gap: 1 }}>
                          <FormControl size="small" sx={{ minWidth: 130 }}>
                            <Select
                              value={operators[field] ?? ">="}
                              onChange={e =>
                                updateOperator(field, e.target.value)
                              }
                            >
                              {Object.entries(conditionOperators ?? {}).map(
                                ([key, value]) => (
                                  <MenuItem key={key} value={value}>
                                    {key.replace(/_/g, " ")}{" "}
                                    {/* Optional: make it readable */}
                                  </MenuItem>
                                )
                              )}
                            </Select>
                          </FormControl>

                          <TextField
                            fullWidth
                            size="small"
                            value={formValues[field] ?? ""}
                            onChange={e => updateField(field, e.target.value)}
                            placeholder="Enter amount"
                          />
                        </Box>
                      ) : (
                        <TextField
                          fullWidth
                          size="small"
                          value={formValues[field] ?? ""}
                          onChange={e => updateField(field, e.target.value)}
                        />
                      )}
                    </>
                  )}

                  {/* SELECTS */}
                  {type === "select" && (
                    <FormControl fullWidth size="small">
                      <Select
                        value={formValues[field] ?? ""}
                        onChange={e => updateField(field, e.target.value)}
                        displayEmpty
                      >
                        <MenuItem value="">
                          <em>{label}</em>
                        </MenuItem>
                        {options?.map(opt => (
                          <MenuItem key={opt} value={opt}>
                            {opt}
                          </MenuItem>
                        ))}
                      </Select>
                    </FormControl>
                  )}

                  {/* DATE RANGE */}
                  {type === "date" && (
                    <Stack spacing={2}>
                      <DatePicker
                        label="Start Date"
                        value={
                          formValues[`${field}_start`]
                            ? new Date(formValues[`${field}_start`])
                            : null
                        }
                        onChange={value => {
                          if (!value) {
                            updateDateRange(
                              field,
                              undefined,
                              formValues[`${field}_end`]
                            );
                            setFormValues(prev => ({
                              ...prev,
                              [`${field}_start`]: "",
                            }));
                            return;
                          }
                          const v = new Date(value);
                          v.setHours(0, 0, 0, 0);
                          const isoString = v.toISOString();
                          setFormValues(prev => ({
                            ...prev,
                            [`${field}_start`]: isoString,
                          }));
                          updateDateRange(
                            field,
                            isoString,
                            formValues[`${field}_end`]
                          );
                        }}
                        slotProps={{
                          textField: { fullWidth: true, size: "small" },
                        }}
                      />

                      <DatePicker
                        label="End Date"
                        value={
                          formValues[`${field}_end`]
                            ? new Date(formValues[`${field}_end`])
                            : null
                        }
                        onChange={value => {
                          if (!value) {
                            updateDateRange(
                              field,
                              formValues[`${field}_start`],
                              undefined
                            );
                            setFormValues(prev => ({
                              ...prev,
                              [`${field}_end`]: "",
                            }));
                            return;
                          }
                          const v = new Date(value);
                          v.setHours(23, 59, 59, 999);
                          const isoString = v.toISOString();
                          setFormValues(prev => ({
                            ...prev,
                            [`${field}_end`]: isoString,
                          }));
                          updateDateRange(
                            field,
                            formValues[`${field}_start`],
                            isoString
                          );
                        }}
                        slotProps={{
                          textField: { fullWidth: true, size: "small" },
                        }}
                      />
                    </Stack>
                  )}
                </Box>
              ))}
            </Stack>
          </LocalizationProvider>
        </Box>
      </Drawer>
    </Box>
  );
}
