/**
 * Claude Code Task & Team Scanner
 *
 * Read-only bridge that discovers Claude Code's:
 * - Team tasks from ~/.claude/tasks/<team>/<N>.json
 * - Team configs from ~/.claude/teams/<name>/config.json
 *
 * Follows the same throttled-scan pattern as claude-sessions.ts.
 */

import { readdirSync, readFileSync, statSync } from 'fs'
import { join } from 'path'
import { config } from './config'
import { logger } from './logger'

export interface ClaudeCodeTask {
  id: string
  teamName: string
  subject: string
  description: string
  status: string
  owner: string
  blocks: string[]
  blockedBy: string[]
  activeForm?: string
}

export interface ClaudeCodeTeam {
  name: string
  description: string
  createdAt: number
  leadAgentId: string
  members: Array<{
    agentId: string
    name: string
    agentType: string
    model: string
  }>
}

export interface ClaudeCodeScanResult {
  teams: ClaudeCodeTeam[]
  tasks: ClaudeCodeTask[]
}

function safeParse<T>(filePath: string): T | null {
  try {
    return JSON.parse(readFileSync(filePath, 'utf-8'))
  } catch {
    return null
  }
}

function scanTeams(claudeHome: string): ClaudeCodeTeam[] {
  const teamsDir = join(claudeHome, 'teams')
  let teamDirs: string[]
  try {
    teamDirs = readdirSync(teamsDir)
  } catch {
    return []
  }

  const teams: ClaudeCodeTeam[] = []

  for (const teamName of teamDirs) {
    const configPath = join(teamsDir, teamName, 'config.json')
    try {
      if (!statSync(configPath).isFile()) continue
    } catch {
      continue
    }

    const data = safeParse<any>(configPath)
    if (!data?.name) continue

    teams.push({
      name: data.name,
      description: data.description || '',
      createdAt: data.createdAt || 0,
      leadAgentId: data.leadAgentId || '',
      members: Array.isArray(data.members)
        ? data.members.map((m: any) => ({
            agentId: m.agentId || '',
            name: m.name || '',
            agentType: m.agentType || '',
            model: m.model || '',
          }))
        : [],
    })
  }

  return teams
}

function scanTasks(claudeHome: string): ClaudeCodeTask[] {
  const tasksDir = join(claudeHome, 'tasks')
  let teamDirs: string[]
  try {
    teamDirs = readdirSync(tasksDir)
  } catch {
    return []
  }

  const tasks: ClaudeCodeTask[] = []

  for (const teamName of teamDirs) {
    const teamDir = join(tasksDir, teamName)
    try {
      if (!statSync(teamDir).isDirectory()) continue
    } catch {
      continue
    }

    // Skip .lock files, only read JSON task files
    let files: string[]
    try {
      files = readdirSync(teamDir).filter(f => f.endsWith('.json'))
    } catch {
      continue
    }

    for (const file of files) {
      const data = safeParse<any>(join(teamDir, file))
      if (!data?.id) continue

      tasks.push({
        id: `${teamName}/${data.id}`,
        teamName,
        subject: data.subject || data.title || `Task ${data.id}`,
        description: data.description || '',
        status: data.status || 'unknown',
        owner: data.owner || '',
        blocks: Array.isArray(data.blocks) ? data.blocks : [],
        blockedBy: Array.isArray(data.blockedBy) ? data.blockedBy : [],
        activeForm: data.activeForm,
      })
    }
  }

  return tasks
}

export function scanClaudeCodeTasks(): ClaudeCodeScanResult {
  const claudeHome = config.claudeHome
  if (!claudeHome) return { teams: [], tasks: [] }

  return {
    teams: scanTeams(claudeHome),
    tasks: scanTasks(claudeHome),
  }
}

// Throttle full disk scans
let lastScanAt = 0
let cachedResult: ClaudeCodeScanResult = { teams: [], tasks: [] }
const SCAN_THROTTLE_MS = 30_000

export function getClaudeCodeTasks(force = false): ClaudeCodeScanResult {
  const now = Date.now()
  if (!force && lastScanAt > 0 && (now - lastScanAt) < SCAN_THROTTLE_MS) {
    return cachedResult
  }

  try {
    cachedResult = scanClaudeCodeTasks()
    lastScanAt = now
  } catch (err) {
    logger.warn({ err }, 'Claude Code task scan failed')
  }

  return cachedResult
}
