import { r as reactExports, j as jsxRuntimeExports, c as a, w as h, d as c, s, h as m, o as a$1, i as s$1, x as l, y as l$1, z as m$1, A as o, B as i, C as m$2, k as c$1, l as i$1, e as gql, p as s$2, q as c$2, u, t as n, v as i$2, m as m$3 } from "./index-Cr4zbAtA.js";
import { M as Metadata } from "./Metadata-aK5zM6ek.js";
import { c as createCell } from "./createCell-D7cbP3PP.js";
import { D as Dagre, F as ForwardRef, B as Background$1, a as BackgroundVariant, C as Controls$1 } from "./index-x4KEE2o6.js";
import { H as Handle$1, P as Position, R as ReactFlowProvider, u as useReactFlow, a as useNodesState, b as useEdgesState, c as ReactFlow, d as Panel } from "./index-DFcimn70.js";
import { F as ForwardRef$1 } from "./ArrowsRightLeftIcon-BIf68FuZ.js";
const parseProperties = (properties) => {
  const fields = {};
  if (properties) {
    for (const propertyName in properties) {
      const property = properties[propertyName];
      const type = Array.isArray(property.type) ? property.type.join(", ") : property.type;
      const format = property.format;
      const field = {
        type,
        format,
        relationship: null,
        relatedModel: null
      };
      if (property.$ref) {
        const relatedModel = property.$ref.split("/").pop();
        field.type = "object";
        field.relatedModel = relatedModel;
        field.relationship = `Model-${relatedModel}`;
      }
      fields[propertyName] = field;
    }
  }
  return fields;
};
const extractNodesAndEdges = (jsonSchema) => {
  const definitions = (jsonSchema == null ? void 0 : jsonSchema.definitions) ?? {};
  const objectNodeKeys = [];
  const nodes = [];
  const edges = [];
  let index = 0;
  if (definitions) {
    for (const definitionName in definitions) {
      const definition = definitions[definitionName];
      const id = `Model-${definitionName}`;
      const model = {
        id,
        type: "PrismaModel",
        data: {
          name: definitionName,
          type: definition.type || "object",
          fields: parseProperties(definition.properties),
          fieldCount: Object.keys(definition.properties || {}).length
        },
        position: {
          x: 0,
          y: index * 128
        },
        deletable: false,
        draggable: true
      };
      objectNodeKeys.push(definitionName);
      nodes.push(model);
      index++;
    }
  }
  objectNodeKeys.forEach((node) => {
    const nodeSchema = jsonSchema.definitions[node];
    const properties = nodeSchema.properties;
    Object.keys(properties).forEach((property) => {
      const propertySchema = properties[property];
      if (propertySchema.$ref) {
        const target = propertySchema.$ref.split("/").pop();
        if (target) {
          edges.push({
            id: `e-${node}-${property}`,
            source: `Model-${node}`,
            target: `Model-${target}`,
            label: property,
            animated: true
          });
        }
      }
    });
  });
  return {
    nodes,
    edges
  };
};
const getTableDataForSchema = (schema) => {
  const tableData = [];
  const {
    nodes
  } = extractNodesAndEdges(schema);
  nodes.forEach((node) => {
    const {
      name,
      fields
    } = node.data;
    const row = {
      name,
      fields: []
    };
    Object.keys(fields).forEach((fieldName) => {
      row.fields.push({
        name: fieldName,
        ...fields[fieldName]
      });
    });
    tableData.push(row);
  });
  return tableData;
};
const PrismaSchemaNode = ({
  data
}) => {
  const {
    name,
    color,
    emoji
  } = {
    name: data.name,
    color: "zinc",
    emoji: "📦"
  };
  const textColor = `text-${color}-600`;
  const borderColor = `border-${color}-700`;
  const bgColor = `bg-${color}-200`;
  const captionColor = `text-${color}-400`;
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `${borderColor} max-w-64 max-h-32 rounded-md border-2 border-r-2 ${borderColor} bg-white px-4 py-2 shadow-md`, children: [
    /* @__PURE__ */ jsxRuntimeExports.jsx(Handle$1, { type: "target", position: Position.Top }),
    /* @__PURE__ */ jsxRuntimeExports.jsx(Handle$1, { type: "source", position: Position.Bottom }),
    /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center", children: [
      /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `flex h-12 w-12 items-center justify-center rounded-full ${bgColor}`, children: emoji }),
      /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ml-2", children: [
        /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `text-lg font-bold ${textColor}`, children: name }),
        /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `text-sm ${captionColor}`, children: [
          data.fieldCount,
          " fields"
        ] })
      ] })
    ] })
  ] });
};
const PrismaSchemaNode$1 = reactExports.memo(PrismaSchemaNode);
const g = new Dagre.graphlib.Graph().setDefaultEdgeLabel(() => ({}));
const getLayoutedElements = (nodes, edges, options) => {
  g.setGraph({
    rankdir: options.direction
  });
  edges.forEach((edge) => g.setEdge(edge.source, edge.target));
  nodes.forEach((node) => g.setNode(node.id, node));
  Dagre.layout(g);
  return {
    nodes: nodes.map((node) => {
      const {
        x,
        y
      } = g.node(node.id);
      return {
        ...node,
        position: {
          x,
          y
        }
      };
    }),
    edges
  };
};
const LayoutFlow = ({
  prismaSchema
}) => {
  const {
    fitView
  } = useReactFlow();
  const {
    nodes: initialNodes,
    edges: initialEdges
  } = extractNodesAndEdges(prismaSchema.schema);
  const nodeTypes = {
    PrismaModel: PrismaSchemaNode$1
  };
  const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
  const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
  const onLayout = reactExports.useCallback((direction) => {
    const layouted = getLayoutedElements(nodes, edges, {
      direction
    });
    setNodes([...layouted.nodes]);
    setEdges([...layouted.edges]);
    window.requestAnimationFrame(() => {
      fitView();
    });
  }, [nodes, edges, fitView, setNodes, setEdges]);
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-[640px] w-full min-w-[320px]", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(ReactFlow, { className: "bg-zinc-50", nodes, edges, nodeTypes, onNodesChange, onEdgesChange, nodesDraggable: true, fitView: true, children: [
    /* @__PURE__ */ jsxRuntimeExports.jsx(Panel, { position: "top-right", onLoad: () => onLayout("TB"), children: /* @__PURE__ */ jsxRuntimeExports.jsxs(a, { flexDirection: "row", alignItems: "center", justifyContent: "evenly", className: "space-x-4", children: [
      /* @__PURE__ */ jsxRuntimeExports.jsx(h, { icon: ForwardRef, onClick: () => onLayout("TB") }),
      /* @__PURE__ */ jsxRuntimeExports.jsx(h, { icon: ForwardRef$1, onClick: () => onLayout("LR") })
    ] }) }),
    /* @__PURE__ */ jsxRuntimeExports.jsx(Background$1, { variant: BackgroundVariant.Dots }),
    /* @__PURE__ */ jsxRuntimeExports.jsx(Controls$1, { className: "bg-white", showInteractive: false })
  ] }) });
};
const PrismaEntityRelationshipDiagram = ({
  prismaSchema
}) => {
  return /* @__PURE__ */ jsxRuntimeExports.jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(LayoutFlow, { prismaSchema }) });
};
const PrismaModelList = ({
  prismaSchema
}) => {
  const {
    nodes
  } = extractNodesAndEdges(prismaSchema.schema);
  const data = nodes.map((node) => {
    const {
      name,
      fieldCount: value
    } = node.data;
    return {
      name,
      value
    };
  });
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(c, { className: "w-full", children: [
    /* @__PURE__ */ jsxRuntimeExports.jsx(s, { children: "Models" }),
    /* @__PURE__ */ jsxRuntimeExports.jsxs(a, { className: "mt-4", children: [
      /* @__PURE__ */ jsxRuntimeExports.jsx(m, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(a$1, { children: "Name" }) }),
      /* @__PURE__ */ jsxRuntimeExports.jsx(m, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(a$1, { children: "Fields" }) })
    ] }),
    /* @__PURE__ */ jsxRuntimeExports.jsx(s$1, { data, className: "mt-2" })
  ] });
};
const PrismaTableCard = ({
  data
}) => {
  var _a;
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(c, { children: [
    /* @__PURE__ */ jsxRuntimeExports.jsx(s, { children: data.name }),
    /* @__PURE__ */ jsxRuntimeExports.jsxs(l, { className: "mt-5", children: [
      /* @__PURE__ */ jsxRuntimeExports.jsx(l$1, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(m$1, { children: [
        /* @__PURE__ */ jsxRuntimeExports.jsx(o, { children: "Name" }),
        /* @__PURE__ */ jsxRuntimeExports.jsx(o, { children: "Type" }),
        /* @__PURE__ */ jsxRuntimeExports.jsx(o, { children: "Format" }),
        /* @__PURE__ */ jsxRuntimeExports.jsx(o, { children: "Relationship" })
      ] }) }),
      /* @__PURE__ */ jsxRuntimeExports.jsx(i, { children: (_a = data == null ? void 0 : data.fields) == null ? void 0 : _a.map((field) => /* @__PURE__ */ jsxRuntimeExports.jsxs(m$1, { children: [
        /* @__PURE__ */ jsxRuntimeExports.jsx(m$2, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(a$1, { children: field.name }) }),
        /* @__PURE__ */ jsxRuntimeExports.jsx(m$2, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(m, { children: field.type }) }),
        /* @__PURE__ */ jsxRuntimeExports.jsx(m$2, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(m, { children: field.format }) }),
        /* @__PURE__ */ jsxRuntimeExports.jsx(m$2, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(m, { children: field.relatedModel }) })
      ] }, field.name)) })
    ] })
  ] });
};
const PrismaTableViews = ({
  prismaSchema
}) => {
  const tableData = getTableDataForSchema(prismaSchema.schema);
  return /* @__PURE__ */ jsxRuntimeExports.jsx(c$1, { numItems: 2, numItemsSm: 1, numItemsLg: 2, className: "gap-4", children: tableData.map((table) => /* @__PURE__ */ jsxRuntimeExports.jsx(i$1, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(PrismaTableCard, { data: table }, table.name) }, table.name)) });
};
const QUERY = gql`
  query FindPrismaSchemaQuery {
    prismaSchema {
      id
      schema
    }
  }
`;
const Loading = () => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." });
const Empty = () => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Empty" });
const Failure = ({
  error
}) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", {
  className: "font-bold text-tremor-brand dark:text-dark-tremor-brand",
  children: [
    "Error: ",
    error == null ? void 0 : error.message
  ]
});
const Success = ({
  prismaSchema
}) => {
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(s$2, {
    children: [
      /* @__PURE__ */ jsxRuntimeExports.jsxs(c$2, {
        className: "mt-8",
        children: [
          /* @__PURE__ */ jsxRuntimeExports.jsx(u, { children: "Diagram" }),
          /* @__PURE__ */ jsxRuntimeExports.jsx(u, { children: "Schema" }),
          /* @__PURE__ */ jsxRuntimeExports.jsx(u, { children: "Details" })
        ]
      }),
      /* @__PURE__ */ jsxRuntimeExports.jsxs(n, {
        children: [
          /* @__PURE__ */ jsxRuntimeExports.jsx(i$2, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(PrismaEntityRelationshipDiagram, { prismaSchema }) }),
          /* @__PURE__ */ jsxRuntimeExports.jsx(i$2, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(PrismaTableViews, { prismaSchema }) }),
          /* @__PURE__ */ jsxRuntimeExports.jsx(i$2, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(PrismaModelList, { prismaSchema }) })
        ]
      })
    ]
  });
};
const PrismaSchemaCell = createCell({ QUERY, Loading, Empty, Failure, Success, displayName: "PrismaSchemaCell" });
const DatabaseSchemaPage = () => {
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
    /* @__PURE__ */ jsxRuntimeExports.jsx(Metadata, { title: "Database Schema", description: "Explore your database schema." }),
    /* @__PURE__ */ jsxRuntimeExports.jsx(s, { children: "Database Schema" }),
    /* @__PURE__ */ jsxRuntimeExports.jsx(m$3, { children: "Explore your database schema." }),
    /* @__PURE__ */ jsxRuntimeExports.jsx(PrismaSchemaCell, {})
  ] });
};
export {
  DatabaseSchemaPage as default
};
