import * as vscode from "vscode"

import { CodeActionName, CodeActionId } from "@roo-code/types"
import { Package } from "../shared/package"

import { getCodeActionCommand } from "../utils/commands"
import { EditorUtils } from "../integrations/editor/EditorUtils"

export const TITLES: Record<CodeActionName, string> = {
	EXPLAIN: "Explain with CoStrict",
	FIX: "Fix with CoStrict",
	IMPROVE: "Improve with CoStrict",
	ADD_TO_CONTEXT: "Add to CoStrict",
	NEW_TASK: "New CoStrict Task",

	// right menu and quick menu
	ZGSM_EXPLAIN: "CoStrict: Explain Code",
	ZGSM_ADD_COMMENT: "CoStrict: Add Comment",
	ZGSM_CODE_REVIEW: "CoStrict: Code Review",
	ZGSM_ADD_DEBUG_CODE: "CoStrict: Add Debug Code",
	ZGSM_ADD_STRONG_CODE: "CoStrict: Add Strong Code",
	ZGSM_SIMPLIFY_CODE: "CoStrict: Simplify Code",
	ZGSM_PERFORMANCE: "CoStrict: Performance Optimization",
} as const

export class CodeActionProvider implements vscode.CodeActionProvider {
	public static readonly providedCodeActionKinds = [
		vscode.CodeActionKind.QuickFix,
		vscode.CodeActionKind.RefactorRewrite,
	]

	private createAction(
		title: string,
		kind: vscode.CodeActionKind,
		command: CodeActionId,
		args: any[],
	): vscode.CodeAction {
		const action = new vscode.CodeAction(title, kind)
		action.command = { command: getCodeActionCommand(command), title, arguments: args }
		return action
	}

	public provideCodeActions(
		document: vscode.TextDocument,
		range: vscode.Range | vscode.Selection,
		context: vscode.CodeActionContext,
	): vscode.ProviderResult<(vscode.CodeAction | vscode.Command)[]> {
		try {
			if (!vscode.workspace.getConfiguration(Package.commandIDPrefix).get<boolean>("enableCodeActions", true)) {
				return []
			}

			const effectiveRange = EditorUtils.getEffectiveRange(document, range)

			if (!effectiveRange) {
				return []
			}

			const filePath = EditorUtils.getFilePath(document)
			const actions: vscode.CodeAction[] = []

			actions.push(
				this.createAction(TITLES.ADD_TO_CONTEXT, vscode.CodeActionKind.QuickFix, "addToContext", [
					filePath,
					effectiveRange.text,
					effectiveRange.range.start.line + 1,
					effectiveRange.range.end.line + 1,
				]),
			)

			if (context.diagnostics.length > 0) {
				const relevantDiagnostics = context.diagnostics.filter((d) =>
					EditorUtils.hasIntersectingRange(effectiveRange.range, d.range),
				)

				if (relevantDiagnostics.length > 0) {
					actions.push(
						this.createAction(TITLES.FIX, vscode.CodeActionKind.QuickFix, "fixCode", [
							filePath,
							effectiveRange.text,
							effectiveRange.range.start.line + 1,
							effectiveRange.range.end.line + 1,
							relevantDiagnostics?.map(EditorUtils.createDiagnosticData),
						]),
					)
				}
			} else {
				actions.push(
					this.createAction(TITLES.EXPLAIN, vscode.CodeActionKind.QuickFix, "explainCode", [
						filePath,
						effectiveRange.text,
						effectiveRange.range.start.line + 1,
						effectiveRange.range.end.line + 1,
					]),
				)

				actions.push(
					this.createAction(TITLES.IMPROVE, vscode.CodeActionKind.QuickFix, "improveCode", [
						filePath,
						effectiveRange.text,
						effectiveRange.range.start.line + 1,
						effectiveRange.range.end.line + 1,
					]),
				)
			}

			return actions
		} catch (error) {
			console.error("Error providing code actions:", error)
			return []
		}
	}
}
