import type { WorkspaceLastViewedTarget } from "@coder-studio/core";
import { z } from "zod";
import { WorkspaceHistoryStore } from "../workspace/history-store.js";
import { registerCommand } from "../ws/dispatch.js";

const WORKSPACE_LAST_VIEWED_TARGET_KEY = "workspace.lastViewedTarget";
const workspaceLastViewedTargetSchema = z.object({
  workspaceId: z.string(),
  sessionId: z.string().optional(),
  updatedAt: z.number(),
});

function parseWorkspaceLastViewedTarget(value: string): WorkspaceLastViewedTarget | null {
  try {
    const parsed = JSON.parse(value);
    const result = workspaceLastViewedTargetSchema.safeParse(parsed);
    return result.success ? result.data : null;
  } catch {
    return null;
  }
}

registerCommand(
  "workspace.activate",
  z.object({
    workspaceId: z.string(),
  }),
  async (args, ctx, clientId) => {
    if (!clientId) {
      return {};
    }

    ctx.autoFetch.registerViewer(clientId, args.workspaceId);
    return {};
  }
);

registerCommand("workspace.deactivate", z.object({}), async (_args, ctx, clientId) => {
  if (!clientId) {
    return {};
  }

  ctx.autoFetch.unregisterViewer(clientId);
  return {};
});

registerCommand("workspace.lastViewedTarget.get", z.object({}), async (_args, ctx) => {
  const value = ctx.settingsRepo.get<unknown>(WORKSPACE_LAST_VIEWED_TARGET_KEY);
  if (value === undefined) {
    return null;
  }

  return parseWorkspaceLastViewedTarget(typeof value === "string" ? value : JSON.stringify(value));
});

registerCommand("workspace.history.list", z.object({}), async (_args, ctx) => {
  return new WorkspaceHistoryStore(ctx.settingsRepo).list();
});

registerCommand(
  "workspace.lastViewedTarget.set",
  z.object({
    workspaceId: z.string(),
    sessionId: z.string().optional(),
  }),
  async (args, ctx) => {
    const workspace = ctx.workspaceMgr.get(args.workspaceId);
    if (!workspace) {
      throw {
        code: "workspace_not_found",
        message: `Workspace not found: ${args.workspaceId}`,
      };
    }

    const session = args.sessionId ? ctx.sessionMgr.get(args.sessionId) : undefined;

    const nextTarget: WorkspaceLastViewedTarget = {
      workspaceId: args.workspaceId,
      sessionId: session && session.workspaceId === args.workspaceId ? session.id : undefined,
      updatedAt: Date.now(),
    };

    ctx.settingsRepo.set(WORKSPACE_LAST_VIEWED_TARGET_KEY, nextTarget);

    return nextTarget;
  }
);
