/**
 * Ignite Memory Worker Service
 * Simplified worker for Ignite's memory system
 */

const express = require('express');
const path = require('path');
const fs = require('fs').promises;
const Database = require('better-sqlite3');

class IgniteMemoryWorker {
  constructor(config = {}) {
    this.config = {
      port: config.port || process.env.IGNITE_MEMORY_PORT || 37777,
      host: config.host || 'localhost',
      dataDir: config.dataDir || path.join(process.env.HOME, '.ignite', 'memory'),
      dbPath: config.dbPath || path.join(config.dataDir || path.join(process.env.HOME, '.ignite', 'memory'), 'ignite.db')
    };

    this.app = express();
    this.db = null;
    this.sessions = new Map();
  }

  async initialize() {
    // Ensure data directory exists
    await fs.mkdir(this.config.dataDir, { recursive: true });

    // Initialize database
    this.db = new Database(this.config.dbPath);
    this.db.pragma('journal_mode = WAL');
    this.db.pragma('foreign_keys = ON');

    // Load schemas
    await this.loadSchemas();

    // Setup middleware
    this.app.use(express.json({ limit: '10mb' }));
    this.app.use(express.static(path.join(__dirname, '..', 'ui')));

    // Setup routes
    this.setupRoutes();

    // Start server
    return new Promise((resolve) => {
      this.server = this.app.listen(this.config.port, this.config.host, () => {
        console.log(`Ignite Memory Worker running at http://${this.config.host}:${this.config.port}`);
        resolve();
      });
    });
  }

  async loadSchemas() {
    // Load Claude-Mem base schema
    const baseSchemaPath = path.join(__dirname, '..', 'database', 'sqlite', 'schema.sql');
    const igniteSchemaPath = path.join(__dirname, '..', 'database', 'ignite-schema.sql');

    try {
      // Load and execute Ignite schema
      const igniteSchema = await fs.readFile(igniteSchemaPath, 'utf8');
      this.db.exec(igniteSchema);
      console.log('Database schemas loaded');
    } catch (error) {
      console.error('Failed to load schemas:', error);
      // Continue anyway - tables might already exist
    }
  }

  setupRoutes() {
    // Health check
    this.app.get('/health', (req, res) => {
      res.json({
        status: 'ok',
        uptime: process.uptime(),
        sessions: this.sessions.size
      });
    });

    // Session management
    this.app.post('/api/session/init', (req, res) => {
      const { session_id, project, phase, agent, command, user_prompt } = req.body;

      const sessionId = session_id || `${project}-${Date.now()}`;

      // Create session in database
      const stmt = this.db.prepare(`
        INSERT OR IGNORE INTO projects (name, path, created_at, created_at_epoch, updated_at, updated_at_epoch)
        VALUES (?, ?, datetime('now'), strftime('%s', 'now') * 1000, datetime('now'), strftime('%s', 'now') * 1000)
      `);
      stmt.run(project || 'default', process.cwd());

      // Store session
      this.sessions.set(sessionId, {
        id: sessionId,
        project,
        phase,
        agent,
        command,
        userPrompt: user_prompt,
        startTime: new Date().toISOString()
      });

      res.json({
        id: sessionId,
        status: 'initialized'
      });
    });

    // Search endpoint
    this.app.get('/api/search', (req, res) => {
      const { q, type, project, limit = 20 } = req.query;

      try {
        let query = 'SELECT * FROM agent_runs WHERE 1=1';
        const params = [];

        if (project) {
          query += ' AND project_id = (SELECT id FROM projects WHERE name = ?)';
          params.push(project);
        }

        if (type) {
          query += ' AND agent_type = ?';
          params.push(type);
        }

        if (q) {
          query += ' AND (input_prompt LIKE ? OR output_response LIKE ?)';
          params.push(`%${q}%`, `%${q}%`);
        }

        query += ` ORDER BY created_at_epoch DESC LIMIT ${parseInt(limit)}`;

        const stmt = this.db.prepare(query);
        const results = stmt.all(...params);

        res.json({ results });
      } catch (error) {
        res.status(500).json({ error: error.message });
      }
    });

    // Store observation
    this.app.post('/api/observation', (req, res) => {
      const { session_id, type, title, content, metadata } = req.body;

      try {
        const session = this.sessions.get(session_id);
        if (!session) {
          return res.status(404).json({ error: 'Session not found' });
        }

        // Store in agent_runs table for now
        const stmt = this.db.prepare(`
          INSERT INTO agent_runs (
            session_id, agent_type, input_prompt, output_response,
            observations_captured, created_at, created_at_epoch
          ) VALUES (?, ?, ?, ?, ?, datetime('now'), strftime('%s', 'now') * 1000)
        `);

        const result = stmt.run(
          session_id,
          session.agent || 'unknown',
          title || 'Observation',
          content,
          JSON.stringify({ type, metadata })
        );

        res.json({
          id: result.lastInsertRowid,
          success: true
        });
      } catch (error) {
        res.status(500).json({ error: error.message });
      }
    });

    // Context injection
    this.app.get('/api/context/inject', (req, res) => {
      const { project, phase, max_summaries = 3, max_observations = 20 } = req.query;

      try {
        // Fetch recent relevant data
        const recentRuns = this.db.prepare(`
          SELECT * FROM agent_runs
          WHERE session_id IN (
            SELECT session_id FROM agent_runs
            ORDER BY created_at_epoch DESC
            LIMIT ?
          )
          ORDER BY created_at_epoch DESC
        `).all(max_observations);

        const context = {
          observations: recentRuns.slice(0, max_observations),
          summaries: [], // TODO: Implement summaries
          patterns: []   // TODO: Implement pattern detection
        };

        res.json(context);
      } catch (error) {
        res.status(500).json({ error: error.message });
      }
    });

    // Summary generation
    this.app.post('/api/summary', (req, res) => {
      const { session_id, content } = req.body;

      // For now, just store the summary request
      res.json({
        success: true,
        summary: 'Summary generation pending implementation'
      });
    });

    // Similar work finder
    this.app.post('/api/similar', (req, res) => {
      const { reference, project, limit = 10 } = req.body;

      try {
        // Simple text similarity search for now
        const results = this.db.prepare(`
          SELECT * FROM agent_runs
          WHERE input_prompt LIKE ? OR output_response LIKE ?
          ORDER BY created_at_epoch DESC
          LIMIT ?
        `).all(`%${reference}%`, `%${reference}%`, limit);

        res.json({ results });
      } catch (error) {
        res.status(500).json({ error: error.message });
      }
    });

    // Project insights
    this.app.get('/api/projects/:project/insights', (req, res) => {
      const { project } = req.params;

      try {
        // Get project statistics
        const stats = this.db.prepare(`
          SELECT
            COUNT(*) as total_runs,
            COUNT(DISTINCT agent_type) as agent_types,
            COUNT(DISTINCT session_id) as sessions
          FROM agent_runs
          WHERE session_id IN (
            SELECT session_id FROM agent_runs WHERE session_id LIKE ?
          )
        `).get(`${project}-%`);

        res.json({
          insights: {
            stats,
            patterns: [],      // TODO: Implement pattern detection
            preferences: [],   // TODO: Implement preference learning
            antipatterns: []   // TODO: Implement antipattern detection
          }
        });
      } catch (error) {
        res.status(500).json({ error: error.message });
      }
    });

    // Session close
    this.app.post('/api/session/:sessionId/close', (req, res) => {
      const { sessionId } = req.params;

      if (this.sessions.has(sessionId)) {
        this.sessions.delete(sessionId);
        res.json({ success: true });
      } else {
        res.status(404).json({ error: 'Session not found' });
      }
    });

    // Serve UI at root
    this.app.get('/', (req, res) => {
      res.sendFile(path.join(__dirname, '..', 'ui', 'index.html'));
    });
  }

  async shutdown() {
    if (this.server) {
      return new Promise((resolve) => {
        this.server.close(() => {
          if (this.db) {
            this.db.close();
          }
          resolve();
        });
      });
    }
  }
}

// Start worker if run directly
if (require.main === module) {
  const worker = new IgniteMemoryWorker();

  worker.initialize().catch((error) => {
    console.error('Failed to start worker:', error);
    process.exit(1);
  });

  // Graceful shutdown
  process.on('SIGTERM', async () => {
    console.log('Shutting down worker...');
    await worker.shutdown();
    process.exit(0);
  });

  process.on('SIGINT', async () => {
    console.log('Shutting down worker...');
    await worker.shutdown();
    process.exit(0);
  });
}

module.exports = IgniteMemoryWorker;