import * as Diff from "diff"

interface SingleLineCompletionResult {
  completionText: string
  range?: {
    start: number
    end: number
  }
}

interface DiffType {
  count?: number
  added?: boolean
  removed?: boolean
  value: string
}

function diffPatternMatches(diffs: DiffType[], pattern: DiffPartType[]): boolean {
  if (diffs.length !== pattern.length) {
    return false
  }

  for (let i = 0; i < diffs.length; i++) {
    const diff = diffs[i]
    const diffPartType: DiffPartType = !diff.added && !diff.removed ? "=" : diff.added ? "+" : "-"

    if (diffPartType !== pattern[i]) {
      return false
    }
  }

  return true
}

type DiffPartType = "+" | "-" | "="

export function processSingleLineCompletion(
  lastLineOfCompletionText: string,
  currentText: string,
  cursorPosition: number,
): SingleLineCompletionResult | undefined {
  const diffs: DiffType[] = Diff.diffWords(currentText, lastLineOfCompletionText)

  if (diffPatternMatches(diffs, ["+"])) {
    // Just insert, we're already at the end of the line
    return {
      completionText: lastLineOfCompletionText,
    }
  }

  if (diffPatternMatches(diffs, ["+", "="]) || diffPatternMatches(diffs, ["+", "=", "+"])) {
    // The model repeated the text after the cursor to the end of the line
    return {
      completionText: lastLineOfCompletionText,
      range: {
        start: cursorPosition,
        end: currentText.length + cursorPosition,
      },
    }
  }

  if (diffPatternMatches(diffs, ["+", "-"]) || diffPatternMatches(diffs, ["-", "+"])) {
    // We are midline and the model just inserted without repeating to the end of the line
    return {
      completionText: lastLineOfCompletionText,
    }
  }

  // For any other diff pattern, just use the first added part if available
  if (diffs[0]?.added) {
    return {
      completionText: diffs[0].value,
    }
  }

  // Default case: treat as simple insertion
  return {
    completionText: lastLineOfCompletionText,
  }
}
