import { defineHandler, useLogger, useLLM, useConfig } from '@kb-labs/sdk';
import { resolveCommitConfig, COMMIT_CACHE_PREFIX } from '@kb-labs/commit-contracts';
import { loadPlan, savePlan } from '@kb-labs/commit-core/storage';
import { getFileSummaries, getFileDiffs } from '@kb-labs/commit-core/analyzer';
import { SYSTEM_PROMPT_WITH_DIFF, COMMIT_PLAN_TOOL } from '@kb-labs/commit-core/generator';
import * as path from 'path';

// src/rest/handlers/regenerate-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);
}

// src/rest/handlers/regenerate-handler.ts
var regenerate_handler_default = defineHandler({
  async execute(ctx, input) {
    const logger = useLogger();
    const { scope = "root", commitId, instruction } = input.body ?? {};
    if (!commitId) {
      throw new Error("commitId is required");
    }
    const plan = await loadPlan(ctx.cwd, scope);
    if (!plan) {
      throw new Error("No commit plan found. Generate a plan first.");
    }
    const commitIndex = plan.commits.findIndex((c) => c.id === commitId);
    if (commitIndex === -1) {
      throw new Error(`Commit "${commitId}" not found in plan`);
    }
    const existingCommit = plan.commits[commitIndex];
    const files = existingCommit.files;
    if (files.length === 0) {
      throw new Error("Commit has no files to regenerate");
    }
    const llm = useLLM();
    if (!llm || !llm.chatWithTools) {
      throw new Error("LLM is not available for regeneration");
    }
    try {
      const fileConfig = await useConfig();
      const config = resolveCommitConfig(fileConfig ?? {});
      const scopeCwd = resolveScopePath(ctx.cwd, scope, config.scope?.scopes);
      const summaries = await getFileSummaries(scopeCwd, files);
      const diffs = await getFileDiffs(scopeCwd, files);
      const fileContext = summaries.map((s) => {
        const diff = diffs.get(s.path) || "";
        return `File: ${s.path} (${s.status}, +${s.additions}/-${s.deletions})${diff ? `
Diff:
${diff}` : ""}`;
      }).join("\n\n");
      const instructionText = instruction ? `

User instruction: ${instruction}` : "";
      const userPrompt = `Analyze these files and generate exactly ONE commit following conventional commit conventions.
These files were previously grouped as: ${existingCommit.type}(${existingCommit.scope || ""}): ${existingCommit.message}

Re-analyze them and generate an improved commit message.${instructionText}

Files to analyze:
${fileContext}`;
      const messages = [
        { role: "system", content: SYSTEM_PROMPT_WITH_DIFF },
        { role: "user", content: userPrompt }
      ];
      const response = await llm.chatWithTools(messages, {
        tools: [COMMIT_PLAN_TOOL],
        toolChoice: {
          type: "function",
          function: { name: "generate_commit_plan" }
        },
        temperature: 0.3
      });
      const toolCall = response.toolCalls?.[0];
      if (!toolCall || toolCall.name !== "generate_commit_plan") {
        throw new Error("LLM did not call generate_commit_plan tool");
      }
      const toolArgs = toolCall.input;
      const regeneratedCommit = toolArgs.commits[0];
      if (!regeneratedCommit) {
        throw new Error("LLM returned no commits");
      }
      regeneratedCommit.id = existingCommit.id;
      regeneratedCommit.files = existingCommit.files;
      plan.commits[commitIndex] = regeneratedCommit;
      await savePlan(ctx.cwd, plan, scope);
      const appliedCacheKey = `${COMMIT_CACHE_PREFIX}plan-applied:${scope}`;
      await ctx.platform.cache.delete(appliedCacheKey);
      await logger.info("[regenerate-handler] Commit regenerated", {
        scope,
        commitId,
        oldMessage: `${existingCommit.type}: ${existingCommit.message}`,
        newMessage: `${regeneratedCommit.type}: ${regeneratedCommit.message}`
      });
      if (ctx.platform.analytics) {
        await ctx.platform.analytics.track("commit.regenerate.success", {
          scope,
          commitId,
          hadInstruction: !!instruction,
          filesCount: files.length
        });
      }
      return {
        success: true,
        scope,
        commitId,
        commit: regeneratedCommit
      };
    } catch (error) {
      if (ctx.platform.analytics) {
        await ctx.platform.analytics.track("commit.regenerate.error", {
          scope,
          commitId,
          error: error instanceof Error ? error.message : String(error)
        });
      }
      throw new Error(`Failed to regenerate commit: ${error}`);
    }
  }
});

export { regenerate_handler_default as default };
//# sourceMappingURL=regenerate-handler.js.map
//# sourceMappingURL=regenerate-handler.js.map