/**
 * Git Handler
 * Handles git file watching and client notifications for the sync server.
 */

import { watch, type FSWatcher } from 'fs'
import { join } from 'path'

// Git watcher state
let gitWatcher: FSWatcher | null = null
let debounceTimer: ReturnType<typeof setTimeout> | null = null
const DEBOUNCE_MS = 300

// Files to ignore
const IGNORE_PATTERNS = [
  'FETCH_HEAD',
  'gc.log',
  '.lock',
  'COMMIT_EDITMSG',
  'ORIG_HEAD',
  'gitk.cache',
  'sourcetreeconfig',
  '.DS_Store',
  'fsmonitor',
  'packed-refs'
]

/**
 * Set up git directory watcher
 */
export function setupGitWatcher(workingDir: string, broadcast: (message: string, filter?: (ws: any) => boolean) => void) {
  const gitDir = join(workingDir, '.git')

  try {
    gitWatcher = watch(gitDir, { recursive: true }, (_, filename) => {
      if (!filename) return

      // Ignore noisy files
      if (IGNORE_PATTERNS.some(p => filename.includes(p))) return

      // Only meaningful changes
      const isRelevant =
        filename.includes('refs/') ||
        filename === 'HEAD' ||
        filename === 'index' ||
        filename.includes('objects/')

      if (!isRelevant) return

      // Debounce
      if (debounceTimer) clearTimeout(debounceTimer)
      debounceTimer = setTimeout(() => {
        console.log(`[Git] Change: ${filename}`)
        broadcast(JSON.stringify({
          type: 'git-change',
          timestamp: Date.now()
        }))
      }, DEBOUNCE_MS)
    })

    console.log(`[Git] Watching ${gitDir}`)
  } catch (e: any) {
    console.error(`[Git] Watch failed: ${e.message}`)
  }
}

/**
 * Handle new git client connection
 */
export function handleGitClient(ws: any) {
  ws.send(JSON.stringify({ type: 'connected' }))
}

/**
 * Cleanup git watcher
 */
export function cleanupGitWatcher() {
  if (gitWatcher) {
    gitWatcher.close()
    gitWatcher = null
  }
  if (debounceTimer) {
    clearTimeout(debounceTimer)
    debounceTimer = null
  }
}
