import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
import { WSBridgeClient } from './ws-client';

export interface BrainWatcherContext {
    logToFile: (msg: string) => void;
    wsBridge: WSBridgeClient;
    projectName: string;
}

export class BrainWatcher {
    private brainDir: string;
    private ctx: BrainWatcherContext;
    private currentSessionId: string = '';
    private watcher: fs.FSWatcher | null = null;
    private lastEventTimes: Map<string, number> = new Map();

    constructor(ctx: BrainWatcherContext) {
        this.ctx = ctx;
        // The bridgePath is ~/.gemini/antigravity/bridge, so brain is sibling
        this.brainDir = path.join(os.homedir(), '.gemini', 'antigravity', 'brain');
    }

    public updateSession(sessionId: string) {
        if (!sessionId || this.currentSessionId === sessionId) {
            return;
        }
        this.currentSessionId = sessionId;
        this.startWatching(sessionId);
    }

    private startWatching(sessionId: string) {
        this.stop();

        const sessionDir = path.join(this.brainDir, sessionId);
        if (!fs.existsSync(sessionDir)) {
            // It might not be created yet, poll gently
            setTimeout(() => this.startWatching(sessionId), 2000);
            return;
        }

        try {
            this.watcher = fs.watch(sessionDir, { persistent: false }, (eventType, filename) => {
                if (!filename || !filename.endsWith('.md')) return;

                // Dedup rapid events
                const now = Date.now();
                const last = this.lastEventTimes.get(filename) || 0;
                if (now - last < 500) return; // 500ms debounce
                this.lastEventTimes.set(filename, now);

                this.handleFileChange(sessionDir, filename, eventType);
            });
            this.ctx.logToFile(`[BRAIN-WATCHER] Started watching session: ${sessionId.substring(0, 8)}`);
        } catch (e: any) {
            this.ctx.logToFile(`[BRAIN-WATCHER] Failed to watch ${sessionId}: ${e.message}`);
        }
    }

    private handleFileChange(dir: string, filename: string, rawEventType: string) {
        const filePath = path.join(dir, filename);
        let content = '';
        let eventType = 'file_changed';

        try {
            if (fs.existsSync(filePath)) {
                content = fs.readFileSync(filePath, 'utf-8');
            } else {
                eventType = 'file_deleted';
            }
        } catch (e) {
            // File might be locked or deleted during read
            return;
        }

        if (this.ctx.wsBridge && this.ctx.wsBridge.isConnected()) {
            this.ctx.wsBridge.sendBrainEvent({
                event_type: eventType,
                conversation_id: this.currentSessionId,
                file_name: filename,
                content: content,
                timestamp: Date.now() / 1000,
                project_name: this.ctx.projectName,
            });
            this.ctx.logToFile(`[BRAIN-WATCHER] Sent ${eventType} for ${filename}`);
        }
    }

    public stop() {
        if (this.watcher) {
            this.watcher.close();
            this.watcher = null;
        }
    }
}
