import { fileURLToPath as __fileURLToPath } from 'url';
import { dirname as __pathDirname } from 'path';
const __filename = __fileURLToPath(import.meta.url);
const __dirname = __pathDirname(__filename);
import chalk from "chalk";
import {
  UnifiedLinearSync
} from "../../integrations/linear/unified-sync.js";
import { LinearAuthManager } from "../../integrations/linear/auth.js";
import { LinearClient } from "../../integrations/linear/client.js";
import { LinearTaskManager } from "../../features/tasks/linear-task-manager.js";
import Database from "better-sqlite3";
import { join } from "path";
import { existsSync, readFileSync } from "fs";
import Table from "cli-table3";
import ora from "ora";
function registerUnifiedLinearCommands(parent) {
  const linear = parent.command("linear").description(
    "Unified Linear integration with duplicate detection and task planning"
  );
  linear.command("sync").description(
    "Intelligent sync with Linear (duplicate detection, bidirectional, task planning)"
  ).option(
    "-d, --direction <dir>",
    "Sync direction: bidirectional, to_linear, from_linear",
    "bidirectional"
  ).option("-t, --team <id>", "Linear team ID").option("--no-duplicates", "Disable duplicate detection").option(
    "--merge-strategy <strategy>",
    "Duplicate handling: merge_content, skip, create_anyway",
    "merge_content"
  ).option(
    "--conflict <resolution>",
    "Conflict resolution: newest_wins, linear_wins, local_wins",
    "newest_wins"
  ).option("--task-plan", "Enable task planning integration").option("--dry-run", "Preview changes without syncing").option("--daemon", "Run as background daemon").option("-i, --interval <minutes>", "Auto-sync interval", "15").option("--verbose", "Show detailed sync progress").action(async (options) => {
    const spinner = ora("Initializing Linear sync...").start();
    try {
      const projectRoot = process.cwd();
      const dbPath = join(projectRoot, ".stackmemory", "context.db");
      if (!existsSync(dbPath)) {
        spinner.fail("StackMemory not initialized");
        console.log(chalk.yellow('Run "stackmemory init" first'));
        return;
      }
      const db = new Database(dbPath);
      const taskStore = new LinearTaskManager(projectRoot, db);
      const authManager = new LinearAuthManager(projectRoot);
      const config = {
        direction: options.direction,
        defaultTeamId: options.team,
        duplicateDetection: options.duplicates !== false,
        mergeStrategy: options.mergeStrategy,
        conflictResolution: options.conflict,
        taskPlanningEnabled: options.taskPlan || false
      };
      const unifiedSync = new UnifiedLinearSync(
        taskStore,
        authManager,
        projectRoot,
        config
      );
      if (options.verbose) {
        unifiedSync.on("sync:started", ({ config: config2 }) => {
          spinner.text = `Syncing (${config2.direction})...`;
        });
      }
      spinner.text = "Authenticating with Linear...";
      await unifiedSync.initialize();
      if (options.dryRun) {
        spinner.info("Dry run mode - no changes will be made");
        return;
      }
      if (options.daemon) {
        spinner.succeed("Starting sync daemon");
        console.log(chalk.cyan(`Sync interval: ${options.interval} minutes`));
        console.log(chalk.gray("Press Ctrl+C to stop\n"));
        const stats = await unifiedSync.sync();
        displaySyncStats(stats);
        const interval = setInterval(
          async () => {
            console.log(
              chalk.yellow(
                `
[${(/* @__PURE__ */ new Date()).toLocaleTimeString()}] Running scheduled sync...`
              )
            );
            try {
              const stats2 = await unifiedSync.sync();
              displaySyncStats(stats2);
            } catch (error) {
              console.error(
                chalk.red("Sync failed:"),
                error.message
              );
            }
          },
          parseInt(options.interval) * 60 * 1e3
        );
        process.on("SIGINT", () => {
          console.log(chalk.yellow("\nStopping sync daemon..."));
          clearInterval(interval);
          db.close();
          process.exit(0);
        });
        process.stdin.resume();
      } else {
        spinner.text = "Syncing tasks...";
        const stats = await unifiedSync.sync();
        spinner.succeed("Sync completed");
        displaySyncStats(stats);
        if (options.taskPlan) {
          displayTaskPlan(projectRoot);
        }
        db.close();
      }
    } catch (error) {
      spinner.fail("Sync failed");
      console.error(chalk.red("Error:"), error.message);
      if (options.verbose) {
        console.error(error);
      }
      process.exit(1);
    }
  });
  linear.command("status").description("Show Linear connection status and sync statistics").action(async () => {
    try {
      const authManager = new LinearAuthManager(process.cwd());
      const hasAuth = authManager.isConfigured();
      if (!hasAuth && !process.env.STACKMEMORY_LINEAR_API_KEY && !process.env.LINEAR_API_KEY) {
        console.log(chalk.yellow("\u26A0 Not connected to Linear"));
        console.log('Run "stackmemory linear auth" to connect');
        return;
      }
      console.log(chalk.green("\u2713 Linear connection configured"));
      const statsFile = join(
        process.cwd(),
        ".stackmemory",
        "sync-stats.json"
      );
      if (existsSync(statsFile)) {
        const stats = JSON.parse(readFileSync(statsFile, "utf8"));
        console.log(chalk.cyan("\nLast sync:"));
        console.log(`  Time: ${new Date(stats.timestamp).toLocaleString()}`);
        console.log(`  Duration: ${stats.duration}ms`);
        console.log(
          `  To Linear: ${stats.toLinear.created} created, ${stats.toLinear.updated} updated`
        );
        console.log(
          `  From Linear: ${stats.fromLinear.created} created, ${stats.fromLinear.updated} updated`
        );
        if (stats.toLinear.duplicatesMerged > 0) {
          console.log(
            chalk.green(
              `  Duplicates prevented: ${stats.toLinear.duplicatesMerged}`
            )
          );
        }
      }
      const planFile = join(process.cwd(), ".stackmemory", "task-plan.md");
      if (existsSync(planFile)) {
        console.log(chalk.cyan("\n\u2713 Task planning enabled"));
        const reportFile = join(
          process.cwd(),
          ".stackmemory",
          "task-report.md"
        );
        if (existsSync(reportFile)) {
          console.log(`  Report: ${reportFile}`);
        }
      }
    } catch (error) {
      console.error(
        chalk.red("Status check failed:"),
        error.message
      );
    }
  });
  linear.command("plan").description("View and manage task planning").option("--generate", "Generate task plan from current tasks").option("--report", "Show task report").action(async (options) => {
    try {
      const projectRoot = process.cwd();
      if (options.generate) {
        console.log(chalk.yellow("Generating task plan..."));
        const dbPath = join(projectRoot, ".stackmemory", "context.db");
        const db = new Database(dbPath);
        const taskStore = new LinearTaskManager(projectRoot, db);
        const authManager = new LinearAuthManager(projectRoot);
        const unifiedSync = new UnifiedLinearSync(
          taskStore,
          authManager,
          projectRoot,
          {
            taskPlanningEnabled: true,
            autoCreateTaskPlan: true
          }
        );
        await unifiedSync.initialize();
        await unifiedSync.sync();
        console.log(chalk.green("\u2713 Task plan generated"));
        db.close();
      }
      displayTaskPlan(projectRoot, options.report);
    } catch (error) {
      console.error(
        chalk.red("Plan generation failed:"),
        error.message
      );
    }
  });
  linear.command("duplicates").description("Check for and manage duplicate Linear issues").option("--check <title>", "Check if a title would create a duplicate").option("--merge", "Merge detected duplicates").option("--list", "List potential duplicates").action(async (options) => {
    try {
      const authManager = new LinearAuthManager(process.cwd());
      const token = await authManager.getValidToken();
      if (!token) {
        console.log(chalk.red("Not authenticated with Linear"));
        return;
      }
      const client = new LinearClient({
        apiKey: token,
        useBearer: authManager.isOAuth()
      });
      if (options.check) {
        const { LinearDuplicateDetector } = await import("../../integrations/linear/sync-enhanced.js");
        const detector = new LinearDuplicateDetector(client);
        console.log(
          chalk.yellow(`Checking for duplicates of: "${options.check}"`)
        );
        const result = await detector.checkForDuplicate(options.check);
        if (result.isDuplicate && result.existingIssue) {
          console.log(chalk.red("\u26A0 Duplicate detected!"));
          console.log(
            `  Issue: ${result.existingIssue.identifier} - ${result.existingIssue.title}`
          );
          console.log(
            `  Similarity: ${Math.round((result.similarity || 0) * 100)}%`
          );
          console.log(`  URL: ${result.existingIssue.url}`);
        } else {
          console.log(chalk.green("\u2713 No duplicates found"));
        }
      } else if (options.list) {
        console.log(chalk.yellow("Scanning for potential duplicates..."));
        console.log("Feature coming soon");
      } else {
        console.log("Specify --check, --merge, or --list");
      }
    } catch (error) {
      console.error(
        chalk.red("Duplicate check failed:"),
        error.message
      );
    }
  });
  linear.command("auth").description("Authenticate with Linear").option("--api-key <key>", "Use API key").option("--oauth", "Use OAuth flow").action(async (options) => {
    try {
      if (options.apiKey) {
        process.env.STACKMEMORY_LINEAR_API_KEY = options.apiKey;
        console.log(chalk.green("\u2713 API key configured"));
        const client = new LinearClient({ apiKey: options.apiKey });
        const user = await client.getViewer();
        console.log(chalk.cyan(`Connected as: ${user.name} (${user.email})`));
      } else {
        console.log(chalk.cyan("Linear Authentication"));
        console.log("\nOption 1: API Key (Recommended for automation)");
        console.log("  1. Go to: https://linear.app/settings/api");
        console.log("  2. Create a personal API key");
        console.log("  3. Run: stackmemory linear auth --api-key YOUR_KEY");
        console.log("\nOption 2: OAuth (For user-facing apps)");
        console.log("  Configure OAuth app and use linear-oauth-server");
      }
    } catch (error) {
      console.error(
        chalk.red("Authentication failed:"),
        error.message
      );
    }
  });
}
function displaySyncStats(stats) {
  const table = new Table({
    head: ["Direction", "Created", "Updated", "Merged", "Skipped"],
    style: { head: ["cyan"] }
  });
  table.push(
    [
      "\u2192 Linear",
      stats.toLinear.created,
      stats.toLinear.updated,
      stats.toLinear.duplicatesMerged,
      stats.toLinear.skipped
    ],
    [
      "\u2190 Linear",
      stats.fromLinear.created,
      stats.fromLinear.updated,
      "-",
      stats.fromLinear.skipped
    ]
  );
  console.log("\n" + table.toString());
  if (stats.conflicts.length > 0) {
    console.log(chalk.yellow(`
\u26A0 Conflicts: ${stats.conflicts.length}`));
    stats.conflicts.slice(0, 5).forEach((c) => {
      console.log(`  - ${c.reason}`);
    });
  }
  if (stats.errors.length > 0) {
    console.log(chalk.red(`
\u274C Errors: ${stats.errors.length}`));
    stats.errors.slice(0, 5).forEach((e) => {
      console.log(`  - ${e.substring(0, 100)}`);
    });
  }
  console.log(chalk.gray(`
Completed in ${stats.duration}ms`));
}
function displayTaskPlan(projectRoot, showReport = false) {
  const reportFile = join(projectRoot, ".stackmemory", "task-report.md");
  const planFile = join(projectRoot, ".stackmemory", "task-plan.json");
  if (showReport && existsSync(reportFile)) {
    const report = readFileSync(reportFile, "utf8");
    console.log("\n" + report);
  } else if (existsSync(planFile)) {
    const plan = JSON.parse(readFileSync(planFile, "utf8"));
    console.log(chalk.cyan("\n\u{1F4CB} Task Plan Overview"));
    console.log(
      `Last updated: ${new Date(plan.lastUpdated).toLocaleString()}
`
    );
    plan.phases.forEach((phase) => {
      console.log(chalk.yellow(`${phase.name} (${phase.tasks.length})`));
      console.log(chalk.gray(`  ${phase.description}`));
      if (phase.tasks.length > 0) {
        phase.tasks.slice(0, 5).forEach((task) => {
          const status = task.linearId ? "\u{1F517}" : "  ";
          console.log(`  ${status} ${task.title}`);
        });
        if (phase.tasks.length > 5) {
          console.log(chalk.gray(`     ...and ${phase.tasks.length - 5} more`));
        }
      }
      console.log();
    });
  } else {
    console.log(
      chalk.yellow("No task plan found. Run sync with --task-plan to generate.")
    );
  }
}
export {
  registerUnifiedLinearCommands
};
//# sourceMappingURL=linear-unified.js.map
