import Dexie, { type Table } from 'dexie'
import type { Workspace, NoteFile, EditorState } from './types'

/**
 * Simplified database for Notes workspace
 * - One workspace per API (not multiple projects)
 * - Notes are files for brainstorming (code, diagrams, markdown)
 */
class NotesDatabase extends Dexie {
  workspaces!: Table<Workspace>
  notes!: Table<NoteFile>
  editorStates!: Table<EditorState>

  constructor() {
    super('brainfish-notes')
    
    this.version(1).stores({
      // Single workspace per API
      workspaces: 'id, apiSpecUrl, updatedAt',
      
      // Notes/files in workspace
      notes: 'id, workspaceId, [workspaceId+path], updatedAt',
      
      // Editor state per workspace
      editorStates: 'workspaceId',
    })
  }
}

// Singleton database instance
export const db = new NotesDatabase()

/**
 * Generate a workspace ID from API spec URL
 */
export function getWorkspaceId(apiSpecUrl: string): string {
  // Simple hash for consistent ID
  let hash = 0
  for (let i = 0; i < apiSpecUrl.length; i++) {
    const char = apiSpecUrl.charCodeAt(i)
    hash = ((hash << 5) - hash) + char
    hash = hash & hash // Convert to 32-bit integer
  }
  return `ws-${Math.abs(hash).toString(16)}`
}

/**
 * Database operations - simplified for notes workspace
 */
export const dbOperations = {
  // Workspace operations (auto-created, one per API)
  
  async getOrCreateWorkspace(apiSpecUrl: string, name: string): Promise<Workspace> {
    const id = getWorkspaceId(apiSpecUrl)
    
    let workspace = await db.workspaces.get(id)
    
    if (!workspace) {
      workspace = {
        id,
        name,
        apiSpecUrl,
        createdAt: new Date(),
        updatedAt: new Date(),
      }
      await db.workspaces.add(workspace)
    }
    
    return workspace
  },

  async getWorkspace(id: string): Promise<Workspace | undefined> {
    return db.workspaces.get(id)
  },

  async updateWorkspace(id: string, updates: Partial<Workspace>): Promise<void> {
    await db.workspaces.update(id, {
      ...updates,
      updatedAt: new Date(),
    })
  },

  // Note/file operations
  
  async createNote(workspaceId: string, path: string, content: string = ''): Promise<NoteFile> {
    const note: NoteFile = {
      id: crypto.randomUUID(),
      workspaceId,
      path,
      content,
      createdAt: new Date(),
      updatedAt: new Date(),
    }
    await db.notes.add(note)
    
    // Update workspace timestamp
    await db.workspaces.update(workspaceId, { updatedAt: new Date() })
    
    return note
  },

  async getNote(workspaceId: string, path: string): Promise<NoteFile | undefined> {
    return db.notes
      .where('[workspaceId+path]')
      .equals([workspaceId, path])
      .first()
  },

  async listNotes(workspaceId: string): Promise<NoteFile[]> {
    return db.notes
      .where('workspaceId')
      .equals(workspaceId)
      .toArray()
  },

  async updateNote(workspaceId: string, path: string, content: string): Promise<void> {
    await db.notes
      .where('[workspaceId+path]')
      .equals([workspaceId, path])
      .modify({
        content,
        updatedAt: new Date(),
      })
    
    await db.workspaces.update(workspaceId, { updatedAt: new Date() })
  },

  async deleteNote(workspaceId: string, path: string): Promise<void> {
    await db.notes
      .where('[workspaceId+path]')
      .equals([workspaceId, path])
      .delete()
    
    await db.workspaces.update(workspaceId, { updatedAt: new Date() })
  },

  async renameNote(workspaceId: string, oldPath: string, newPath: string): Promise<void> {
    await db.notes
      .where('[workspaceId+path]')
      .equals([workspaceId, oldPath])
      .modify({
        path: newPath,
        updatedAt: new Date(),
      })
    
    await db.workspaces.update(workspaceId, { updatedAt: new Date() })
  },

  // Editor state operations
  
  async getEditorState(workspaceId: string): Promise<EditorState | undefined> {
    return db.editorStates.get(workspaceId)
  },

  async saveEditorState(state: EditorState): Promise<void> {
    await db.editorStates.put(state)
  },

  // Clear all notes in workspace (reset)
  async clearWorkspace(workspaceId: string): Promise<void> {
    await db.notes.where('workspaceId').equals(workspaceId).delete()
    await db.editorStates.delete(workspaceId)
  },
}
