import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { buildApp } from '../../app.js';
describe('kanban routes', () => {
    let app;
    let cookie;
    beforeAll(async () => {
        app = await buildApp({ config: { jwtSecret: 'test-secret-kanban' } });
        await app.ready();
        // Clean up any leftover kanban tasks from previous runs
        app.db.prepare('DELETE FROM kanban_tasks').run();
        const loginRes = await app.inject({
            method: 'POST',
            url: '/api/auth/login',
            payload: { username: 'admin', password: 'admin' },
        });
        const cookies = loginRes.cookies;
        const access = cookies.find((c) => c.name === 'access_token');
        const refresh = cookies.find((c) => c.name === 'refresh_token');
        cookie = `access_token=${access.value}; refresh_token=${refresh.value}`;
    });
    afterAll(async () => {
        await app.close();
    });
    it('GET /api/kanban/:squad/tasks — returns empty array initially', async () => {
        const res = await app.inject({
            method: 'GET',
            url: '/api/kanban/test-squad/tasks',
            headers: { cookie },
        });
        expect(res.statusCode).toBe(200);
        expect(res.json()).toEqual([]);
    });
    it('POST /api/kanban/:squad/tasks — creates a task', async () => {
        const res = await app.inject({
            method: 'POST',
            url: '/api/kanban/test-squad/tasks',
            headers: { cookie },
            payload: { title: 'Research competitors', description: 'Analyze top 5' },
        });
        expect(res.statusCode).toBe(201);
        const task = res.json();
        expect(task.title).toBe('Research competitors');
        expect(task.description).toBe('Analyze top 5');
        expect(task.status).toBe('planned');
        expect(task.squad_code).toBe('test-squad');
        expect(task.id).toBeDefined();
    });
    it('POST rejects empty title', async () => {
        const res = await app.inject({
            method: 'POST',
            url: '/api/kanban/test-squad/tasks',
            headers: { cookie },
            payload: { title: '  ' },
        });
        expect(res.statusCode).toBe(400);
    });
    it('POST rejects invalid status', async () => {
        const res = await app.inject({
            method: 'POST',
            url: '/api/kanban/test-squad/tasks',
            headers: { cookie },
            payload: { title: 'Task', status: 'invalid' },
        });
        expect(res.statusCode).toBe(400);
    });
    it('GET returns created tasks', async () => {
        const res = await app.inject({
            method: 'GET',
            url: '/api/kanban/test-squad/tasks',
            headers: { cookie },
        });
        expect(res.statusCode).toBe(200);
        const tasks = res.json();
        expect(tasks.length).toBeGreaterThanOrEqual(1);
        expect(tasks[0]).toHaveProperty('title');
        expect(tasks[0]).toHaveProperty('status');
    });
    it('PATCH /api/kanban/:squad/tasks/:id — updates status with timestamps', async () => {
        // Create a task
        const createRes = await app.inject({
            method: 'POST',
            url: '/api/kanban/test-squad/tasks',
            headers: { cookie },
            payload: { title: 'Write report' },
        });
        const task = createRes.json();
        expect(task.started_at).toBeNull();
        // Move to executing — started_at should be set
        const execRes = await app.inject({
            method: 'PATCH',
            url: `/api/kanban/test-squad/tasks/${task.id}`,
            headers: { cookie },
            payload: { status: 'executing' },
        });
        expect(execRes.statusCode).toBe(200);
        const executing = execRes.json();
        expect(executing.status).toBe('executing');
        expect(executing.started_at).toBeTruthy();
        expect(executing.finished_at).toBeNull();
        // Move to done — finished_at should be set
        const doneRes = await app.inject({
            method: 'PATCH',
            url: `/api/kanban/test-squad/tasks/${task.id}`,
            headers: { cookie },
            payload: { status: 'done' },
        });
        const done = doneRes.json();
        expect(done.status).toBe('done');
        expect(done.started_at).toBeTruthy();
        expect(done.finished_at).toBeTruthy();
    });
    it('PATCH stores result text', async () => {
        const createRes = await app.inject({
            method: 'POST',
            url: '/api/kanban/test-squad/tasks',
            headers: { cookie },
            payload: { title: 'Task with result' },
        });
        const task = createRes.json();
        const patchRes = await app.inject({
            method: 'PATCH',
            url: `/api/kanban/test-squad/tasks/${task.id}`,
            headers: { cookie },
            payload: { status: 'done', result: 'Report generated with 5 pages' },
        });
        const updated = patchRes.json();
        expect(updated.result).toBe('Report generated with 5 pages');
    });
    it('GET /api/kanban/:squad/tasks/:id — returns single task', async () => {
        const createRes = await app.inject({
            method: 'POST',
            url: '/api/kanban/test-squad/tasks',
            headers: { cookie },
            payload: { title: 'Single fetch task', description: 'Detail test' },
        });
        const task = createRes.json();
        const getRes = await app.inject({
            method: 'GET',
            url: `/api/kanban/test-squad/tasks/${task.id}`,
            headers: { cookie },
        });
        expect(getRes.statusCode).toBe(200);
        const fetched = getRes.json();
        expect(fetched.title).toBe('Single fetch task');
        expect(fetched.description).toBe('Detail test');
    });
    it('PATCH returns 404 for non-existent task', async () => {
        const res = await app.inject({
            method: 'PATCH',
            url: '/api/kanban/test-squad/tasks/nonexistent-id',
            headers: { cookie },
            payload: { status: 'done' },
        });
        expect(res.statusCode).toBe(404);
    });
    it('PATCH rejects invalid status', async () => {
        const createRes = await app.inject({
            method: 'POST',
            url: '/api/kanban/test-squad/tasks',
            headers: { cookie },
            payload: { title: 'Temp task' },
        });
        const task = createRes.json();
        const res = await app.inject({
            method: 'PATCH',
            url: `/api/kanban/test-squad/tasks/${task.id}`,
            headers: { cookie },
            payload: { status: 'invalid' },
        });
        expect(res.statusCode).toBe(400);
    });
    it('DELETE /api/kanban/:squad/tasks/:id — removes a task', async () => {
        const createRes = await app.inject({
            method: 'POST',
            url: '/api/kanban/test-squad/tasks',
            headers: { cookie },
            payload: { title: 'To be deleted' },
        });
        const task = createRes.json();
        const deleteRes = await app.inject({
            method: 'DELETE',
            url: `/api/kanban/test-squad/tasks/${task.id}`,
            headers: { cookie },
        });
        expect(deleteRes.statusCode).toBe(204);
        // Verify it's gone
        const getRes = await app.inject({
            method: 'GET',
            url: '/api/kanban/test-squad/tasks',
            headers: { cookie },
        });
        const tasks = getRes.json();
        expect(tasks.find((t) => t.id === task.id)).toBeUndefined();
    });
    it('DELETE returns 404 for non-existent task', async () => {
        const res = await app.inject({
            method: 'DELETE',
            url: '/api/kanban/test-squad/tasks/nonexistent',
            headers: { cookie },
        });
        expect(res.statusCode).toBe(404);
    });
    it('rejects unauthenticated requests', async () => {
        const res = await app.inject({
            method: 'GET',
            url: '/api/kanban/test-squad/tasks',
        });
        expect(res.statusCode).toBe(401);
    });
    it('tasks are scoped per squad', async () => {
        // Create task in squad-a
        await app.inject({
            method: 'POST',
            url: '/api/kanban/squad-a/tasks',
            headers: { cookie },
            payload: { title: 'Squad A task' },
        });
        // squad-b should have no tasks
        const res = await app.inject({
            method: 'GET',
            url: '/api/kanban/squad-b/tasks',
            headers: { cookie },
        });
        expect(res.json()).toEqual([]);
    });
    it('POST accepts failed status', async () => {
        const res = await app.inject({
            method: 'POST',
            url: '/api/kanban/test-squad/tasks',
            headers: { cookie },
            payload: { title: 'Failed task', status: 'failed' },
        });
        expect(res.statusCode).toBe(201);
        expect(res.json().status).toBe('failed');
    });
    it('PATCH accepts failed status', async () => {
        const createRes = await app.inject({
            method: 'POST',
            url: '/api/kanban/test-squad/tasks',
            headers: { cookie },
            payload: { title: 'Will fail' },
        });
        const task = createRes.json();
        const patchRes = await app.inject({
            method: 'PATCH',
            url: `/api/kanban/test-squad/tasks/${task.id}`,
            headers: { cookie },
            payload: { status: 'failed' },
        });
        expect(patchRes.statusCode).toBe(200);
        expect(patchRes.json().status).toBe('failed');
        expect(patchRes.json().finished_at).toBeTruthy();
    });
    it('GET /api/kanban/tasks — returns tasks from all squads', async () => {
        await app.inject({
            method: 'POST',
            url: '/api/kanban/alpha/tasks',
            headers: { cookie },
            payload: { title: 'Alpha task' },
        });
        await app.inject({
            method: 'POST',
            url: '/api/kanban/beta/tasks',
            headers: { cookie },
            payload: { title: 'Beta task' },
        });
        const res = await app.inject({
            method: 'GET',
            url: '/api/kanban/tasks',
            headers: { cookie },
        });
        expect(res.statusCode).toBe(200);
        const tasks = res.json();
        const codes = tasks.map((t) => t.squad_code);
        expect(codes).toContain('alpha');
        expect(codes).toContain('beta');
    });
    it('GET /api/kanban/tasks — supports status filter', async () => {
        await app.inject({
            method: 'POST',
            url: '/api/kanban/filter-squad/tasks',
            headers: { cookie },
            payload: { title: 'Planned', status: 'planned' },
        });
        await app.inject({
            method: 'POST',
            url: '/api/kanban/filter-squad/tasks',
            headers: { cookie },
            payload: { title: 'Executing', status: 'executing' },
        });
        const res = await app.inject({
            method: 'GET',
            url: '/api/kanban/tasks?status=planned',
            headers: { cookie },
        });
        const tasks = res.json();
        expect(tasks.every((t) => t.status === 'planned')).toBe(true);
    });
    it('GET /api/kanban/tasks — supports pagination', async () => {
        const res = await app.inject({
            method: 'GET',
            url: '/api/kanban/tasks?limit=2&offset=0',
            headers: { cookie },
        });
        expect(res.statusCode).toBe(200);
        expect(res.json().length).toBeLessThanOrEqual(2);
    });
    it('GET /api/kanban/tasks — rejects unauthenticated', async () => {
        const res = await app.inject({
            method: 'GET',
            url: '/api/kanban/tasks',
        });
        expect(res.statusCode).toBe(401);
    });
});
//# sourceMappingURL=kanban-routes.test.js.map