import { fileURLToPath as __fileURLToPath } from 'url';
import { dirname as __pathDirname } from 'path';
const __filename = __fileURLToPath(import.meta.url);
const __dirname = __pathDirname(__filename);
import { createHmac } from "crypto";
import { LinearSyncEngine } from "./sync.js";
import { LinearAuthManager } from "./auth.js";
import { logger } from "../../core/monitoring/logger.js";
function getEnv(key, defaultValue) {
  const value = process.env[key];
  if (value === void 0) {
    if (defaultValue !== void 0) return defaultValue;
    throw new Error(`Environment variable ${key} is required`);
  }
  return value;
}
function getOptionalEnv(key) {
  return process.env[key];
}
class LinearWebhookHandler {
  taskStore;
  syncEngine = null;
  webhookSecret;
  constructor(taskStore, webhookSecret) {
    this.taskStore = taskStore;
    this.webhookSecret = webhookSecret;
    if (process.env["LINEAR_API_KEY"]) {
      const authManager = new LinearAuthManager();
      this.syncEngine = new LinearSyncEngine(taskStore, authManager, {
        enabled: true,
        direction: "from_linear",
        autoSync: false,
        conflictResolution: "linear_wins"
      });
    }
  }
  /**
   * Verify webhook signature
   */
  verifySignature(payload, signature) {
    const hmac = createHmac("sha256", this.webhookSecret);
    hmac.update(payload);
    const expectedSignature = hmac.digest("hex");
    return signature === expectedSignature;
  }
  /**
   * Handle incoming webhook from Linear
   */
  async handleWebhook(req, res) {
    try {
      const rawBody = JSON.stringify(req.body);
      const signature = req.headers["linear-signature"];
      if (!this.verifySignature(rawBody, signature)) {
        logger.error("Invalid webhook signature");
        res.status(401).json({ error: "Invalid signature" });
        return;
      }
      const payload = req.body;
      if (payload.type !== "Issue") {
        res.status(200).json({ message: "Ignored non-issue webhook" });
        return;
      }
      switch (payload.action) {
        case "create":
          await this.handleIssueCreate(payload);
          break;
        case "update":
          await this.handleIssueUpdate(payload);
          break;
        case "remove":
          await this.handleIssueRemove(payload);
          break;
        default:
          logger.warn(`Unknown webhook action: ${payload.action}`);
      }
      res.status(200).json({ message: "Webhook processed successfully" });
    } catch (error) {
      logger.error("Failed to process webhook:", error);
      res.status(500).json({ error: "Failed to process webhook" });
    }
  }
  /**
   * Handle issue creation
   */
  async handleIssueCreate(payload) {
    const issue = payload.data;
    const existingTasks = this.taskStore.getActiveTasks();
    const exists = existingTasks.some(
      (t) => t.title.includes(issue.identifier) || t.external_refs?.linear === issue.id
    );
    if (exists) {
      logger.info(`Task ${issue.identifier} already exists locally`);
      return;
    }
    const taskId = this.taskStore.createTask({
      title: `[${issue.identifier}] ${issue.title}`,
      description: issue.description || "",
      priority: this.mapLinearPriorityToLocal(issue.priority),
      frameId: "linear-webhook",
      tags: issue.labels?.map((l) => l.name) || ["linear"],
      estimatedEffort: issue.estimate ? issue.estimate * 60 : void 0,
      assignee: issue.assignee?.name
    });
    const status = this.mapLinearStateToLocalStatus(issue.state.type);
    if (status !== "pending") {
      this.taskStore.updateTaskStatus(
        taskId,
        status,
        `Synced from Linear (${issue.state.name})`
      );
    }
    await this.storeLinearMapping(taskId, issue.id, issue.identifier);
    logger.info(`Created task ${taskId} from Linear issue ${issue.identifier}`);
  }
  /**
   * Handle issue update
   */
  async handleIssueUpdate(payload) {
    const issue = payload.data;
    const tasks = this.taskStore.getActiveTasks();
    const localTask = tasks.find(
      (t) => t.title.includes(issue.identifier) || t.external_refs?.linear === issue.id
    );
    if (!localTask) {
      await this.handleIssueCreate(payload);
      return;
    }
    const newStatus = this.mapLinearStateToLocalStatus(issue.state.type);
    if (newStatus !== localTask.status) {
      this.taskStore.updateTaskStatus(
        localTask.id,
        newStatus,
        `Updated from Linear (${issue.state.name})`
      );
    }
    const newPriority = this.mapLinearPriorityToLocal(issue.priority);
    if (newPriority !== localTask.priority) {
      logger.info(
        `Priority changed for ${issue.identifier}: ${localTask.priority} -> ${newPriority}`
      );
    }
    logger.info(
      `Updated task ${localTask.id} from Linear issue ${issue.identifier}`
    );
  }
  /**
   * Handle issue removal
   */
  async handleIssueRemove(payload) {
    const issue = payload.data;
    const tasks = this.taskStore.getActiveTasks();
    const localTask = tasks.find(
      (t) => t.title.includes(issue.identifier) || t.external_refs?.linear === issue.id
    );
    if (localTask) {
      this.taskStore.updateTaskStatus(
        localTask.id,
        "cancelled",
        `Removed in Linear`
      );
      logger.info(
        `Cancelled task ${localTask.id} (Linear issue ${issue.identifier} was removed)`
      );
    }
  }
  /**
   * Store Linear mapping for a task
   */
  async storeLinearMapping(taskId, linearId, linearIdentifier) {
    logger.info(
      `Mapped task ${taskId} to Linear ${linearIdentifier} (${linearId})`
    );
  }
  /**
   * Map Linear priority to local priority
   */
  mapLinearPriorityToLocal(priority) {
    if (!priority) return "medium";
    switch (priority) {
      case 0:
        return "urgent";
      case 1:
        return "high";
      case 2:
        return "medium";
      case 3:
      case 4:
        return "low";
      default:
        return "medium";
    }
  }
  /**
   * Map Linear state to local status
   */
  mapLinearStateToLocalStatus(state) {
    switch (state) {
      case "backlog":
      case "unstarted":
        return "pending";
      case "started":
        return "in_progress";
      case "completed":
        return "completed";
      case "cancelled":
        return "cancelled";
      default:
        return "pending";
    }
  }
}
export {
  LinearWebhookHandler
};
//# sourceMappingURL=webhook-handler.js.map
