import { NextRequest, NextResponse } from 'next/server'
import * as fs from 'fs/promises'
import * as path from 'path'

/**
 * Agent SOUL File API
 *
 * GET - Get SOUL file content
 * PUT - Update SOUL file content
 * GET /history - Get version history
 */

const AGENT_CORE_PATH = process.env.AGENT_CORE_PATH || '/app/agent-core'
const SOUL_PATH = path.join(AGENT_CORE_PATH, 'soul')

interface SoulVersion {
  version: string
  timestamp: string
  content: string
  author: string
  changes: string
}

// Read SOUL file content
async function readSoulFile(agentId: string): Promise<string | null> {
  const soulFile = `${agentId}.soul.md`
  const soulFilePath = path.join(SOUL_PATH, soulFile)

  try {
    const content = await fs.readFile(soulFilePath, 'utf-8')
    return content
  } catch {
    return null
  }
}

// Get version history from backup directory
async function getVersionHistory(agentId: string): Promise<SoulVersion[]> {
  const backupDir = path.join(SOUL_PATH, '.backups')
  const versions: SoulVersion[] = []

  try {
    const files = await fs.readdir(backupDir)
    const agentBackups = files.filter(f => f.startsWith(`${agentId}-`) && f.endsWith('.soul.md'))

    for (const file of agentBackups.slice(-10)) { // Last 10 versions
      const filePath = path.join(backupDir, file)
      const stats = await fs.stat(filePath)
      const content = await fs.readFile(filePath, 'utf-8')

      // Extract timestamp from filename
      const match = file.match(/-(\d+)\.soul\.md$/)
      const timestamp = match ? new Date(parseInt(match[1])).toISOString() : stats.mtime.toISOString()

      versions.push({
        version: file.replace('.soul.md', ''),
        timestamp,
        content,
        author: 'Admin',
        changes: 'Manual update'
      })
    }

    // Sort by timestamp descending
    versions.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())
  } catch {
    // No backup directory or can't read
  }

  return versions
}

// GET - Get SOUL file content
export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ agentId: string }> }
) {
  try {
    const { agentId } = await params
    const url = new URL(request.url)
    const includeHistory = url.searchParams.get('history') === 'true'

    const content = await readSoulFile(agentId)
    if (!content) {
      return NextResponse.json(
        { error: 'SOUL file not found' },
        { status: 404 }
      )
    }

    const soulFile = `${agentId}.soul.md`
    const soulFilePath = path.join(SOUL_PATH, soulFile)
    const stats = await fs.stat(soulFilePath)

    const response: {
      agentId: string
      soulFile: string
      content: string
      updatedAt: string
      size: number
      history?: SoulVersion[]
    } = {
      agentId,
      soulFile,
      content,
      updatedAt: stats.mtime.toISOString(),
      size: stats.size
    }

    if (includeHistory) {
      response.history = await getVersionHistory(agentId)
    }

    return NextResponse.json(response)
  } catch (error) {
    console.error('Error fetching SOUL file:', error)
    return NextResponse.json(
      { error: error instanceof Error ? error.message : 'Failed to fetch SOUL file' },
      { status: 500 }
    )
  }
}

// PUT - Update SOUL file content
export async function PUT(
  request: NextRequest,
  { params }: { params: Promise<{ agentId: string }> }
) {
  try {
    const { agentId } = await params
    const body = await request.json()
    const { content, author, changeDescription } = body

    if (!content) {
      return NextResponse.json(
        { error: 'content is required' },
        { status: 400 }
      )
    }

    const soulFile = `${agentId}.soul.md`
    const soulFilePath = path.join(SOUL_PATH, soulFile)

    // Check if file exists
    try {
      await fs.access(soulFilePath)
    } catch {
      return NextResponse.json(
        { error: 'SOUL file not found' },
        { status: 404 }
      )
    }

    // Create backup before updating
    const backupDir = path.join(SOUL_PATH, '.backups')
    const backupPath = path.join(backupDir, `${agentId}-${Date.now()}.soul.md`)

    try {
      await fs.mkdir(backupDir, { recursive: true })
      const currentContent = await fs.readFile(soulFilePath, 'utf-8')
      await fs.writeFile(backupPath, currentContent, 'utf-8')
    } catch (backupError) {
      console.warn('Failed to create backup:', backupError)
    }

    // Write new content
    await fs.writeFile(soulFilePath, content, 'utf-8')
    const stats = await fs.stat(soulFilePath)

    return NextResponse.json({
      success: true,
      message: `SOUL file for ${agentId} updated successfully`,
      agentId,
      soulFile,
      updatedAt: stats.mtime.toISOString(),
      size: stats.size,
      author: author || 'Admin',
      changeDescription: changeDescription || 'Manual update'
    })
  } catch (error) {
    console.error('Error updating SOUL file:', error)
    return NextResponse.json(
      { error: error instanceof Error ? error.message : 'Failed to update SOUL file' },
      { status: 500 }
    )
  }
}
