import {
  integer,
  jsonb,
  pgEnum,
  pgTable,
  text,
  timestamp,
} from "drizzle-orm/pg-core";

import { generateId } from "@turbostarter/shared/utils";

import {
  createInsertSchema,
  createSelectSchema,
  createUpdateSchema,
} from "../lib/zod";

import { user } from "./auth";

import type * as z from "zod";

export const diagramTypeEnum = pgEnum("diagram_type", [
  "bpmn",
  "er",
  "orgchart",
  "architecture",
  "sequence",
  "flowchart",
]);

export const project = pgTable("project", {
  id: text().primaryKey().notNull().$defaultFn(generateId),
  name: text().notNull(),
  userId: text()
    .references(() => user.id, { onDelete: "cascade" })
    .notNull(),
  sortOrder: integer().default(0),
  createdAt: timestamp().defaultNow(),
  updatedAt: timestamp().$onUpdate(() => new Date()),
});

export const diagram = pgTable("diagram", {
  id: text().primaryKey().notNull().$defaultFn(generateId),
  title: text().notNull(),
  type: diagramTypeEnum().notNull(),
  graphData: jsonb().$type<object>().default({}),
  userId: text()
    .references(() => user.id, { onDelete: "cascade" })
    .notNull(),
  projectId: text(),
  sortOrder: integer().default(0),
  lastAiMessage: text(),
  deletedAt: timestamp(),
  createdAt: timestamp().defaultNow(),
  updatedAt: timestamp().$onUpdate(() => new Date()),
});

export const insertDiagramSchema = createInsertSchema(diagram);
export const selectDiagramSchema = createSelectSchema(diagram);
export const updateDiagramSchema = createUpdateSchema(diagram);

export type InsertDiagram = z.infer<typeof insertDiagramSchema>;
export type SelectDiagram = z.infer<typeof selectDiagramSchema>;
export type UpdateDiagram = z.infer<typeof updateDiagramSchema>;

export const insertProjectSchema = createInsertSchema(project);
export const selectProjectSchema = createSelectSchema(project);
export const updateProjectSchema = createUpdateSchema(project);

export type InsertProject = z.infer<typeof insertProjectSchema>;
export type SelectProject = z.infer<typeof selectProjectSchema>;
export type UpdateProject = z.infer<typeof updateProjectSchema>;
