const express = require('express');
const cors = require('cors');
const path = require('path');

const db = require('./src/database');
const { getDataDir } = require('./src/config/runtime');
const cloudClientConfig = require('./src/config/cloud-client');
const { createAIService } = require('./src/services/ai');
const { createMemoryService } = require('./src/services/memory');
const { createSkillsService } = require('./src/services/skills');
const { createAgentsService } = require('./src/services/agents');
const { createBriefingService } = require('./src/services/briefing');
const { createWorkflowHistoryService } = require('./src/services/workflow-history');
const { createMetricsAutomationService } = require('./src/services/metrics-automation');
const { createProductionService } = require('./src/services/production');
const { createQAService } = require('./src/services/qa');
const { createClientSuccessService } = require('./src/services/client-success');
const { createEmbeddedRuntimeService } = require('./src/services/embedded-runtime');
const invoices = require('./src/services/invoices');
const { registerWorkspaceRoutes } = require('./src/routes/workspace');
const { registerAIRoutes } = require('./src/routes/ai');
const { registerOperationsRoutes } = require('./src/routes/operations');
const { registerPortalAndMemoryRoutes } = require('./src/routes/portal-memory');
const { registerProductionRoutes } = require('./src/routes/production');
const { registerQARoutes } = require('./src/routes/qa');
const { registerClientSuccessRoutes } = require('./src/routes/client-success');
const { registerSkillsRoutes } = require('./src/routes/skills');
const { registerDocsRoutes } = require('./src/routes/docs');
const { registerHistoryRoutes } = require('./src/routes/history');
const { registerAgentRoutes } = require('./src/routes/agents');
const { registerPublicConfigRoutes } = require('./src/routes/public-config');
const { registerLocalRuntimeRoutes } = require('./src/routes/local-runtime');

const app = express();
const rootDir = __dirname;
const dataDir = getDataDir();

app.use(cors());
app.use(express.json({ limit: '12mb' }));
app.use((req, res, next) => {
  const ext = path.extname(req.path).toLowerCase();
  const noCacheExts = new Set(['.html', '.css', '.js']);

  if (req.path === '/' || req.path === '/portal' || req.path === '/docs' || noCacheExts.has(ext)) {
    res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
    res.setHeader('Pragma', 'no-cache');
    res.setHeader('Expires', '0');
    res.setHeader('Surrogate-Control', 'no-store');
  }

  next();
});

app.get('/favicon.ico', (_req, res) => {
  res.status(204).end();
});

app.use(express.static(path.join(rootDir, 'public'), {
  etag: false,
  lastModified: false,
  maxAge: 0
}));

const embeddedRuntime = createEmbeddedRuntimeService();
const ai = createAIService({ db, embeddedRuntime });
const memory = createMemoryService({ db, embeddedRuntime });
const skills = createSkillsService({ db, memory });
const workflowHistory = createWorkflowHistoryService({ db });
const metricsAutomation = createMetricsAutomationService({ db, workflowHistory });
const briefing = createBriefingService({ db, callAI: ai.callAI });
const agents = createAgentsService({ db, ai, memory, skills, workflowHistory, metricsAutomation, briefing });
const production = createProductionService({ db });
const qa = createQAService({ db });
const clientSuccess = createClientSuccessService({ db });

const deps = { db, ai, memory, skills, agents, briefing, invoices, workflowHistory, metricsAutomation, production, qa, clientSuccess, embeddedRuntime, rootDir, dataDir };
registerPublicConfigRoutes(app, { cloudClientConfig });
registerLocalRuntimeRoutes(app, deps);
registerWorkspaceRoutes(app, deps);
registerAIRoutes(app, deps);
registerOperationsRoutes(app, deps);
registerPortalAndMemoryRoutes(app, { ...deps, rootDir });
registerProductionRoutes(app, deps);
registerQARoutes(app, deps);
registerClientSuccessRoutes(app, deps);
registerSkillsRoutes(app, deps);
registerDocsRoutes(app, deps);
registerHistoryRoutes(app, deps);
registerAgentRoutes(app, deps);

const PORT = process.env.PORT || 3005;
app.listen(PORT, '0.0.0.0', () => {
  console.log(`Server running on port ${PORT}`);

  setTimeout(async () => {
    const memResult = await memory.backfillEmbeddings();
    if (memResult.total > 0 && memResult.done > 0) console.log(`[RAG] Memory backfill: ${memResult.done}/${memResult.total}`);
    const skillResult = await skills.backfillSkillEmbeddings();
    if (skillResult.total > 0 && skillResult.done > 0) console.log(`[RAG] Skills backfill: ${skillResult.done}/${skillResult.total}`);
  }, 2000);

  setInterval(async () => {
    try {
      const results = await agents.runDueScheduledAgents(new Date());
      if (results.length) {
        briefing.invalidateBriefingCache();
        console.log(`[Agents] Scheduled cycle complete. ${results.length} agent(s) ran.`);
      }
    } catch (error) {
      console.error('[Agents] Scheduled cycle failed:', error.message);
    }
  }, 60000);
});
