import express from "express";
import { AnalyticsService } from "../core/analytics-service.js";
import { WebSocketServer, WebSocket } from "ws";
class AnalyticsAPI {
  router;
  analyticsService;
  wss;
  constructor(projectPath) {
    this.router = express.Router();
    this.analyticsService = new AnalyticsService(projectPath);
    this.setupRoutes();
  }
  setupRoutes() {
    this.router.use(express.json());
    this.router.get("/metrics", this.getMetrics.bind(this));
    this.router.get("/tasks", this.getTasks.bind(this));
    this.router.get("/team/:userId", this.getTeamMetrics.bind(this));
    this.router.post("/tasks", this.addTask.bind(this));
    this.router.put("/tasks/:taskId", this.updateTask.bind(this));
    this.router.post("/sync", this.syncLinear.bind(this));
    this.router.get("/export", this.exportMetrics.bind(this));
  }
  async getMetrics(req, res) {
    try {
      const query = this.parseQuery(req.query);
      const dashboardState = await this.analyticsService.getDashboardState(query);
      res.json({
        success: true,
        data: {
          metrics: dashboardState.metrics,
          lastUpdated: dashboardState.lastUpdated
        }
      });
    } catch (error) {
      this.handleError(res, error);
    }
  }
  async getTasks(req, res) {
    try {
      const query = this.parseQuery(req.query);
      const dashboardState = await this.analyticsService.getDashboardState(query);
      res.json({
        success: true,
        data: {
          tasks: dashboardState.recentTasks,
          total: dashboardState.metrics.totalTasks
        }
      });
    } catch (error) {
      this.handleError(res, error);
    }
  }
  async getTeamMetrics(req, res) {
    try {
      const { userId } = req.params;
      const query = this.parseQuery(req.query);
      if (userId === "all") {
        const dashboardState = await this.analyticsService.getDashboardState(query);
        res.json({
          success: true,
          data: dashboardState.teamMetrics
        });
      } else {
        const dashboardState = await this.analyticsService.getDashboardState({
          ...query,
          userIds: [userId]
        });
        const userMetrics = dashboardState.teamMetrics.find(
          (m) => m.userId === userId
        );
        if (!userMetrics) {
          res.status(404).json({
            success: false,
            error: "User metrics not found"
          });
          return;
        }
        res.json({
          success: true,
          data: userMetrics
        });
      }
    } catch (error) {
      this.handleError(res, error);
    }
  }
  async addTask(req, res) {
    try {
      const task = {
        ...req.body,
        createdAt: new Date(req.body.createdAt || Date.now()),
        completedAt: req.body.completedAt ? new Date(req.body.completedAt) : void 0
      };
      await this.analyticsService.addTask(task);
      res.status(201).json({
        success: true,
        message: "Task added successfully"
      });
    } catch (error) {
      this.handleError(res, error);
    }
  }
  async updateTask(req, res) {
    try {
      const { taskId } = req.params;
      const updates = req.body;
      if (updates.completedAt) {
        updates.completedAt = new Date(updates.completedAt);
      }
      await this.analyticsService.updateTask(taskId, updates);
      res.json({
        success: true,
        message: "Task updated successfully"
      });
    } catch (error) {
      this.handleError(res, error);
    }
  }
  async syncLinear(req, res) {
    try {
      await this.analyticsService.syncLinearTasks();
      res.json({
        success: true,
        message: "Linear tasks synced successfully"
      });
    } catch (error) {
      this.handleError(res, error);
    }
  }
  async exportMetrics(req, res) {
    try {
      const query = this.parseQuery(req.query);
      const format = req.query.format || "json";
      const dashboardState = await this.analyticsService.getDashboardState(query);
      if (format === "csv") {
        const csv = this.convertToCSV(dashboardState);
        res.setHeader("Content-Type", "text/csv");
        res.setHeader(
          "Content-Disposition",
          'attachment; filename="analytics-export.csv"'
        );
        res.send(csv);
      } else {
        res.json({
          success: true,
          data: dashboardState
        });
      }
    } catch (error) {
      this.handleError(res, error);
    }
  }
  parseQuery(query) {
    const result = {};
    if (query.start && query.end) {
      result.timeRange = {
        start: new Date(query.start),
        end: new Date(query.end),
        preset: query.preset
      };
    } else if (query.preset) {
      result.timeRange = this.getPresetTimeRange(query.preset);
    }
    if (query.users) {
      result.userIds = Array.isArray(query.users) ? query.users : [query.users];
    }
    if (query.states) {
      result.states = Array.isArray(query.states) ? query.states : [query.states];
    }
    if (query.priorities) {
      result.priorities = Array.isArray(query.priorities) ? query.priorities : [query.priorities];
    }
    if (query.labels) {
      result.labels = Array.isArray(query.labels) ? query.labels : [query.labels];
    }
    if (query.limit) {
      result.limit = parseInt(query.limit);
    }
    if (query.offset) {
      result.offset = parseInt(query.offset);
    }
    return result;
  }
  getPresetTimeRange(preset) {
    const end = /* @__PURE__ */ new Date();
    const start = /* @__PURE__ */ new Date();
    switch (preset) {
      case "today":
        start.setHours(0, 0, 0, 0);
        break;
      case "7d":
        start.setDate(start.getDate() - 7);
        break;
      case "30d":
        start.setDate(start.getDate() - 30);
        break;
      case "90d":
        start.setDate(start.getDate() - 90);
        break;
      default:
        start.setDate(start.getDate() - 7);
    }
    return { start, end, preset };
  }
  convertToCSV(dashboardState) {
    const tasks = dashboardState.recentTasks;
    if (!tasks || tasks.length === 0) return "No data";
    const headers = Object.keys(tasks[0]).join(",");
    const rows = tasks.map(
      (task) => Object.values(task).map((v) => typeof v === "object" ? JSON.stringify(v) : v).join(",")
    );
    return [headers, ...rows].join("\n");
  }
  handleError(res, error) {
    console.error("Analytics API error:", error);
    res.status(500).json({
      success: false,
      error: error.message || "Internal server error"
    });
  }
  setupWebSocket(server) {
    this.wss = new WebSocketServer({
      server,
      path: "/ws/analytics"
    });
    this.wss.on("connection", (ws) => {
      console.log("WebSocket client connected to analytics");
      const unsubscribe = this.analyticsService.subscribeToUpdates((state) => {
        if (ws.readyState === WebSocket.OPEN) {
          ws.send(
            JSON.stringify({
              type: "update",
              data: state
            })
          );
        }
      });
      ws.on("message", async (message) => {
        try {
          const data = JSON.parse(message);
          if (data.type === "subscribe") {
            const query = this.parseQuery(data.query || {});
            const state = await this.analyticsService.getDashboardState(query);
            ws.send(
              JSON.stringify({
                type: "initial",
                data: state
              })
            );
          }
        } catch (error) {
          ws.send(
            JSON.stringify({
              type: "error",
              error: "Invalid message format"
            })
          );
        }
      });
      ws.on("close", () => {
        unsubscribe();
        console.log("WebSocket client disconnected");
      });
      ws.on("error", (error) => {
        console.error("WebSocket error:", error);
        unsubscribe();
      });
    });
  }
  getRouter() {
    return this.router;
  }
  close() {
    this.analyticsService.close();
    if (this.wss) {
      this.wss.close();
    }
  }
}
export {
  AnalyticsAPI
};
//# sourceMappingURL=analytics-api.js.map
