/**
 * Project Tracker
 *
 * Manages project state persistence across sessions.
 * State is stored in .sandcode/tracker.json in the project root.
 */

import { readFile, writeFile, mkdir } from 'fs/promises'
import { join, basename } from 'path'
import { getCwd } from '../../utils/cwd.js'
import { logForDebugging } from '../../utils/debug.js'
import { getSessionId } from '../../bootstrap/state.js'
import type {
  ProjectDecision,
  ProjectMilestone,
  ProjectTask,
  ProjectTrackerState,
} from './types.js'

const TRACKER_DIR = '.sandcode'
const TRACKER_FILE = 'tracker.json'

function getTrackerPath(): string {
  return join(getCwd(), TRACKER_DIR, TRACKER_FILE)
}

/**
 * Load the project tracker state from disk.
 * Returns a fresh state if no tracker file exists.
 */
export async function loadTrackerState(): Promise<ProjectTrackerState> {
  try {
    const content = await readFile(getTrackerPath(), 'utf-8')
    const parsed = JSON.parse(content) as ProjectTrackerState
    if (parsed.version === 1) {
      return parsed
    }
    logForDebugging(
      `Project tracker: unknown version ${parsed.version}, creating fresh state`,
    )
  } catch {
    // File doesn't exist or is invalid — create fresh state
  }

  return createFreshState()
}

/**
 * Save the project tracker state to disk.
 */
export async function saveTrackerState(
  state: ProjectTrackerState,
): Promise<void> {
  const trackerPath = getTrackerPath()
  await mkdir(join(getCwd(), TRACKER_DIR), { recursive: true })
  await writeFile(trackerPath, JSON.stringify(state, null, 2), 'utf-8')
}

/**
 * Record a key decision in the project tracker.
 */
export async function recordDecision(
  decision: string,
  rationale: string,
): Promise<void> {
  const state = await loadTrackerState()
  state.decisions.push({
    decision,
    rationale,
    timestamp: Date.now(),
    sessionId: getSessionId(),
  })
  // Keep last 50 decisions
  if (state.decisions.length > 50) {
    state.decisions = state.decisions.slice(-50)
  }
  await saveTrackerState(state)
}

/**
 * Record a completed milestone.
 */
export async function recordMilestone(
  description: string,
  filesChanged: string[],
): Promise<void> {
  const state = await loadTrackerState()
  state.milestones.push({
    description,
    completedAt: Date.now(),
    filesChanged,
    sessionId: getSessionId(),
  })
  // Keep last 100 milestones
  if (state.milestones.length > 100) {
    state.milestones = state.milestones.slice(-100)
  }
  await saveTrackerState(state)
}

/**
 * Add or update a task.
 */
export async function upsertTask(
  task: Omit<ProjectTask, 'createdAt' | 'updatedAt'>,
): Promise<void> {
  const state = await loadTrackerState()
  const existing = state.tasks.findIndex(t => t.id === task.id)
  const now = Date.now()

  if (existing >= 0) {
    state.tasks[existing] = {
      ...task,
      createdAt: state.tasks[existing]!.createdAt,
      updatedAt: now,
    }
  } else {
    state.tasks.push({
      ...task,
      createdAt: now,
      updatedAt: now,
    })
  }

  await saveTrackerState(state)
}

/**
 * Update the project summary.
 */
export async function updateSummary(summary: string): Promise<void> {
  const state = await loadTrackerState()
  state.summary = summary
  await saveTrackerState(state)
}

/**
 * Get a formatted status report of the project.
 */
export async function getStatusReport(): Promise<string> {
  const state = await loadTrackerState()

  const lines: string[] = []
  lines.push(`# ${state.projectName} — Project Status`)
  lines.push('')

  if (state.summary) {
    lines.push(`## Summary`)
    lines.push(state.summary)
    lines.push('')
  }

  // Active tasks
  const activeTasks = state.tasks.filter(
    t => t.status === 'in-progress' || t.status === 'planned',
  )
  if (activeTasks.length > 0) {
    lines.push(`## Active Tasks`)
    for (const task of activeTasks) {
      const status = task.status === 'in-progress' ? '🔄' : '📋'
      lines.push(`${status} **${task.description}** (${task.status})`)
      if (task.blockedBy) {
        lines.push(`  ⚠️ Blocked by: ${task.blockedBy}`)
      }
    }
    lines.push('')
  }

  // Recent milestones (last 5)
  const recentMilestones = state.milestones.slice(-5)
  if (recentMilestones.length > 0) {
    lines.push(`## Recent Milestones`)
    for (const ms of recentMilestones.reverse()) {
      const date = new Date(ms.completedAt).toLocaleDateString()
      lines.push(`- ✅ ${ms.description} (${date})`)
    }
    lines.push('')
  }

  // Recent decisions (last 5)
  const recentDecisions = state.decisions.slice(-5)
  if (recentDecisions.length > 0) {
    lines.push(`## Key Decisions`)
    for (const dec of recentDecisions.reverse()) {
      const date = new Date(dec.timestamp).toLocaleDateString()
      lines.push(`- **${dec.decision}** — ${dec.rationale} (${date})`)
    }
    lines.push('')
  }

  if (
    activeTasks.length === 0 &&
    recentMilestones.length === 0 &&
    recentDecisions.length === 0
  ) {
    lines.push('No tracked activity yet. Start working and SANDCODE will track your progress.')
  }

  return lines.join('\n')
}

function createFreshState(): ProjectTrackerState {
  return {
    version: 1,
    projectName: basename(getCwd()),
    startedAt: Date.now(),
    decisions: [],
    milestones: [],
    tasks: [],
  }
}
