/**
 * SF Command — /backlog
 *
 * Structured backlog management with 999.x numbering.
 * Items live in `.sf/sf.db`.
 * Items can be promoted to active slices via add-slice.
 */
import { mkdirSync } from "node:fs";
import { join } from "node:path";
import { sfRoot } from "./paths.js";
import {
	addBacklogItem as addBacklogItemToDb,
	listBacklogItems,
	openDatabase,
	removeBacklogItem as removeBacklogItemFromDb,
	updateBacklogItemStatus,
} from "./sf-db.js";

function ensureBacklogDb(basePath) {
	const sfDir = sfRoot(basePath);
	mkdirSync(sfDir, { recursive: true });
	return openDatabase(join(sfDir, "sf.db"));
}

function currentItems(basePath) {
	if (!ensureBacklogDb(basePath)) return [];
	return listBacklogItems();
}

async function listBacklog(basePath, ctx) {
	const items = currentItems(basePath);
	if (items.length === 0) {
		ctx.ui.notify(
			"Backlog is empty. Add items with /backlog add <title>",
			"info",
		);
		return;
	}
	const lines = ["Backlog:\n"];
	for (const item of items) {
		const done = item.status === "promoted" || item.status === "done";
		const status = done ? "✓" : "○";
		const note = item.note ? ` (${item.note})` : "";
		lines.push(`  ${status} ${item.id} — ${item.title}${note}`);
	}
	const pending = items.filter((i) => i.status === "pending").length;
	lines.push(`\n${pending} pending, ${items.length - pending} promoted/done`);
	ctx.ui.notify(lines.join("\n"), "info");
}

async function addBacklogItem(basePath, title, ctx) {
	if (!title) {
		ctx.ui.notify("Usage: /backlog add <title>", "warning");
		return;
	}
	if (!ensureBacklogDb(basePath)) {
		ctx.ui.notify("Backlog DB is unavailable; cannot add item.", "warning");
		return;
	}
	const cleanTitle = title.replace(/^['"]|['"]$/g, "");
	const date = new Date().toISOString().slice(0, 10);
	const id = addBacklogItemToDb({
		title: cleanTitle,
		status: "pending",
		note: `added ${date}`,
		source: "manual",
	});
	ctx.ui.notify(`Added ${id}: "${cleanTitle}"`, "success");
}

async function promoteBacklogItem(basePath, itemId, ctx, _pi) {
	if (!itemId) {
		ctx.ui.notify(
			"Usage: /backlog promote <id>\nExample: /backlog promote 999.1",
			"warning",
		);
		return;
	}
	if (!ensureBacklogDb(basePath)) {
		ctx.ui.notify("Backlog DB is unavailable; cannot promote item.", "warning");
		return;
	}
	const item = listBacklogItems().find((i) => i.id === itemId);
	if (!item) {
		ctx.ui.notify(`Backlog item ${itemId} not found.`, "warning");
		return;
	}
	if (item.status === "promoted" || item.status === "done") {
		ctx.ui.notify(`${itemId} is already promoted/done.`, "info");
		return;
	}
	updateBacklogItemStatus(
		itemId,
		"promoted",
		`promoted ${new Date().toISOString().slice(0, 10)}`,
	);
	ctx.ui.notify(
		`Promoted ${itemId}: "${item.title}" — add it to the roadmap manually or use the slice planning tools.`,
		"info",
	);
}

async function removeBacklogItem(basePath, itemId, ctx) {
	if (!itemId) {
		ctx.ui.notify("Usage: /backlog remove <id>", "warning");
		return;
	}
	if (!ensureBacklogDb(basePath)) {
		ctx.ui.notify("Backlog DB is unavailable; cannot remove item.", "warning");
		return;
	}
	const item = listBacklogItems().find((i) => i.id === itemId);
	if (!item) {
		ctx.ui.notify(`Backlog item ${itemId} not found.`, "warning");
		return;
	}
	removeBacklogItemFromDb(itemId);
	ctx.ui.notify(`Removed ${item.id}: "${item.title}"`, "success");
}

export async function handleBacklog(args, ctx, pi) {
	const basePath = process.cwd();
	const parts = args.trim().split(/\s+/);
	const sub = parts[0] ?? "";
	const rest = parts.slice(1).join(" ");
	switch (sub) {
		case "":
			return listBacklog(basePath, ctx);
		case "add":
			return addBacklogItem(basePath, rest, ctx);
		case "promote":
			return promoteBacklogItem(basePath, rest.trim(), ctx, pi);
		case "remove":
			return removeBacklogItem(basePath, rest.trim(), ctx);
		default:
			return addBacklogItem(basePath, args, ctx);
	}
}
