import { v4 as uuidv4 } from "uuid";
import {
  Box,
  Typography,
  Button,
  Paper,
  IconButton,
  FormControl,
  InputLabel,
  Select,
  MenuItem,
  TextField,
  Alert,
  Switch,
  FormControlLabel,
  Chip,
  Tooltip,
} from "@mui/material";
import {
  Add as AddIcon,
  Delete as DeleteIcon,
  FilterList as FilterIcon,
} from "@mui/icons-material";
import { useQueries } from "@tanstack/react-query";
import { reportGeneratorService } from "../../services/reportService";
import type {
  VirtualDatasetSource,
  VirtualDatasetFilter,
  DatasetTypeDto,
} from "../../types/report";

interface FilterBuilderProps {
  sources: VirtualDatasetSource[];
  filters: VirtualDatasetFilter[];
  baseDatasets: DatasetTypeDto[];
  onChange: (filters: VirtualDatasetFilter[]) => void;
}

const OPERATORS = [
  {
    value: "eq",
    label: "Uguale a (=)",
    description: "Il campo deve essere uguale al valore",
  },
  {
    value: "neq",
    label: "Diverso da (!=)",
    description: "Il campo deve essere diverso dal valore",
  },
  {
    value: "gt",
    label: "Maggiore di (>)",
    description: "Il campo deve essere maggiore del valore",
  },
  {
    value: "gte",
    label: "Maggiore o uguale (>=)",
    description: "Il campo deve essere maggiore o uguale al valore",
  },
  {
    value: "lt",
    label: "Minore di (<)",
    description: "Il campo deve essere minore del valore",
  },
  {
    value: "lte",
    label: "Minore o uguale (<=)",
    description: "Il campo deve essere minore o uguale al valore",
  },
  {
    value: "contains",
    label: "Contiene",
    description: "Il campo deve contenere il testo",
  },
  {
    value: "startsWith",
    label: "Inizia con",
    description: "Il campo deve iniziare con il testo",
  },
  {
    value: "endsWith",
    label: "Finisce con",
    description: "Il campo deve terminare con il testo",
  },
  {
    value: "isNull",
    label: "E' vuoto",
    description: "Il campo deve essere vuoto/null",
  },
  {
    value: "isNotNull",
    label: "Non è vuoto",
    description: "Il campo non deve essere vuoto/null",
  },
];

export default function FilterBuilder({
  sources,
  filters,
  baseDatasets,
  onChange,
}: FilterBuilderProps) {
  // Fetch schemas for all sources
  const schemaQueries = useQueries({
    queries: sources.map((source) => ({
      queryKey: ["dataset-schema", source.datasetId],
      queryFn: () => reportGeneratorService.getSchema(source.datasetId),
      staleTime: 60000,
    })),
  });

  const getSchemaForSource = (sourceId: string) => {
    const source = sources.find((s) => s.id === sourceId);
    if (!source) return undefined;
    const index = sources.findIndex((s) => s.id === sourceId);
    return schemaQueries[index]?.data;
  };

  const getSourceLabel = (sourceId: string) => {
    const source = sources.find((s) => s.id === sourceId);
    if (!source) return sourceId;
    const baseDataset = baseDatasets.find((d) => d.id === source.datasetId);
    return `${source.alias} (${baseDataset?.name || source.datasetId})`;
  };

  const handleAddFilter = () => {
    if (sources.length === 0) return;

    const newFilter: VirtualDatasetFilter = {
      id: uuidv4(),
      sourceId: sources[0].id,
      field: "",
      operator: "eq",
      value: "",
      valueType: "static",
      logicalOperator: "and",
      enabled: true,
    };
    onChange([...filters, newFilter]);
  };

  const handleUpdateFilter = (
    id: string,
    updates: Partial<VirtualDatasetFilter>,
  ) => {
    onChange(filters.map((f) => (f.id === id ? { ...f, ...updates } : f)));
  };

  const handleDeleteFilter = (id: string) => {
    onChange(filters.filter((f) => f.id !== id));
  };

  const needsValue = (operator: string) => {
    return !["isNull", "isNotNull"].includes(operator);
  };

  if (sources.length === 0) {
    return (
      <Alert severity="info">
        Aggiungi almeno una sorgente dati per poter definire filtri.
      </Alert>
    );
  }

  return (
    <Box>
      <Box
        sx={{
          display: "flex",
          justifyContent: "space-between",
          alignItems: "center",
          mb: 2,
        }}
      >
        <Box>
          <Typography variant="subtitle2">Filtri</Typography>
          <Typography variant="caption" color="text.secondary">
            Definisci condizioni per filtrare i dati del dataset
          </Typography>
        </Box>
        <Button
          variant="outlined"
          startIcon={<AddIcon />}
          onClick={handleAddFilter}
        >
          Aggiungi Filtro
        </Button>
      </Box>

      {filters.length === 0 ? (
        <Alert severity="info">
          Nessun filtro definito. Tutti i dati saranno inclusi nel dataset.
        </Alert>
      ) : (
        <Box sx={{ display: "flex", flexDirection: "column", gap: 2 }}>
          {filters.map((filter, index) => {
            const schema = getSchemaForSource(filter.sourceId);
            const selectedField = schema?.fields.find(
              (f) => f.name === filter.field,
            );

            return (
              <Paper
                key={filter.id}
                variant="outlined"
                sx={{
                  p: 2,
                  opacity: filter.enabled ? 1 : 0.6,
                  bgcolor: filter.enabled ? "inherit" : "grey.50",
                }}
              >
                {/* Logical operator for subsequent filters */}
                {index > 0 && (
                  <Box
                    sx={{ display: "flex", justifyContent: "center", mb: 2 }}
                  >
                    <FormControl size="small" sx={{ minWidth: 100 }}>
                      <Select
                        value={filter.logicalOperator}
                        onChange={(e) =>
                          handleUpdateFilter(filter.id, {
                            logicalOperator: e.target.value as "and" | "or",
                          })
                        }
                        sx={{
                          bgcolor: "primary.main",
                          color: "white",
                          "& .MuiSelect-icon": { color: "white" },
                        }}
                      >
                        <MenuItem value="and">AND</MenuItem>
                        <MenuItem value="or">OR</MenuItem>
                      </Select>
                    </FormControl>
                  </Box>
                )}

                <Box sx={{ display: "flex", alignItems: "flex-start", gap: 2 }}>
                  <FilterIcon
                    color={filter.enabled ? "primary" : "disabled"}
                    sx={{ mt: 1 }}
                  />

                  {/* Source */}
                  <FormControl size="small" sx={{ minWidth: 150 }}>
                    <InputLabel>Sorgente</InputLabel>
                    <Select
                      value={filter.sourceId}
                      label="Sorgente"
                      onChange={(e) =>
                        handleUpdateFilter(filter.id, {
                          sourceId: e.target.value,
                          field: "", // Reset field when source changes
                        })
                      }
                      disabled={!filter.enabled}
                    >
                      {sources.map((source) => (
                        <MenuItem key={source.id} value={source.id}>
                          {getSourceLabel(source.id)}
                        </MenuItem>
                      ))}
                    </Select>
                  </FormControl>

                  {/* Field */}
                  <FormControl size="small" sx={{ minWidth: 180 }}>
                    <InputLabel>Campo</InputLabel>
                    <Select
                      value={filter.field}
                      label="Campo"
                      onChange={(e) =>
                        handleUpdateFilter(filter.id, { field: e.target.value })
                      }
                      disabled={!filter.enabled}
                    >
                      {schema?.fields.map((field) => (
                        <MenuItem key={field.name} value={field.name}>
                          {field.label}
                          <Chip
                            label={field.type}
                            size="small"
                            sx={{ ml: 1, height: 18, fontSize: "0.65rem" }}
                          />
                        </MenuItem>
                      ))}
                    </Select>
                  </FormControl>

                  {/* Operator */}
                  <FormControl size="small" sx={{ minWidth: 160 }}>
                    <InputLabel>Operatore</InputLabel>
                    <Select
                      value={filter.operator}
                      label="Operatore"
                      onChange={(e) =>
                        handleUpdateFilter(filter.id, {
                          operator: e.target
                            .value as VirtualDatasetFilter["operator"],
                        })
                      }
                      disabled={!filter.enabled}
                    >
                      {OPERATORS.map((op) => (
                        <MenuItem key={op.value} value={op.value}>
                          {op.label}
                        </MenuItem>
                      ))}
                    </Select>
                  </FormControl>

                  {/* Value */}
                  {needsValue(filter.operator) && (
                    <Box sx={{ display: "flex", gap: 1, flex: 1 }}>
                      <FormControl size="small" sx={{ minWidth: 100 }}>
                        <InputLabel>Tipo Valore</InputLabel>
                        <Select
                          value={filter.valueType}
                          label="Tipo Valore"
                          onChange={(e) =>
                            handleUpdateFilter(filter.id, {
                              valueType: e.target.value as
                                | "static"
                                | "parameter"
                                | "field",
                            })
                          }
                          disabled={!filter.enabled}
                        >
                          <MenuItem value="static">Statico</MenuItem>
                          <MenuItem value="parameter">Parametro</MenuItem>
                          <MenuItem value="field">Campo</MenuItem>
                        </Select>
                      </FormControl>

                      {filter.valueType === "static" && (
                        <TextField
                          label="Valore"
                          size="small"
                          value={filter.value || ""}
                          onChange={(e) =>
                            handleUpdateFilter(filter.id, {
                              value: e.target.value,
                            })
                          }
                          disabled={!filter.enabled}
                          placeholder={
                            selectedField?.type === "date"
                              ? "YYYY-MM-DD"
                              : selectedField?.type === "number" ||
                                  selectedField?.type === "currency"
                                ? "0"
                                : "Testo"
                          }
                          sx={{ flex: 1 }}
                        />
                      )}

                      {filter.valueType === "parameter" && (
                        <TextField
                          label="Nome Parametro"
                          size="small"
                          value={filter.value || ""}
                          onChange={(e) =>
                            handleUpdateFilter(filter.id, {
                              value: e.target.value,
                            })
                          }
                          disabled={!filter.enabled}
                          placeholder="nomeParametro"
                          helperText="Usabile come {{nomeParametro}}"
                          sx={{ flex: 1 }}
                        />
                      )}

                      {filter.valueType === "field" && (
                        <FormControl size="small" sx={{ flex: 1 }}>
                          <InputLabel>Campo di confronto</InputLabel>
                          <Select
                            value={filter.value || ""}
                            label="Campo di confronto"
                            onChange={(e) =>
                              handleUpdateFilter(filter.id, {
                                value: e.target.value,
                              })
                            }
                            disabled={!filter.enabled}
                          >
                            {sources.flatMap((s) => {
                              const srcSchema = getSchemaForSource(s.id);
                              return (
                                srcSchema?.fields.map((f) => (
                                  <MenuItem
                                    key={`${s.id}.${f.name}`}
                                    value={`${s.alias}.${f.name}`}
                                  >
                                    {s.alias}.{f.label}
                                  </MenuItem>
                                )) || []
                              );
                            })}
                          </Select>
                        </FormControl>
                      )}
                    </Box>
                  )}

                  {/* Actions */}
                  <Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
                    <FormControlLabel
                      control={
                        <Switch
                          checked={filter.enabled}
                          onChange={(e) =>
                            handleUpdateFilter(filter.id, {
                              enabled: e.target.checked,
                            })
                          }
                          size="small"
                        />
                      }
                      label=""
                    />
                    <Tooltip title="Elimina filtro">
                      <IconButton
                        size="small"
                        color="error"
                        onClick={() => handleDeleteFilter(filter.id)}
                      >
                        <DeleteIcon />
                      </IconButton>
                    </Tooltip>
                  </Box>
                </Box>

                {/* Description */}
                <Box sx={{ mt: 1, ml: 5 }}>
                  <Typography variant="caption" color="text.secondary">
                    {
                      OPERATORS.find((op) => op.value === filter.operator)
                        ?.description
                    }
                  </Typography>
                </Box>
              </Paper>
            );
          })}
        </Box>
      )}

      {/* Help */}
      <Alert severity="info" sx={{ mt: 2 }}>
        <Typography variant="caption">
          <strong>Tipi di valore:</strong>
          <br />• <strong>Statico:</strong> Un valore fisso (es: "10",
          "Confermato")
          <br />• <strong>Parametro:</strong> Un valore dinamico passato al
          momento della generazione del report
          <br />• <strong>Campo:</strong> Confronta con il valore di un altro
          campo (es: dataFine {">"} dataInizio)
        </Typography>
      </Alert>
    </Box>
  );
}
