import {
  pgTable,
  pgEnum,
  uuid,
  text,
  integer,
  boolean,
  timestamp,
  jsonb,
  real,
  uniqueIndex,
  index,
} from 'drizzle-orm/pg-core';
import { relations } from 'drizzle-orm';

// ── Enums ──────────────────────────────────────────────────────────────────────

export const userTierEnum = pgEnum('user_tier', [
  'free',
  'pro',
  'team',
  'enterprise',
]);

export const projectStatusEnum = pgEnum('project_status', [
  'draft',
  'analyzed',
  'generated',
  'tested',
  'deployed',
]);

export const deploymentStatusEnum = pgEnum('deployment_status', [
  'pending',
  'building',
  'live',
  'failed',
  'stopped',
]);

export const listingStatusEnum = pgEnum('listing_status', [
  'review',
  'published',
  'rejected',
  'archived',
]);

// ── Teams ──────────────────────────────────────────────────────────────────────

export const teams = pgTable(
  'teams',
  {
    id: uuid('id').primaryKey().defaultRandom(),
    name: text('name').notNull(),
    slug: text('slug').notNull(),
    ownerId: uuid('owner_id'), // FK to users.id (circular ref handled in relations)
    tier: userTierEnum('tier').default('team').notNull(),
    stripeSubscriptionId: text('stripe_subscription_id'),
    maxSeats: integer('max_seats').default(5).notNull(),
    createdAt: timestamp('created_at', { withTimezone: true })
      .defaultNow()
      .notNull(),
  },
  (t) => [
    uniqueIndex('teams_slug_idx').on(t.slug),
  ],
);

// ── Users ──────────────────────────────────────────────────────────────────────

export const users = pgTable(
  'users',
  {
    id: uuid('id').primaryKey().defaultRandom(),
    clerkId: text('clerk_id').notNull(),
    email: text('email').notNull(),
    name: text('name'),
    avatarUrl: text('avatar_url'),
    tier: userTierEnum('tier').default('free').notNull(),
    stripeCustomerId: text('stripe_customer_id'),
    teamId: uuid('team_id').references(() => teams.id),
    createdAt: timestamp('created_at', { withTimezone: true })
      .defaultNow()
      .notNull(),
    updatedAt: timestamp('updated_at', { withTimezone: true })
      .defaultNow()
      .notNull(),
  },
  (t) => [
    uniqueIndex('users_clerk_id_idx').on(t.clerkId),
    uniqueIndex('users_email_idx').on(t.email),
    index('users_team_id_idx').on(t.teamId),
  ],
);

// ── Projects ───────────────────────────────────────────────────────────────────

export const projects = pgTable(
  'projects',
  {
    id: uuid('id').primaryKey().defaultRandom(),
    userId: uuid('user_id')
      .references(() => users.id)
      .notNull(),
    teamId: uuid('team_id').references(() => teams.id),
    name: text('name').notNull(),
    slug: text('slug').notNull(),
    description: text('description'),
    status: projectStatusEnum('status').default('draft').notNull(),
    specUrl: text('spec_url'),
    specRaw: jsonb('spec_raw'),
    analysis: jsonb('analysis'),
    toolConfig: jsonb('tool_config'),
    appConfig: jsonb('app_config'),
    authConfig: jsonb('auth_config'),
    serverBundle: jsonb('server_bundle'),
    templateId: uuid('template_id'), // FK to marketplace_listings (circular ref handled in relations)
    createdAt: timestamp('created_at', { withTimezone: true })
      .defaultNow()
      .notNull(),
    updatedAt: timestamp('updated_at', { withTimezone: true })
      .defaultNow()
      .notNull(),
  },
  (t) => [
    uniqueIndex('projects_user_slug_idx').on(t.userId, t.slug),
    index('projects_user_id_idx').on(t.userId),
    index('projects_team_id_idx').on(t.teamId),
    index('projects_status_idx').on(t.status),
    index('projects_template_id_idx').on(t.templateId),
  ],
);

// ── Tools ──────────────────────────────────────────────────────────────────────

export const tools = pgTable(
  'tools',
  {
    id: uuid('id').primaryKey().defaultRandom(),
    projectId: uuid('project_id')
      .references(() => projects.id, { onDelete: 'cascade' })
      .notNull(),
    name: text('name').notNull(),
    description: text('description'),
    groupName: text('group_name'),
    inputSchema: jsonb('input_schema'),
    outputSchema: jsonb('output_schema'),
    annotations: jsonb('annotations'),
    enabled: boolean('enabled').default(true).notNull(),
    position: integer('position').default(0).notNull(),
    canvasX: real('canvas_x'),
    canvasY: real('canvas_y'),
    createdAt: timestamp('created_at', { withTimezone: true })
      .defaultNow()
      .notNull(),
  },
  (t) => [
    index('tools_project_id_idx').on(t.projectId),
    index('tools_group_name_idx').on(t.groupName),
  ],
);

// ── Apps ────────────────────────────────────────────────────────────────────────

export const apps = pgTable(
  'apps',
  {
    id: uuid('id').primaryKey().defaultRandom(),
    projectId: uuid('project_id')
      .references(() => projects.id, { onDelete: 'cascade' })
      .notNull(),
    name: text('name').notNull(),
    pattern: text('pattern'),
    layoutConfig: jsonb('layout_config'),
    htmlBundle: text('html_bundle'),
    toolBindings: jsonb('tool_bindings'),
    createdAt: timestamp('created_at', { withTimezone: true })
      .defaultNow()
      .notNull(),
  },
  (t) => [
    index('apps_project_id_idx').on(t.projectId),
  ],
);

// ── Deployments ────────────────────────────────────────────────────────────────

export const deployments = pgTable(
  'deployments',
  {
    id: uuid('id').primaryKey().defaultRandom(),
    projectId: uuid('project_id')
      .references(() => projects.id)
      .notNull(),
    userId: uuid('user_id')
      .references(() => users.id)
      .notNull(),
    target: text('target').notNull(),
    status: deploymentStatusEnum('status').default('pending').notNull(),
    url: text('url'),
    endpoint: text('endpoint'),
    workerId: text('worker_id'),
    version: text('version'),
    logs: jsonb('logs'),
    createdAt: timestamp('created_at', { withTimezone: true })
      .defaultNow()
      .notNull(),
    stoppedAt: timestamp('stopped_at', { withTimezone: true }),
  },
  (t) => [
    index('deployments_project_id_idx').on(t.projectId),
    index('deployments_user_id_idx').on(t.userId),
    index('deployments_status_idx').on(t.status),
  ],
);

// ── Marketplace Listings ───────────────────────────────────────────────────────

export const marketplaceListings = pgTable(
  'marketplace_listings',
  {
    id: uuid('id').primaryKey().defaultRandom(),
    projectId: uuid('project_id').references(() => projects.id),
    authorId: uuid('author_id').references(() => users.id),
    name: text('name').notNull(),
    slug: text('slug').notNull(),
    description: text('description'),
    category: text('category'),
    tags: text('tags').array(),
    iconUrl: text('icon_url'),
    previewUrl: text('preview_url'),
    toolCount: integer('tool_count').default(0).notNull(),
    appCount: integer('app_count').default(0).notNull(),
    forkCount: integer('fork_count').default(0).notNull(),
    isOfficial: boolean('is_official').default(false).notNull(),
    isFeatured: boolean('is_featured').default(false).notNull(),
    priceCents: integer('price_cents').default(0).notNull(),
    status: listingStatusEnum('status').default('review').notNull(),
    createdAt: timestamp('created_at', { withTimezone: true })
      .defaultNow()
      .notNull(),
    publishedAt: timestamp('published_at', { withTimezone: true }),
  },
  (t) => [
    uniqueIndex('marketplace_slug_idx').on(t.slug),
    index('marketplace_category_idx').on(t.category),
    index('marketplace_status_idx').on(t.status),
    index('marketplace_is_official_idx').on(t.isOfficial),
    index('marketplace_is_featured_idx').on(t.isFeatured),
    index('marketplace_author_id_idx').on(t.authorId),
  ],
);

// ── Usage Logs ─────────────────────────────────────────────────────────────────

export const usageLogs = pgTable(
  'usage_logs',
  {
    id: uuid('id').primaryKey().defaultRandom(),
    userId: uuid('user_id')
      .references(() => users.id)
      .notNull(),
    action: text('action').notNull(),
    projectId: uuid('project_id').references(() => projects.id),
    tokensUsed: integer('tokens_used').default(0),
    durationMs: integer('duration_ms').default(0),
    createdAt: timestamp('created_at', { withTimezone: true })
      .defaultNow()
      .notNull(),
  },
  (t) => [
    index('usage_logs_user_id_idx').on(t.userId),
    index('usage_logs_project_id_idx').on(t.projectId),
    index('usage_logs_action_idx').on(t.action),
    index('usage_logs_created_at_idx').on(t.createdAt),
  ],
);

// ── API Keys ───────────────────────────────────────────────────────────────────

export const apiKeys = pgTable(
  'api_keys',
  {
    id: uuid('id').primaryKey().defaultRandom(),
    projectId: uuid('project_id')
      .references(() => projects.id, { onDelete: 'cascade' })
      .notNull(),
    userId: uuid('user_id')
      .references(() => users.id)
      .notNull(),
    keyName: text('key_name').notNull(),
    encryptedValue: text('encrypted_value').notNull(),
    createdAt: timestamp('created_at', { withTimezone: true })
      .defaultNow()
      .notNull(),
  },
  (t) => [
    index('api_keys_project_id_idx').on(t.projectId),
    index('api_keys_user_id_idx').on(t.userId),
  ],
);

// ── Relations ──────────────────────────────────────────────────────────────────

export const usersRelations = relations(users, ({ one, many }) => ({
  team: one(teams, { fields: [users.teamId], references: [teams.id] }),
  projects: many(projects),
  deployments: many(deployments),
  usageLogs: many(usageLogs),
  apiKeys: many(apiKeys),
}));

export const teamsRelations = relations(teams, ({ one, many }) => ({
  owner: one(users, { fields: [teams.ownerId], references: [users.id] }),
  members: many(users),
  projects: many(projects),
}));

export const projectsRelations = relations(projects, ({ one, many }) => ({
  user: one(users, { fields: [projects.userId], references: [users.id] }),
  team: one(teams, { fields: [projects.teamId], references: [teams.id] }),
  template: one(marketplaceListings, {
    fields: [projects.templateId],
    references: [marketplaceListings.id],
  }),
  tools: many(tools),
  apps: many(apps),
  deployments: many(deployments),
  apiKeys: many(apiKeys),
}));

export const toolsRelations = relations(tools, ({ one }) => ({
  project: one(projects, { fields: [tools.projectId], references: [projects.id] }),
}));

export const appsRelations = relations(apps, ({ one }) => ({
  project: one(projects, { fields: [apps.projectId], references: [projects.id] }),
}));

export const deploymentsRelations = relations(deployments, ({ one }) => ({
  project: one(projects, {
    fields: [deployments.projectId],
    references: [projects.id],
  }),
  user: one(users, { fields: [deployments.userId], references: [users.id] }),
}));

export const marketplaceListingsRelations = relations(
  marketplaceListings,
  ({ one, many }) => ({
    project: one(projects, {
      fields: [marketplaceListings.projectId],
      references: [projects.id],
    }),
    author: one(users, {
      fields: [marketplaceListings.authorId],
      references: [users.id],
    }),
  }),
);

export const usageLogsRelations = relations(usageLogs, ({ one }) => ({
  user: one(users, { fields: [usageLogs.userId], references: [users.id] }),
  project: one(projects, {
    fields: [usageLogs.projectId],
    references: [projects.id],
  }),
}));

export const apiKeysRelations = relations(apiKeys, ({ one }) => ({
  project: one(projects, {
    fields: [apiKeys.projectId],
    references: [projects.id],
  }),
  user: one(users, { fields: [apiKeys.userId], references: [users.id] }),
}));
