import * as React from "react";
import {
  Box,
  Button,
  Paper,
  TextField,
  Autocomplete,
  Select,
  MenuItem,
  FormControl,
  InputLabel,
  Typography,
} from "@mui/material";
import FilterListIcon from "@mui/icons-material/FilterList";
import { ResourceField, ResourceMode } from "../types/config";

function getDisplayValue(item: any, field: ResourceField): string {
  if (!item) return "";
  const df = field.displayField;
  if (!df) return item.name || item.title || item.label || String(item.id ?? "");
  if (Array.isArray(df)) {
    return df.map((k) => item[k]).filter((v) => v != null).join(" ");
  }
  return item[df] ?? String(item.id ?? "");
}

function extractOptions(
  fieldName: string,
  field: ResourceField,
  data: any[]
): string[] {
  const values = new Set<string>();

  if (field.options) {
    return field.options;
  }

  if (!data) return [];

  for (const item of data) {
    const v = item[fieldName];
    if (v == null) continue;

    if (field.type === "array" && Array.isArray(v)) {
      for (const el of v) {
        if (el != null && typeof el === "object") {
          const d = getDisplayValue(el, field);
          if (d) values.add(d);
        } else if (el != null) {
          values.add(String(el));
        }
      }
    } else if (typeof v === "object") {
      const d = getDisplayValue(v, field);
      if (d) values.add(d);
    } else {
      values.add(String(v));
    }
  }

  return Array.from(values).sort();
}

function renderFilterInput(
  fieldName: string,
  field: ResourceField,
  options: string[],
  value: any,
  onChange: (key: string, val: any) => void
) {
  const isRange =
    field.type === "number" || field.type === "datetime" || field.type === "date";

  if (isRange) {
    const rangeVal = (value as { min?: string; max?: string; start?: string; end?: string }) || {};
    const isDate = field.type === "datetime" || field.type === "date";
    const inputType = isDate ? "datetime-local" : "number";

    if (isDate) {
      return (
        <Box key={fieldName} sx={{ display: "flex", gap: 1, alignItems: "center" }}>
          <Typography variant="caption" sx={{ minWidth: 80, color: "text.secondary" }}>
            {field.label}
          </Typography>
          <TextField
            type={inputType}
            placeholder="From"
            size="small"
            value={rangeVal.start ?? ""}
            onChange={(e) => onChange("start", e.target.value || undefined)}
            InputLabelProps={{ shrink: true }}
            sx={{ width: 190 }}
          />
          <TextField
            type={inputType}
            placeholder="To"
            size="small"
            value={rangeVal.end ?? ""}
            onChange={(e) => onChange("end", e.target.value || undefined)}
            InputLabelProps={{ shrink: true }}
            sx={{ width: 190 }}
          />
        </Box>
      );
    }

    return (
      <Box key={fieldName} sx={{ display: "flex", gap: 1, alignItems: "center" }}>
        <Typography variant="caption" sx={{ minWidth: 80, color: "text.secondary" }}>
          {field.label}
        </Typography>
        <TextField
          type={inputType}
          placeholder="Min"
          size="small"
          value={rangeVal.min ?? ""}
          onChange={(e) => onChange("min", e.target.value || undefined)}
          sx={{ width: 120 }}
        />
        <TextField
          type={inputType}
          placeholder="Max"
          size="small"
          value={rangeVal.max ?? ""}
          onChange={(e) => onChange("max", e.target.value || undefined)}
          sx={{ width: 120 }}
        />
      </Box>
    );
  }

  if (field.type === "boolean") {
    return (
      <FormControl key={fieldName} size="small" sx={{ minWidth: 140 }}>
        <InputLabel>{field.label}</InputLabel>
        <Select
          value={value ?? ""}
          label={field.label}
          onChange={(e) => onChange("value", e.target.value || undefined)}
        >
          <MenuItem value="">All</MenuItem>
          <MenuItem value="true">Yes</MenuItem>
          <MenuItem value="false">No</MenuItem>
        </Select>
      </FormControl>
    );
  }

  if (options.length <= 20) {
    return (
      <Autocomplete
        key={fieldName}
        options={options}
        value={value ?? null}
        onChange={(_, val) => onChange("value", val || undefined)}
        renderInput={(params) => (
          <TextField {...params} label={field.label} size="small" />
        )}
        sx={{ minWidth: 180 }}
        size="small"
      />
    );
  }

  return (
    <TextField
      key={fieldName}
      label={field.label}
      value={value ?? ""}
      onChange={(e) => onChange("value", e.target.value || undefined)}
      size="small"
      sx={{ minWidth: 180 }}
    />
  );
}

export interface FilterBarProps {
  fields: Record<string, ResourceField>;
  filterableFields: string[];
  mode: ResourceMode;
  data?: any[];
  appliedValues: Record<string, any>;
  onApply: (values: Record<string, any>) => void;
  onClear: () => void;
}

export default function FilterBar({
  fields,
  filterableFields,
  data,
  appliedValues,
  onApply,
  onClear,
}: FilterBarProps) {
  const [open, setOpen] = React.useState(false);
  const [draft, setDraft] = React.useState<Record<string, any>>(() => ({ ...appliedValues }));

  React.useEffect(() => {
    if (!open) setDraft({ ...appliedValues });
  }, [appliedValues, open]);

  if (!filterableFields || filterableFields.length === 0) return null;

  const activeCount = Object.keys(appliedValues).filter((k) => {
    const v = appliedValues[k];
    if (v == null || v === "") return false;
    if (typeof v === "object" && Object.values(v).every((x) => x == null || x === "")) return false;
    return true;
  }).length;

  const handleApply = () => onApply({ ...draft });
  const handleClear = () => {
    setDraft({});
    onClear();
  };

  const updateDraft = (fieldName: string, key: string, val: any) => {
    setDraft((prev) => {
      if (key === "value") {
        return { ...prev, [fieldName]: val };
      }
      const existing = prev[fieldName] || {};
      return { ...prev, [fieldName]: { ...existing, [key]: val } };
    });
  };

  return (
    <Paper variant="outlined" sx={{ mb: 2, borderRadius: 2, overflow: "hidden" }}>
      <Box
        sx={{
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          px: 2,
          py: 1,
          cursor: "pointer",
          "&:hover": { bgcolor: "action.hover" },
        }}
        onClick={() => setOpen((o) => !o)}
      >
        <Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
          <FilterListIcon fontSize="small" color="action" />
          <Typography variant="subtitle2" fontWeight={600}>
            {open ? "Hide Filters" : "Show Filters"}
          </Typography>
        </Box>
        {activeCount > 0 && (
          <Typography variant="caption" color="primary" fontWeight={600}>
            {activeCount} active
          </Typography>
        )}
      </Box>

      {open && (
        <Box sx={{ px: 2, pb: 2, borderTop: "1px solid", borderColor: "divider", pt: 2 }}>
          <Box sx={{ display: "flex", flexWrap: "wrap", gap: 2, alignItems: "flex-end" }}>
            {filterableFields.map((fieldName) => {
              const field = fields[fieldName];
              if (!field) return null;

              const options = extractOptions(fieldName, field, data ?? []);
              const raw = draft[fieldName];

              return (
                <React.Fragment key={fieldName}>
                  {renderFilterInput(fieldName, field, options, raw, (key, val) =>
                    updateDraft(fieldName, key, val)
                  )}
                </React.Fragment>
              );
            })}
          </Box>

          <Box sx={{ mt: 2, display: "flex", gap: 1 }}>
            <Button variant="contained" size="small" onClick={handleApply}>
              Apply
            </Button>
            <Button variant="outlined" size="small" onClick={handleClear}>
              Clear
            </Button>
          </Box>
        </Box>
      )}
    </Paper>
  );
}
