import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
import type { InferSelectModel, InferInsertModel } from 'drizzle-orm';

export const clients = sqliteTable('clients', {
  id: text('id').primaryKey(),
  parentId: text('parent_id'),
  name: text('name').notNull(),
  industry: text('industry'),
  createdAt: integer('created_at', { mode: 'number' }).notNull(),
});

export const projects = sqliteTable('projects', {
  id: text('id').primaryKey(),
  clientId: text('client_id'),
  name: text('name').notNull(),
  status: text('status', { enum: ['active', 'archived'] }).notNull().default('active'),
  aiSummary: text('ai_summary'),
  createdAt: integer('created_at', { mode: 'number' }).notNull(),
  folderPath: text('folder_path'),
  folderLastScannedAt: integer('folder_last_scanned_at', { mode: 'number' }),
  folderLastScanStatus: text('folder_last_scan_status', {
    enum: ['idle', 'scanning', 'error'],
  }).default('idle'),
  folderTotalFiles: integer('folder_total_files', { mode: 'number' }).notNull().default(0),
});

export const tasks = sqliteTable('tasks', {
  id: text('id').primaryKey(),
  projectId: text('project_id'),
  title: text('title').notNull(),
  description: text('description'),
  status: text('status').notNull().default('todo'),
  priority: text('priority').notNull().default('medium'),
  assignee: text('assignee'),
  dueDate: integer('due_date', { mode: 'number' }),
  estimate: integer('estimate', { mode: 'number' }),
  isAiSuggested: integer('is_ai_suggested', { mode: 'number' }).notNull().default(0),
  createdAt: integer('created_at', { mode: 'number' }).notNull(),
  completedAt: integer('completed_at', { mode: 'number' }),
});

export const timelineEvents = sqliteTable('timeline_events', {
  id: text('id').primaryKey(),
  projectId: text('project_id'),
  title: text('title').notNull(),
  date: integer('date', { mode: 'number' }).notNull(),
  endDate: integer('end_date', { mode: 'number' }),
  type: text('type', { enum: ['milestone', 'checkpoint', 'activity'] }).notNull().default('milestone'),
  isCompleted: integer('is_completed', { mode: 'number' }).notNull().default(0),
  isAiSuggested: integer('is_ai_suggested', { mode: 'number' }).notNull().default(0),
  createdAt: integer('created_at', { mode: 'number' }).notNull(),
  completedAt: integer('completed_at', { mode: 'number' }),
});

export const timelineEventDependencies = sqliteTable('timeline_event_dependencies', {
  id: text('id').primaryKey(),
  fromEventId: text('from_event_id').notNull(),
  toEventId: text('to_event_id').notNull(),
  createdAt: integer('created_at', { mode: 'number' }).notNull(),
});

export const notes = sqliteTable('notes', {
  id: text('id').primaryKey(),
  projectId: text('project_id'),
  title: text('title').notNull(),
  content: text('content').notNull().default(''),
  aiSummary: text('ai_summary'),
  aiSummaryUpdatedAt: integer('ai_summary_updated_at', { mode: 'number' }),
  createdAt: integer('created_at', { mode: 'number' }).notNull(),
  updatedAt: integer('updated_at', { mode: 'number' }).notNull(),
});

export const projectFolderFiles = sqliteTable('project_folder_files', {
  id: text('id').primaryKey(),
  projectId: text('project_id').notNull(),
  relativePath: text('relative_path').notNull(),
  ext: text('ext').notNull(),
  kind: text('kind', { enum: ['text', 'image', 'pdf', 'docx', 'csv', 'skipped', 'error'] }).notNull(),
  sizeBytes: integer('size_bytes', { mode: 'number' }).notNull(),
  mtimeMs: integer('mtime_ms', { mode: 'number' }).notNull(),
  summary: text('summary'),
  summaryUpdatedAt: integer('summary_updated_at', { mode: 'number' }),
});

export type ProjectFolderFile = InferSelectModel<typeof projectFolderFiles>;
export type NewProjectFolderFile = InferInsertModel<typeof projectFolderFiles>;

export const noteEdits = sqliteTable('note_edits', {
  id: text('id').primaryKey(),
  noteId: text('note_id').notNull(),
  type: text('type', { enum: ['append', 'insert', 'replace'] }).notNull(),
  anchorBefore: text('anchor_before'),
  anchorText: text('anchor_text'),
  proposedContent: text('proposed_content').notNull(),
  status: text('status', { enum: ['pending', 'approved', 'rejected'] }).notNull().default('pending'),
  agentId: text('agent_id'),
  runId: text('run_id'),
  reasoning: text('reasoning'),
  createdAt: integer('created_at', { mode: 'number' }).notNull(),
  resolvedAt: integer('resolved_at', { mode: 'number' }),
});

export const taskComments = sqliteTable('task_comments', {
  id: text('id').primaryKey(),
  taskId: text('task_id').notNull(),
  author: text('author').notNull(),
  content: text('content').notNull(),
  createdAt: integer('created_at', { mode: 'number' }).notNull(),
});

export const taskAttachments = sqliteTable('task_attachments', {
  id: text('id').primaryKey(),
  taskId: text('task_id').notNull(),
  filename: text('filename').notNull(),
  mimeType: text('mime_type'),
  sizeBytes: integer('size_bytes', { mode: 'number' }).notNull(),
  storedPath: text('stored_path').notNull(),
  createdAt: integer('created_at', { mode: 'number' }).notNull(),
});

// Inferred TypeScript types — no manual duplication
export type Client = InferSelectModel<typeof clients>;
export type NewClient = InferInsertModel<typeof clients>;

export type Project = InferSelectModel<typeof projects>;
export type NewProject = InferInsertModel<typeof projects>;

export type Task = InferSelectModel<typeof tasks>;
export type NewTask = InferInsertModel<typeof tasks>;

export type Note = InferSelectModel<typeof notes>;
export type NewNote = InferInsertModel<typeof notes>;

export type TaskComment = InferSelectModel<typeof taskComments>;
export type NewTaskComment = InferInsertModel<typeof taskComments>;

export type TaskAttachment = InferSelectModel<typeof taskAttachments>;
export type NewTaskAttachment = InferInsertModel<typeof taskAttachments>;

export type TimelineEvent = InferSelectModel<typeof timelineEvents>;
export type NewTimelineEvent = InferInsertModel<typeof timelineEvents>;

export type TimelineEventDependency = InferSelectModel<typeof timelineEventDependencies>;
export type NewTimelineEventDependency = InferInsertModel<typeof timelineEventDependencies>;

export const taskBriefings = sqliteTable('task_briefings', {
  taskId: text('task_id').primaryKey(),
  briefingMarkdown: text('briefing_markdown').notNull(),
  canvasDraft: text('canvas_draft'),
  canvasKind: text('canvas_kind'),
  citations: text('citations'),
  sourceTaskHash: text('source_task_hash').notNull(),
  generatedAt: integer('generated_at', { mode: 'number' }).notNull(),
  modelVersion: text('model_version'),
});

export type TaskBriefing = InferSelectModel<typeof taskBriefings>;
export type NewTaskBriefing = InferInsertModel<typeof taskBriefings>;

export const taskBriefChats = sqliteTable('task_brief_chats', {
  id: text('id').primaryKey(),
  taskId: text('task_id').notNull(),
  role: text('role', { enum: ['user', 'assistant'] }).notNull(),
  content: text('content').notNull(),
  isError: integer('is_error', { mode: 'boolean' }).notNull().default(false),
  createdAt: integer('created_at', { mode: 'number' }).notNull(),
});

export type TaskBriefChat = InferSelectModel<typeof taskBriefChats>;
export type NewTaskBriefChat = InferInsertModel<typeof taskBriefChats>;

export const agentRuns = sqliteTable('agent_runs', {
  id: text('id').primaryKey(),
  agentId: text('agent_id').notNull(),
  status: text('status', { enum: ['running', 'completed', 'failed', 'partial'] }).notNull().default('running'),
  startedAt: integer('started_at', { mode: 'number' }).notNull(),
  completedAt: integer('completed_at', { mode: 'number' }),
});

export const agentRunActions = sqliteTable('agent_run_actions', {
  id: text('id').primaryKey(),
  runId: text('run_id').notNull(),
  agentId: text('agent_id').notNull(),
  /** 'created' | 'updated' | 'deleted' | 'commented' */
  verb: text('verb').notNull(),
  /** 'task' | 'note' | 'project' | 'timeline' | 'comment' */
  entityType: text('entity_type').notNull(),
  entityId: text('entity_id'),
  entityTitle: text('entity_title'),
  createdAt: integer('created_at', { mode: 'number' }).notNull(),
});

export type AgentRun = InferSelectModel<typeof agentRuns>;
export type NewAgentRun = InferInsertModel<typeof agentRuns>;
export type AgentRunAction = InferSelectModel<typeof agentRunActions>;
export type NewAgentRunAction = InferInsertModel<typeof agentRunActions>;

export type NoteEdit = InferSelectModel<typeof noteEdits>;
export type NewNoteEdit = InferInsertModel<typeof noteEdits>;
