import { FSWatcher } from 'chokidar';
import * as chokidar from 'chokidar';
import Store from 'electron-store';
import { ServiceError } from '../types';

const store = new Store<{
  watchedPaths: string[];
  excludedPaths: string[];
}>();

class FileSystemService {
  private watchers: Map<string, FSWatcher>;
  private excludedPaths: Set<string>;

  constructor() {
    this.watchers = new Map();
    this.excludedPaths = new Set(store.get('excludedPaths', []));

    // Add example paths
    const examplePaths = [
      'C:/example/llm-only',
      'C:/example/ocr-only',
      'C:/example/both-enabled'
    ];

    // Set initial watched paths
    store.set('watchedPaths', examplePaths);

    // Start watching example paths
    examplePaths.forEach(path => {
      this.watchers.set(path, null); // Add to watchers without actual watcher since paths don't exist
    });
  }

  public async startWatching(dirPath: string): Promise<void> {
    if (this.watchers.has(dirPath)) {
      throw new ServiceError(`Already watching directory: ${dirPath}`);
    }

    const watcher = chokidar.watch(dirPath, {
      ignored: [
        /(^|[\/\\])\../, // Ignore dotfiles
        '**/node_modules/**',
        ...Array.from(this.excludedPaths),
      ],
      persistent: true,
      ignoreInitial: false,
    });

    watcher.on('add', path => {
      console.log(`File ${path} has been added`);
      // TODO: Process file
    });

    watcher.on('change', path => {
      console.log(`File ${path} has been changed`);
      // TODO: Process file changes
    });

    watcher.on('unlink', path => {
      console.log(`File ${path} has been removed`);
      // TODO: Remove from vector store
    });

    this.watchers.set(dirPath, watcher);
    const watchedPaths = store.get('watchedPaths', []);
    if (!watchedPaths.includes(dirPath)) {
      store.set('watchedPaths', [...watchedPaths, dirPath]);
    }
  }

  public async stopWatching(dirPath: string): Promise<void> {
    const watcher = this.watchers.get(dirPath);
    if (!watcher) {
      throw new ServiceError(`Not watching directory: ${dirPath}`);
    }

    await watcher.close();
    this.watchers.delete(dirPath);

    const watchedPaths = store.get('watchedPaths', []);
    store.set('watchedPaths', watchedPaths.filter(p => p !== dirPath));
  }

  public addExcludedPath(path: string): void {
    this.excludedPaths.add(path);
    store.set('excludedPaths', Array.from(this.excludedPaths));

    // Update all watchers with new excluded path
    this.watchers.forEach(watcher => {
      watcher.unwatch(path);
    });
  }

  public getWatchedPaths(): string[] {
    return Array.from(this.watchers.keys());
  }

  public getExcludedPaths(): string[] {
    return Array.from(this.excludedPaths);
  }
}

export const fileSystemService = new FileSystemService();