import chokidar from 'chokidar';
import fs from 'node:fs';
import path from 'node:path';
import { diffState } from './state-parser.js';
export function createFileWatcher(squadsDir, onEvent) {
    const lastStates = new Map();
    const debounceTimers = new Map();
    // Watch entire squadsDir (chokidar v4 on macOS doesn't support glob patterns well)
    const watcher = chokidar.watch(squadsDir, {
        ignoreInitial: true,
        depth: 5, // supports setor/grupo/sessao/code/state.json (4 levels below squadsDir)
    });
    function handleStateChange(filePath) {
        const squadName = path.basename(path.dirname(filePath));
        // Debounce per squad
        clearTimeout(debounceTimers.get(squadName));
        debounceTimers.set(squadName, setTimeout(() => {
            if (!fs.existsSync(filePath)) {
                lastStates.delete(squadName);
                onEvent({ type: 'squad:inactive', squadName });
                return;
            }
            try {
                const raw = fs.readFileSync(filePath, 'utf-8');
                const state = JSON.parse(raw);
                const prev = lastStates.get(squadName) || null;
                const events = diffState(squadName, prev, state);
                lastStates.set(squadName, state);
                for (const event of events) {
                    onEvent(event);
                }
            }
            catch {
                // Invalid JSON — skip, will retry on next write
            }
        }, 50));
    }
    function isStateJson(filePath) {
        return path.basename(filePath) === 'state.json';
    }
    function isSquadYaml(filePath) {
        return path.basename(filePath) === 'squad.yaml';
    }
    function isUiJson(filePath) {
        return path.basename(filePath) === 'ui.json';
    }
    function handleUiJson(filePath) {
        const squadName = path.basename(path.dirname(filePath));
        try {
            const raw = fs.readFileSync(filePath, 'utf-8');
            const update = JSON.parse(raw);
            if (Array.isArray(update.components)) {
                onEvent({
                    type: 'a2ui:update',
                    squadName,
                    components: update.components,
                });
            }
        }
        catch {
            // Invalid JSON — skip
        }
    }
    watcher.on('change', (filePath) => {
        if (isStateJson(filePath)) {
            handleStateChange(filePath);
        }
        if (isSquadYaml(filePath)) {
            const squadName = path.basename(path.dirname(filePath));
            onEvent({ type: 'squad:config_changed', squadName });
        }
        if (isUiJson(filePath)) {
            handleUiJson(filePath);
        }
    });
    watcher.on('add', (filePath) => {
        if (isStateJson(filePath)) {
            handleStateChange(filePath);
        }
        if (isSquadYaml(filePath)) {
            const squadName = path.basename(path.dirname(filePath));
            onEvent({ type: 'squad:config_changed', squadName });
        }
        if (isUiJson(filePath)) {
            handleUiJson(filePath);
        }
    });
    watcher.on('unlink', (filePath) => {
        if (isStateJson(filePath)) {
            const squadName = path.basename(path.dirname(filePath));
            lastStates.delete(squadName);
            onEvent({ type: 'squad:inactive', squadName });
        }
    });
    const ready = new Promise((resolve) => {
        watcher.on('ready', resolve);
    });
    const stop = () => {
        for (const timer of debounceTimers.values())
            clearTimeout(timer);
        watcher.close();
    };
    return { ready, stop };
}
//# sourceMappingURL=file-watcher.js.map