import * as vscode from 'vscode';
import {
  ACTION_LABELS,
  MIN_SELECTION_LENGTH,
  resolvePromptPersona,
  type ActionId,
} from '@lib/actions';
import { resolveConfig } from './config';
import { generateSuggestion } from './llm';
import { openSuggestionPanel } from './suggestionPanel';
import { withLexAIProgress } from './statusBar';
import { maybeTuneOptionsBeforeRun, openSuggestionZone } from './suggestionZone';

export async function runActionOnSelection(
  context: vscode.ExtensionContext,
  action: ActionId,
): Promise<void> {
  const editor = vscode.window.activeTextEditor;
  if (!editor) {
    void vscode.window.showErrorMessage('LexAI: open a text editor and select text first.');
    return;
  }

  const selection = editor.selection;
  if (selection.isEmpty) {
    void vscode.window.showErrorMessage('LexAI: select some text first.');
    return;
  }

  const text = editor.document.getText(selection);
  if (text.trim().length < MIN_SELECTION_LENGTH) {
    void vscode.window.showErrorMessage(
      `LexAI: select at least ${MIN_SELECTION_LENGTH} characters.`,
    );
    return;
  }

  const resolved = await resolveConfig(context);
  if (resolved.error || !resolved.config) {
    void vscode.window.showErrorMessage(`LexAI: ${resolved.error ?? 'configuration error'}`);
    return;
  }

  const options = await maybeTuneOptionsBeforeRun(action);
  if (!options) return;

  const preview = vscode.workspace
    .getConfiguration('lexai')
    .get<boolean>('previewBeforeReplace', true);
  const ui = vscode.workspace
    .getConfiguration('lexai')
    .get<'zone' | 'panel' | 'both'>('suggestionUi', 'zone');

  const label = ACTION_LABELS[action];
  const response = await withLexAIProgress(`LexAI: ${label}…`, () =>
    generateSuggestion({
      action,
      text,
      config: resolved.config!,
      writingStyle: options.writingStyle,
      promptParams: {
        pattern: options.promptPattern,
        persona: resolvePromptPersona(options.promptPersona, options.customPersona),
        format: options.promptFormat,
      },
      promptModel: options.promptModel || undefined,
    }),
  );

  if (response.error) {
    void vscode.window.showErrorMessage(`LexAI: ${response.error}`);
    return;
  }

  const result = response.result ?? '';
  if (!result) {
    void vscode.window.showErrorMessage('LexAI: empty response from provider.');
    return;
  }

  const range = new vscode.Range(selection.start, selection.end);
  const session = {
    action,
    documentUri: editor.document.uri,
    range,
    originalText: text,
    suggestion: result,
    options,
  };

  if (!preview) {
    const ok = await editor.edit((editBuilder) => {
      editBuilder.replace(selection, result);
    });
    if (!ok) {
      void vscode.window.showErrorMessage('LexAI: could not replace the selection (editor busy?).');
      return;
    }
    void vscode.window.showInformationMessage(`LexAI: ${label} applied.`);
    return;
  }

  if (ui === 'panel') {
    await openSuggestionPanel(context, session);
    return;
  }

  await openSuggestionZone(context, session);
  // Side panel only when explicitly requested — auto-opening it alongside
  // the in-editor zone was confusing during testing.
  if (ui === 'both') {
    await openSuggestionPanel(context, session);
  }
}
