import { convexTest } from 'convex-test';
import { afterAll, beforeAll, describe, expect, test } from 'vitest';

import { api } from '../../convex/_generated/api.js';
import schema from '../../convex/schema';

const modules = import.meta.glob('../../convex/**/*.*s');

beforeAll(() => {
  process.env.SPOON_WORKER_TOKEN = 'test-worker-token';
});

afterAll(() => {
  delete process.env.SPOON_WORKER_TOKEN;
});

describe('applyMaintenanceDecision', () => {
  test('resolves a low-risk sync and stops its maintenance job', async () => {
    const t = convexTest(schema, modules);
    const { jobId, threadId } = await t.mutation(async (ctx) => {
      const now = Date.now();
      const ownerId = await ctx.db.insert('users', {
        email: 'maintenance@example.com',
        name: 'Maintenance Reviewer',
      });
      const spoonId = await ctx.db.insert('spoons', {
        ownerId,
        name: 'Maintenance Spoon',
        provider: 'gitea',
        upstreamOwner: 'upstream',
        upstreamRepo: 'maintenance',
        upstreamDefaultBranch: 'main',
        upstreamUrl: 'https://git.example.com/upstream/maintenance',
        forkOwner: 'team',
        forkRepo: 'maintenance-spoon',
        forkUrl: 'https://git.example.com/team/maintenance-spoon',
        visibility: 'private',
        maintenanceMode: 'watch',
        syncCadence: 'daily',
        productionRefStrategy: 'default_branch',
        status: 'active',
        createdAt: now,
        updatedAt: now,
      });
      const requestId = await ctx.db.insert('agentRequests', {
        spoonId,
        ownerId,
        prompt: 'Review upstream maintenance changes',
        requestType: 'upstream_review',
        status: 'running',
        createdAt: now,
        updatedAt: now,
      });
      const threadId = await ctx.db.insert('threads', {
        ownerId,
        spoonId,
        title: 'Upstream maintenance review',
        source: 'upstream_update',
        status: 'running',
        priority: 'normal',
        relatedAgentRequestId: requestId,
        createdAt: now,
        updatedAt: now,
      });
      const jobId = await ctx.db.insert('agentJobs', {
        spoonId,
        ownerId,
        agentRequestId: requestId,
        threadId,
        jobType: 'maintenance_review',
        status: 'running',
        workspaceStatus: 'active',
        prompt: 'Review upstream maintenance changes',
        runtime: 'opencode',
        baseBranch: 'main',
        workBranch: 'spoon/maintenance-review',
        forkOwner: 'team',
        forkRepo: 'maintenance-spoon',
        forkUrl: 'https://git.example.com/team/maintenance-spoon',
        upstreamOwner: 'upstream',
        upstreamRepo: 'maintenance',
        selectedSecretIds: [],
        model: '',
        reasoningEffort: 'medium',
        claimedBy: 'w1',
        createdAt: now,
        updatedAt: now,
      });
      return { jobId, threadId };
    });

    await t.mutation(api.agentJobs.applyMaintenanceDecision, {
      workerToken: 'test-worker-token',
      workerId: 'w1',
      jobId,
      decision: 'sync',
      risk: 'low',
      summary: 'Safe to sync automatically.',
      ignoredCommitShas: [],
      recommendedAction: 'Sync the upstream changes.',
      requiresUserApproval: false,
    });

    const { job, thread } = await t.run(async (ctx) => ({
      job: await ctx.db.get(jobId),
      thread: await ctx.db.get(threadId),
    }));
    expect(thread?.status).toBe('resolved');
    expect(job?.workspaceStatus).toBe('stopped');
    expect(job?.completedAt).toEqual(expect.any(Number));
  });
});
