/**
 * IDE Integration Module
 * Exports formatters and utilities for IDE-specific config files
 */

import { existsSync, readFileSync, writeFileSync, mkdirSync, unlinkSync } from 'fs'
import { join, dirname } from 'path'

// Export formatters
export { formatCursorRules } from './cursor'
export { formatWindsurfRules } from './windsurf'
export { formatClaudeCodeSection, OCULUM_SECTION_START, OCULUM_SECTION_END } from './claude-code'

/** Supported IDE types */
export type IDEType = 'cursor' | 'windsurf' | 'claude-code'

/** Default file paths for each IDE */
export const IDE_FILE_PATHS: Record<IDEType, string> = {
  cursor: '.cursor/rules/security.mdc',
  windsurf: '.windsurfrules',
  'claude-code': 'CLAUDE.md',
}

/** Result of a file write operation */
export interface WriteIDEFileResult {
  success: boolean
  path: string
  error?: string
}

/** Result of a file clear operation */
export interface ClearIDEFilesResult {
  success: boolean
  clearedFiles: string[]
  errors: string[]
}

/**
 * Detect which IDE configurations exist in the project
 *
 * @param projectPath - Path to the project root
 * @returns Array of detected IDE types
 */
export function detectIDEConfigs(projectPath: string): IDEType[] {
  const detected: IDEType[] = []

  // Check for Cursor
  if (existsSync(join(projectPath, '.cursor'))) {
    detected.push('cursor')
  }

  // Check for Windsurf rules
  if (existsSync(join(projectPath, '.windsurfrules'))) {
    detected.push('windsurf')
  }

  // Check for Claude Code
  if (existsSync(join(projectPath, 'CLAUDE.md'))) {
    detected.push('claude-code')
  }

  return detected
}

/**
 * Write an IDE-specific file
 *
 * @param projectPath - Path to the project root
 * @param relativePath - Relative path for the file
 * @param content - Content to write
 * @returns Result object
 */
export function writeIDEFile(
  projectPath: string,
  relativePath: string,
  content: string
): WriteIDEFileResult {
  const fullPath = join(projectPath, relativePath)

  try {
    // Ensure directory exists
    const dir = dirname(fullPath)
    if (!existsSync(dir)) {
      mkdirSync(dir, { recursive: true })
    }

    // Write file
    writeFileSync(fullPath, content)

    return { success: true, path: fullPath }
  } catch (err) {
    return {
      success: false,
      path: fullPath,
      error: `Failed to write ${relativePath}: ${err instanceof Error ? err.message : 'Unknown error'}`,
    }
  }
}

/**
 * Update the Oculum section in CLAUDE.md
 * Replaces content between OCULUM_SECURITY_START and OCULUM_SECURITY_END markers
 * If markers don't exist, appends the section at the end
 *
 * @param projectPath - Path to the project root
 * @param section - The section content (including markers)
 * @returns Result object
 */
export function updateClaudeMdSection(
  projectPath: string,
  section: string
): WriteIDEFileResult {
  const filePath = join(projectPath, 'CLAUDE.md')

  try {
    let content: string

    if (existsSync(filePath)) {
      content = readFileSync(filePath, 'utf-8')

      // Check if markers exist
      const startMarker = '<!-- OCULUM_SECURITY_START -->'
      const endMarker = '<!-- OCULUM_SECURITY_END -->'
      const startIndex = content.indexOf(startMarker)
      const endIndex = content.indexOf(endMarker)

      if (startIndex !== -1 && endIndex !== -1 && endIndex > startIndex) {
        // Replace existing section
        content =
          content.substring(0, startIndex) +
          section +
          content.substring(endIndex + endMarker.length)
      } else {
        // Append section at end
        content = content.trimEnd() + '\n\n' + section
      }
    } else {
      // Create new file with section
      content = `# CLAUDE.md\n\n${section}`
    }

    writeFileSync(filePath, content)

    return { success: true, path: filePath }
  } catch (err) {
    return {
      success: false,
      path: filePath,
      error: `Failed to update CLAUDE.md: ${err instanceof Error ? err.message : 'Unknown error'}`,
    }
  }
}

/**
 * Clear IDE rule files
 *
 * @param projectPath - Path to the project root
 * @param types - Optional array of IDE types to clear. If not provided, clears all.
 * @returns Result object with list of cleared files
 */
export function clearIDEFiles(
  projectPath: string,
  types?: IDEType[]
): ClearIDEFilesResult {
  const toCheck = types || (['cursor', 'windsurf', 'claude-code'] as IDEType[])
  const clearedFiles: string[] = []
  const errors: string[] = []

  for (const ide of toCheck) {
    const relativePath = IDE_FILE_PATHS[ide]
    const fullPath = join(projectPath, relativePath)

    try {
      if (ide === 'claude-code') {
        // For CLAUDE.md, remove only the Oculum section, not the whole file
        if (existsSync(fullPath)) {
          const content = readFileSync(fullPath, 'utf-8')
          const startMarker = '<!-- OCULUM_SECURITY_START -->'
          const endMarker = '<!-- OCULUM_SECURITY_END -->'
          const startIndex = content.indexOf(startMarker)
          const endIndex = content.indexOf(endMarker)

          if (startIndex !== -1 && endIndex !== -1) {
            // Remove section (including potential surrounding newlines)
            let newContent = content.substring(0, startIndex) + content.substring(endIndex + endMarker.length)
            // Clean up extra newlines
            newContent = newContent.replace(/\n{3,}/g, '\n\n').trimEnd() + '\n'
            writeFileSync(fullPath, newContent)
            clearedFiles.push(relativePath)
          }
        }
      } else {
        // For other IDEs, delete the file
        if (existsSync(fullPath)) {
          unlinkSync(fullPath)
          clearedFiles.push(relativePath)
        }
      }
    } catch (err) {
      errors.push(`Failed to clear ${relativePath}: ${err instanceof Error ? err.message : 'Unknown error'}`)
    }
  }

  return {
    success: errors.length === 0,
    clearedFiles,
    errors,
  }
}

/**
 * Get the default file path for an IDE type
 */
export function getIDEFilePath(ide: IDEType): string {
  return IDE_FILE_PATHS[ide]
}
