import type { Tool } from "@modelcontextprotocol/sdk/types.js";
import {
  listChanges,
  pruneHistory,
  getChangeStats,
  readSnapshotById,
} from "@mandujs/core/change";

export const historyToolDefinitions: Tool[] = [
  {
    name: "mandu.history.list",
    description: "List the change history with snapshots",
    annotations: {
      readOnlyHint: true,
    },
    inputSchema: {
      type: "object",
      properties: {
        limit: {
          type: "number",
          description: "Maximum number of entries to return (default: 10)",
        },
      },
      required: [],
    },
  },
  {
    name: "mandu.history.snapshot",
    description: "Get details of a specific snapshot",
    annotations: {
      readOnlyHint: true,
    },
    inputSchema: {
      type: "object",
      properties: {
        snapshotId: {
          type: "string",
          description: "The snapshot ID to retrieve",
        },
      },
      required: ["snapshotId"],
    },
  },
  {
    name: "mandu.history.prune",
    description: "Remove old snapshots to free up space",
    annotations: {
      destructiveHint: true,
      readOnlyHint: false,
    },
    inputSchema: {
      type: "object",
      properties: {
        keepCount: {
          type: "number",
          description: "Number of snapshots to keep (default: 5)",
        },
      },
      required: [],
    },
  },
];

export function historyTools(projectRoot: string) {
  const handlers: Record<string, (args: Record<string, unknown>) => Promise<unknown>> = {
    "mandu.history.list": async (args: Record<string, unknown>) => {
      const { limit = 10 } = args as { limit?: number };

      const changes = await listChanges(projectRoot);
      const stats = await getChangeStats(projectRoot);

      // Sort by createdAt descending and limit
      const sortedChanges = changes
        .sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())
        .slice(0, limit);

      return {
        changes: sortedChanges.map((c) => ({
          id: c.id,
          message: c.message,
          status: c.status,
          createdAt: c.createdAt,
          snapshotId: c.snapshotId,
          autoGenerated: c.autoGenerated,
        })),
        stats: {
          total: stats.total,
          active: stats.active,
          committed: stats.committed,
          rolledBack: stats.rolledBack,
          snapshotCount: stats.snapshotCount,
        },
      };
    },

    "mandu.history.snapshot": async (args: Record<string, unknown>) => {
      const { snapshotId } = args as { snapshotId: string };

      const snapshot = await readSnapshotById(projectRoot, snapshotId);
      if (!snapshot) {
        return { error: `Snapshot not found: ${snapshotId}` };
      }

      const slotFiles = Object.keys(snapshot.slotContents);

      return {
        id: snapshot.id,
        timestamp: snapshot.timestamp,
        manifest: {
          version: snapshot.manifest.version,
          routeCount: snapshot.manifest.routes.length,
          routes: snapshot.manifest.routes.map((r) => ({
            id: r.id,
            pattern: r.pattern,
            kind: r.kind,
          })),
        },
        hasLock: !!snapshot.lock,
        lock: snapshot.lock
          ? {
              routesHash: snapshot.lock.routesHash,
              updatedAt: snapshot.lock.updatedAt,
            }
          : null,
        slotFiles,
        slotCount: slotFiles.length,
      };
    },

    "mandu.history.prune": async (args: Record<string, unknown>) => {
      const { keepCount = 5 } = args as { keepCount?: number };

      const deletedIds = await pruneHistory(projectRoot, keepCount);

      const stats = await getChangeStats(projectRoot);

      return {
        success: true,
        deletedCount: deletedIds.length,
        deletedIds,
        remaining: {
          snapshotCount: stats.snapshotCount,
          changeCount: stats.total,
        },
      };
    },
  };

  // Backward-compatible aliases (deprecated)
  handlers["mandu_list_history"] = handlers["mandu.history.list"];
  handlers["mandu_get_snapshot"] = handlers["mandu.history.snapshot"];
  handlers["mandu_prune_history"] = handlers["mandu.history.prune"];

  return handlers;
}
