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

interface RelationshipEditorProps {
  sources: VirtualDatasetSource[];
  relationships: VirtualDatasetRelationship[];
  baseDatasets: DatasetTypeDto[];
  onChange: (relationships: VirtualDatasetRelationship[]) => void;
}

export default function RelationshipEditor({
  sources,
  relationships,
  baseDatasets,
  onChange,
}: RelationshipEditorProps) {
  // 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): DataSchemaDto | undefined => {
    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 handleAddRelationship = () => {
    if (sources.length < 2) return;

    const newRelationship: VirtualDatasetRelationship = {
      id: uuidv4(),
      fromSourceId: sources[0].id,
      fromField: "id",
      toSourceId: sources[1].id,
      toField: "id",
      joinType: "left",
      label: "",
    };
    onChange([...relationships, newRelationship]);
  };

  const handleUpdateRelationship = (
    id: string,
    updates: Partial<VirtualDatasetRelationship>,
  ) => {
    onChange(
      relationships.map((r) => (r.id === id ? { ...r, ...updates } : r)),
    );
  };

  const handleDeleteRelationship = (id: string) => {
    onChange(relationships.filter((r) => r.id !== id));
  };

  if (sources.length < 2) {
    return (
      <Alert severity="info">
        Aggiungi almeno 2 sorgenti dati per definire relazioni tra di esse.
      </Alert>
    );
  }

  return (
    <Box>
      <Box
        sx={{
          display: "flex",
          justifyContent: "space-between",
          alignItems: "center",
          mb: 2,
        }}
      >
        <Box>
          <Typography variant="subtitle2">Relazioni tra Dataset</Typography>
          <Typography variant="caption" color="text.secondary">
            Definisci come collegare i dati tra le diverse sorgenti (JOIN)
          </Typography>
        </Box>
        <Button
          variant="outlined"
          startIcon={<AddIcon />}
          onClick={handleAddRelationship}
        >
          Aggiungi Relazione
        </Button>
      </Box>

      {relationships.length === 0 ? (
        <Alert severity="warning">
          Nessuna relazione definita. Senza relazioni, i dati delle diverse
          sorgenti non saranno collegati (prodotto cartesiano).
        </Alert>
      ) : (
        <Box sx={{ display: "flex", flexDirection: "column", gap: 2 }}>
          {relationships.map((rel) => {
            const fromSchema = getSchemaForSource(rel.fromSourceId);
            const toSchema = getSchemaForSource(rel.toSourceId);

            return (
              <Paper key={rel.id} variant="outlined" sx={{ p: 2 }}>
                <Box
                  sx={{ display: "flex", alignItems: "center", gap: 2, mb: 2 }}
                >
                  <LinkIcon color="primary" />
                  <TextField
                    label="Nome relazione"
                    size="small"
                    value={rel.label || ""}
                    onChange={(e) =>
                      handleUpdateRelationship(rel.id, {
                        label: e.target.value,
                      })
                    }
                    placeholder="Es: Evento -> Cliente"
                    sx={{ flex: 1 }}
                  />
                  <FormControl size="small" sx={{ minWidth: 120 }}>
                    <InputLabel>Tipo JOIN</InputLabel>
                    <Select
                      value={rel.joinType}
                      label="Tipo JOIN"
                      onChange={(e) =>
                        handleUpdateRelationship(rel.id, {
                          joinType: e.target.value as
                            | "inner"
                            | "left"
                            | "right",
                        })
                      }
                    >
                      <MenuItem value="left">LEFT JOIN</MenuItem>
                      <MenuItem value="inner">INNER JOIN</MenuItem>
                      <MenuItem value="right">RIGHT JOIN</MenuItem>
                    </Select>
                  </FormControl>
                  <Tooltip title="Elimina relazione">
                    <IconButton
                      color="error"
                      onClick={() => handleDeleteRelationship(rel.id)}
                    >
                      <DeleteIcon />
                    </IconButton>
                  </Tooltip>
                </Box>

                <Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
                  {/* From Source */}
                  <Box sx={{ flex: 1 }}>
                    <FormControl fullWidth size="small" sx={{ mb: 1 }}>
                      <InputLabel>Sorgente</InputLabel>
                      <Select
                        value={rel.fromSourceId}
                        label="Sorgente"
                        onChange={(e) =>
                          handleUpdateRelationship(rel.id, {
                            fromSourceId: e.target.value,
                          })
                        }
                      >
                        {sources.map((source) => (
                          <MenuItem key={source.id} value={source.id}>
                            {getSourceLabel(source.id)}
                          </MenuItem>
                        ))}
                      </Select>
                    </FormControl>
                    <FormControl fullWidth size="small">
                      <InputLabel>Campo Chiave</InputLabel>
                      <Select
                        value={rel.fromField}
                        label="Campo Chiave"
                        onChange={(e) =>
                          handleUpdateRelationship(rel.id, {
                            fromField: e.target.value,
                          })
                        }
                      >
                        {fromSchema?.fields.map((field) => (
                          <MenuItem key={field.name} value={field.name}>
                            {field.label} ({field.name})
                          </MenuItem>
                        ))}
                      </Select>
                    </FormControl>
                  </Box>

                  {/* Arrow */}
                  <Box
                    sx={{
                      display: "flex",
                      flexDirection: "column",
                      alignItems: "center",
                      px: 2,
                    }}
                  >
                    <ArrowIcon color="action" sx={{ fontSize: 32 }} />
                    <Chip
                      label={rel.joinType.toUpperCase()}
                      size="small"
                      color="primary"
                      variant="outlined"
                    />
                  </Box>

                  {/* To Source */}
                  <Box sx={{ flex: 1 }}>
                    <FormControl fullWidth size="small" sx={{ mb: 1 }}>
                      <InputLabel>Sorgente</InputLabel>
                      <Select
                        value={rel.toSourceId}
                        label="Sorgente"
                        onChange={(e) =>
                          handleUpdateRelationship(rel.id, {
                            toSourceId: e.target.value,
                          })
                        }
                      >
                        {sources.map((source) => (
                          <MenuItem key={source.id} value={source.id}>
                            {getSourceLabel(source.id)}
                          </MenuItem>
                        ))}
                      </Select>
                    </FormControl>
                    <FormControl fullWidth size="small">
                      <InputLabel>Campo Chiave</InputLabel>
                      <Select
                        value={rel.toField}
                        label="Campo Chiave"
                        onChange={(e) =>
                          handleUpdateRelationship(rel.id, {
                            toField: e.target.value,
                          })
                        }
                      >
                        {toSchema?.fields.map((field) => (
                          <MenuItem key={field.name} value={field.name}>
                            {field.label} ({field.name})
                          </MenuItem>
                        ))}
                      </Select>
                    </FormControl>
                  </Box>
                </Box>

                {/* Relationship info */}
                <Box sx={{ mt: 2, p: 1, bgcolor: "grey.50", borderRadius: 1 }}>
                  <Typography variant="caption" color="text.secondary">
                    {rel.joinType === "left" &&
                      "LEFT JOIN: Include tutti i record della sorgente sinistra, anche se non hanno corrispondenza"}
                    {rel.joinType === "inner" &&
                      "INNER JOIN: Include solo i record che hanno corrispondenza in entrambe le sorgenti"}
                    {rel.joinType === "right" &&
                      "RIGHT JOIN: Include tutti i record della sorgente destra, anche se non hanno corrispondenza"}
                  </Typography>
                </Box>
              </Paper>
            );
          })}
        </Box>
      )}

      {/* Visual representation hint */}
      {relationships.length > 0 && (
        <Alert severity="info" sx={{ mt: 2 }}>
          <Typography variant="caption">
            <strong>Suggerimento:</strong> Per report più complessi, puoi creare
            catene di relazioni. Ad esempio: Evento → Cliente → Location per
            ottenere tutti i dati correlati in un unico dataset.
          </Typography>
        </Alert>
      )}
    </Box>
  );
}
