import * as vscode from 'vscode';
import { ACTION_LABELS, type ActionId } from '@lib/actions';
import type { VsCodeLexAISettings } from './config';

export type LexAIRunAction = ActionId | 'codeAssist';

export type SuggestionOptions = Pick<
  VsCodeLexAISettings,
  | 'writingStyle'
  | 'promptPattern'
  | 'promptPersona'
  | 'customPersona'
  | 'promptFormat'
  | 'promptModel'
>;

export interface SuggestionSession {
  action: LexAIRunAction;
  documentUri: vscode.Uri;
  range: vscode.Range;
  originalText: string;
  suggestion: string;
  options: SuggestionOptions;
  /** Freeform Code Assist instruction */
  instruction?: string;
  /** Short UI blurb about gathered workspace files */
  contextSummary?: string;
  /** Full context pack for regenerating Code Assist */
  contextText?: string;
}

export function actionLabel(action: LexAIRunAction): string {
  if (action === 'codeAssist') return 'Code Assist';
  return ACTION_LABELS[action];
}

export function resolveReplaceRange(
  doc: vscode.TextDocument,
  s: SuggestionSession,
): vscode.Range | undefined {
  const atRange = doc.getText(s.range);
  if (atRange === s.originalText) return s.range;

  const full = doc.getText();
  const idx = full.indexOf(s.originalText);
  if (idx < 0) return undefined;
  const start = doc.positionAt(idx);
  const end = doc.positionAt(idx + s.originalText.length);
  return new vscode.Range(start, end);
}

export async function applySuggestionReplace(
  session: SuggestionSession,
  suggestion: string,
): Promise<boolean> {
  const doc = await vscode.workspace.openTextDocument(session.documentUri);
  const editor = await vscode.window.showTextDocument(doc, {
    viewColumn: vscode.ViewColumn.One,
    preview: false,
    preserveFocus: false,
  });
  const range = resolveReplaceRange(doc, session);
  if (!range) {
    void vscode.window.showErrorMessage(
      'LexAI: could not find the original selection (it may have changed). Copy the suggestion manually.',
    );
    return false;
  }
  return editor.edit((edit) => {
    edit.replace(range, suggestion);
  });
}
