import { blob, integer, real, sqliteTable, text } from 'drizzle-orm/sqlite-core';

// ---------------------------------------------------------------------------
// repositories
// ---------------------------------------------------------------------------
export const repositories = sqliteTable('repositories', {
	id: text('id').primaryKey(), // e.g. "/facebook/react" or "/local/my-sdk"
	title: text('title').notNull(),
	description: text('description'),
	source: text('source', { enum: ['github', 'local'] }).notNull(),
	sourceUrl: text('source_url').notNull(), // GitHub URL or absolute local path
	branch: text('branch').default('main'),
	state: text('state', {
		enum: ['pending', 'indexing', 'indexed', 'error']
	})
		.notNull()
		.default('pending'),
	totalSnippets: integer('total_snippets').default(0),
	totalTokens: integer('total_tokens').default(0),
	trustScore: real('trust_score').default(0), // 0.0–10.0
	benchmarkScore: real('benchmark_score').default(0), // 0.0–100.0; reserved for future quality metrics
	stars: integer('stars'),
	// TODO: encrypt at rest in production; stored as plaintext for v1
	githubToken: text('github_token'),
	lastIndexedAt: integer('last_indexed_at', { mode: 'timestamp' }),
	createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
	updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull()
});

// ---------------------------------------------------------------------------
// repository_versions
// ---------------------------------------------------------------------------
export const repositoryVersions = sqliteTable('repository_versions', {
	id: text('id').primaryKey(), // e.g. "/facebook/react/v18.3.0"
	repositoryId: text('repository_id')
		.notNull()
		.references(() => repositories.id, { onDelete: 'cascade' }),
	tag: text('tag').notNull(), // git tag or branch name
	title: text('title'),
	state: text('state', {
		enum: ['pending', 'indexing', 'indexed', 'error']
	})
		.notNull()
		.default('pending'),
	totalSnippets: integer('total_snippets').default(0),
	indexedAt: integer('indexed_at', { mode: 'timestamp' }),
	createdAt: integer('created_at', { mode: 'timestamp' }).notNull()
});

// ---------------------------------------------------------------------------
// documents
// ---------------------------------------------------------------------------
export const documents = sqliteTable('documents', {
	id: text('id').primaryKey(), // UUID
	repositoryId: text('repository_id')
		.notNull()
		.references(() => repositories.id, { onDelete: 'cascade' }),
	versionId: text('version_id').references(() => repositoryVersions.id, { onDelete: 'cascade' }),
	filePath: text('file_path').notNull(), // relative path within repo
	title: text('title'),
	language: text('language'), // e.g. "typescript", "markdown"
	tokenCount: integer('token_count').default(0),
	checksum: text('checksum').notNull(), // SHA-256 of file content
	indexedAt: integer('indexed_at', { mode: 'timestamp' }).notNull()
});

// ---------------------------------------------------------------------------
// snippets
// ---------------------------------------------------------------------------
export const snippets = sqliteTable('snippets', {
	id: text('id').primaryKey(), // UUID
	documentId: text('document_id')
		.notNull()
		.references(() => documents.id, { onDelete: 'cascade' }),
	repositoryId: text('repository_id')
		.notNull()
		.references(() => repositories.id, { onDelete: 'cascade' }),
	versionId: text('version_id').references(() => repositoryVersions.id, { onDelete: 'cascade' }),
	type: text('type', { enum: ['code', 'info'] }).notNull(),
	title: text('title'),
	content: text('content').notNull(), // searchable text / code
	language: text('language'),
	breadcrumb: text('breadcrumb'), // e.g. "Installation > Getting Started"
	tokenCount: integer('token_count').default(0),
	createdAt: integer('created_at', { mode: 'timestamp' }).notNull()
});

// ---------------------------------------------------------------------------
// snippet_embeddings
// ---------------------------------------------------------------------------
export const snippetEmbeddings = sqliteTable('snippet_embeddings', {
	snippetId: text('snippet_id')
		.primaryKey()
		.references(() => snippets.id, { onDelete: 'cascade' }),
	model: text('model').notNull(), // embedding model identifier
	dimensions: integer('dimensions').notNull(),
	embedding: blob('embedding').notNull(), // Float32Array as binary blob
	createdAt: integer('created_at', { mode: 'timestamp' }).notNull()
});

// ---------------------------------------------------------------------------
// indexing_jobs
// ---------------------------------------------------------------------------
export const indexingJobs = sqliteTable('indexing_jobs', {
	id: text('id').primaryKey(), // UUID
	repositoryId: text('repository_id')
		.notNull()
		.references(() => repositories.id, { onDelete: 'cascade' }),
	versionId: text('version_id'),
	status: text('status', {
		enum: ['queued', 'running', 'done', 'failed']
	})
		.notNull()
		.default('queued'),
	progress: integer('progress').default(0), // 0–100
	totalFiles: integer('total_files').default(0),
	processedFiles: integer('processed_files').default(0),
	error: text('error'),
	startedAt: integer('started_at', { mode: 'timestamp' }),
	completedAt: integer('completed_at', { mode: 'timestamp' }),
	createdAt: integer('created_at', { mode: 'timestamp' }).notNull()
});

// ---------------------------------------------------------------------------
// repository_configs
// ---------------------------------------------------------------------------
export const repositoryConfigs = sqliteTable('repository_configs', {
	repositoryId: text('repository_id')
		.primaryKey()
		.references(() => repositories.id, { onDelete: 'cascade' }),
	projectTitle: text('project_title'),
	description: text('description'),
	folders: text('folders', { mode: 'json' }).$type<string[]>(),
	excludeFolders: text('exclude_folders', { mode: 'json' }).$type<string[]>(),
	excludeFiles: text('exclude_files', { mode: 'json' }).$type<string[]>(),
	rules: text('rules', { mode: 'json' }).$type<string[]>(),
	previousVersions: text('previous_versions', { mode: 'json' }).$type<
		{ tag: string; title: string }[]
	>(),
	updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull()
});

// ---------------------------------------------------------------------------
// settings
// ---------------------------------------------------------------------------
export const settings = sqliteTable('settings', {
	key: text('key').primaryKey(),
	value: text('value', { mode: 'json' }),
	updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull()
});

// ---------------------------------------------------------------------------
// Inferred TypeScript types
// ---------------------------------------------------------------------------
export type Repository = typeof repositories.$inferSelect;
export type NewRepository = typeof repositories.$inferInsert;

export type RepositoryVersion = typeof repositoryVersions.$inferSelect;
export type NewRepositoryVersion = typeof repositoryVersions.$inferInsert;

export type Document = typeof documents.$inferSelect;
export type NewDocument = typeof documents.$inferInsert;

export type Snippet = typeof snippets.$inferSelect;
export type NewSnippet = typeof snippets.$inferInsert;

export type SnippetEmbedding = typeof snippetEmbeddings.$inferSelect;
export type NewSnippetEmbedding = typeof snippetEmbeddings.$inferInsert;

export type IndexingJob = typeof indexingJobs.$inferSelect;
export type NewIndexingJob = typeof indexingJobs.$inferInsert;

export type RepositoryConfig = typeof repositoryConfigs.$inferSelect;
export type NewRepositoryConfig = typeof repositoryConfigs.$inferInsert;

export type Settings = typeof settings.$inferSelect;
export type NewSettings = typeof settings.$inferInsert;
