/**
 * parallel-monitor-store.js — read-only projections for parallel worker monitors.
 *
 * Purpose: centralize the Node SQLite reads used by the standalone monitor and
 * TUI overlay so parallel worker status is rendered from one DB-first contract.
 *
 * Consumer: `scripts/parallel-monitor.mjs` and `parallel-monitor-overlay.js`.
 */

import { existsSync } from "node:fs";
import { join } from "node:path";
import { DatabaseSync } from "node:sqlite";

function queryRows(dbPath, sql, params = []) {
	const db = new DatabaseSync(dbPath, { readOnly: true });
	try {
		return db
			.prepare(sql)
			.all(...params)
			.map((row) => ({ ...row }));
	} finally {
		db.close();
	}
}

/**
 * Resolve the canonical DB path for a parallel worker worktree.
 *
 * Purpose: keep monitor-side DB reads pointed at the worker-owned `.sf/sf.db`
 * projection instead of ad hoc sidecar files.
 *
 * Consumer: monitor projection query helpers in this module.
 */
export function getParallelWorkerDbPath(basePath, milestoneId) {
	return join(basePath, ".sf", "worktrees", milestoneId, ".sf", "sf.db");
}

/**
 * Read slice/task progress for one parallel worker.
 *
 * Purpose: render worker progress from structured task rows so the script and
 * overlay do not drift into separate SQL contracts.
 *
 * Consumer: parallel monitor script and TUI overlay worker summaries.
 */
export function queryParallelSliceProgress(basePath, milestoneId) {
	const dbPath = getParallelWorkerDbPath(basePath, milestoneId);
	if (!existsSync(dbPath)) return [];

	try {
		return queryRows(
			dbPath,
			`SELECT s.id AS id,
			        s.status AS status,
			        COUNT(t.id) AS total,
			        SUM(CASE WHEN t.task_status='done' THEN 1 ELSE 0 END) AS done
			   FROM slices s
			   LEFT JOIN tasks t ON s.milestone_id=t.milestone_id AND s.id=t.slice_id
			  WHERE s.milestone_id=?
			  GROUP BY s.id
			  ORDER BY s.id`,
			[milestoneId],
		).map((row) => ({
			id: row.id,
			status: row.status,
			total: Number(row.total ?? 0),
			done: Number(row.done ?? 0),
		}));
	} catch {
		return [];
	}
}

/**
 * Read recently completed task rows for one parallel worker.
 *
 * Purpose: feed completion events from the same structured state used for
 * dispatch instead of scraping monitor logs for finished work.
 *
 * Consumer: parallel monitor script and TUI overlay event feeds.
 */
export function queryParallelRecentCompletionRows(
	basePath,
	milestoneId,
	limit = 5,
) {
	const dbPath = getParallelWorkerDbPath(basePath, milestoneId);
	if (!existsSync(dbPath)) return [];

	try {
		return queryRows(
			dbPath,
			`SELECT id AS taskId,
			        slice_id AS sliceId,
			        one_liner AS oneLiner,
			        completed_at AS completedAt
			   FROM tasks
			  WHERE milestone_id=?
			    AND task_status='done'
			    AND completed_at IS NOT NULL
			  ORDER BY completed_at DESC
			  LIMIT ?`,
			[milestoneId, limit],
		);
	} catch {
		return [];
	}
}
