import { NextResponse } from 'next/server';
import { proxyWorker } from '@/lib/agent-worker-proxy';
import { convexAuthNextjsToken } from '@convex-dev/auth/nextjs/server';
import { fetchMutation, fetchQuery } from 'convex/nextjs';

import type { Id } from '@spoon/backend/convex/_generated/dataModel.js';
import { api } from '@spoon/backend/convex/_generated/api.js';

const activeJobStatuses = new Set([
  'claimed',
  'preparing',
  'running',
  'checks_running',
  'changes_ready',
]);

const activeWorkspaceStatuses = new Set(['active', 'idle']);

export const POST = async (
  request: Request,
  context: { params: Promise<{ threadId: string }> },
) => {
  try {
    const token = await convexAuthNextjsToken();
    if (!token) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }
    const { threadId: rawThreadId } = await context.params;
    const threadId = rawThreadId as Id<'threads'>;
    const body = (await request.json()) as { content?: string };
    const content = body.content?.trim() ?? '';
    if (!content) {
      return NextResponse.json(
        { error: 'Message is required.' },
        { status: 400 },
      );
    }
    const details = await fetchQuery(api.threads.get, { threadId }, { token });
    const latestJob = details.latestJob;
    const canSendToWorker =
      latestJob &&
      activeJobStatuses.has(latestJob.status) &&
      activeWorkspaceStatuses.has(latestJob.workspaceStatus ?? '');

    if (!canSendToWorker) {
      await fetchMutation(
        api.threads.appendUserMessage,
        { threadId, content },
        { token },
      );
      return NextResponse.json({
        success: true,
        mode: 'note',
        message: latestJob
          ? 'Message was added as a thread note because the latest workspace is not active.'
          : 'Message was added as a thread note.',
      });
    }

    const proxied = await proxyWorker(latestJob._id, 'message', {
      method: 'POST',
      body: JSON.stringify({ content }),
    });
    if (!proxied.ok) {
      const text = await proxied.text();
      return NextResponse.json(
        {
          error: text,
          recoverable:
            text.includes('workspace is not active') ||
            text.includes('not active on this worker'),
        },
        { status: proxied.status === 500 ? 409 : proxied.status },
      );
    }
    return proxied;
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    return NextResponse.json({ error: message }, { status: 500 });
  }
};
