import { defineHandler, useConfig } from '@kb-labs/sdk';
import { resolveCommitConfig, COMMIT_CACHE_PREFIX } from '@kb-labs/commit-contracts';
import { applyCommitPlan } from '@kb-labs/commit-core/applier';
import { loadPlan } from '@kb-labs/commit-core/storage';
import * as path from 'path';
import { normalize, relative } from 'path';

// src/rest/handlers/apply-handler.ts
function resolveScopePath(baseCwd, scopeId = "root", scopes) {
  const scopeDef = scopes?.find((s) => s.id === scopeId);
  const relativePath = scopeDef?.path ?? (scopeId === "root" ? "." : scopeId);
  return relativePath === "." ? baseCwd : path.join(baseCwd, relativePath);
}
var apply_handler_default = defineHandler({
  async execute(ctx, input) {
    const { scope = "root", force, commitIds } = input.body ?? {};
    const startTime = Date.now();
    try {
      const fileConfig = await useConfig();
      const config = resolveCommitConfig(fileConfig ?? {});
      const scopeCwd = resolveScopePath(ctx.cwd, scope, config.scope?.scopes);
      const plan = await loadPlan(ctx.cwd, scope);
      if (!plan) {
        throw new Error("No commit plan found. Generate a plan first with POST /generate");
      }
      const scopeRelative = normalize(relative(ctx.cwd, scopeCwd));
      const stripScopePrefix = (filePath) => {
        const normalizedPath = normalize(filePath);
        const normalizedPrefix = normalize(scopeRelative);
        if (normalizedPath.startsWith(normalizedPrefix + "/") || normalizedPath.startsWith(normalizedPrefix + "\\")) {
          return normalizedPath.slice(normalizedPrefix.length + 1);
        }
        if (normalizedPath === normalizedPrefix) {
          return "";
        }
        return filePath;
      };
      const transformedPlan = {
        ...plan,
        gitStatus: {
          staged: plan.gitStatus.staged.map(stripScopePrefix),
          unstaged: plan.gitStatus.unstaged.map(stripScopePrefix),
          untracked: plan.gitStatus.untracked.map(stripScopePrefix)
        },
        commits: plan.commits.map((commit) => ({
          ...commit,
          files: commit.files.map(stripScopePrefix)
        }))
      };
      if (commitIds && commitIds.length > 0) {
        const commitIdSet = new Set(commitIds);
        transformedPlan.commits = transformedPlan.commits.filter((c) => commitIdSet.has(c.id));
        if (transformedPlan.commits.length === 0) {
          throw new Error("None of the specified commitIds found in plan");
        }
        const selectedFiles = new Set(transformedPlan.commits.flatMap((c) => c.files));
        transformedPlan.gitStatus = {
          staged: transformedPlan.gitStatus.staged.filter((f) => selectedFiles.has(f)),
          unstaged: transformedPlan.gitStatus.unstaged.filter((f) => selectedFiles.has(f)),
          untracked: transformedPlan.gitStatus.untracked.filter((f) => selectedFiles.has(f))
        };
      }
      const appliedCacheKey = `${COMMIT_CACHE_PREFIX}plan-applied:${scope}`;
      await ctx.platform.cache.delete(appliedCacheKey);
      const result = await applyCommitPlan(scopeCwd, transformedPlan, { force, scope });
      if (result.success) {
        await ctx.platform.cache.set(
          appliedCacheKey,
          {
            commitsApplied: result.appliedCommits.length,
            planCreatedAt: plan.createdAt
          },
          60 * 60 * 1e3
          // 1 hour TTL
        );
      }
      if (ctx.platform.analytics) {
        if (result.success) {
          await ctx.platform.analytics.track("commit.apply.success", {
            scope,
            force,
            commitsApplied: result.appliedCommits.length,
            durationMs: Date.now() - startTime
          });
        } else {
          await ctx.platform.analytics.track("commit.apply.failed", {
            scope,
            force,
            commitsApplied: result.appliedCommits.length,
            errors: result.errors,
            durationMs: Date.now() - startTime
          });
        }
      }
      return {
        result,
        scope
      };
    } catch (error) {
      if (ctx.platform.analytics) {
        await ctx.platform.analytics.track("commit.apply.error", {
          scope,
          force,
          error: error instanceof Error ? error.message : String(error),
          durationMs: Date.now() - startTime
        });
      }
      throw new Error(`Failed to apply commits: ${error}`);
    }
  }
});

export { apply_handler_default as default };
//# sourceMappingURL=apply-handler.js.map
//# sourceMappingURL=apply-handler.js.map