import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import Fastify from 'fastify';
import cookie from '@fastify/cookie';
import Database from 'better-sqlite3';
import { campaignRoutes } from '../campaign-routes.js';
import { leadRoutes } from '../lead-routes.js';
import { registerAuthMiddleware } from '../../auth/auth-middleware.js';
import { authRoutes } from '../../auth/auth-routes.js';
import { hashPassword } from '../../auth/password.js';
import { runMigrations } from '../../db/migrations.js';
const SECRET = 'test-secret-that-is-at-least-32-chars-long!!';
async function buildApp(db) {
    const app = Fastify();
    await app.register(cookie);
    registerAuthMiddleware(app, SECRET);
    await app.register(authRoutes, { db, jwtSecret: SECRET });
    await app.register(leadRoutes, { db });
    await app.register(campaignRoutes, { db });
    await app.ready();
    return app;
}
async function getAuthCookie(app) {
    const res = await app.inject({
        method: 'POST',
        url: '/api/auth/login',
        payload: { username: 'admin', password: 'admin123' },
    });
    const cookies = res.cookies;
    const accessToken = cookies.find(c => c.name === 'access_token');
    return `access_token=${accessToken.value}`;
}
describe('campaign routes', () => {
    let db;
    let app;
    let authCookie;
    beforeEach(async () => {
        db = new Database(':memory:');
        runMigrations(db);
        const hash = await hashPassword('admin123');
        db.prepare("INSERT INTO users (id, username, password_hash, role, created_at) VALUES (?, ?, ?, ?, ?)").run('admin-id', 'admin', hash, 'admin', new Date().toISOString());
        app = await buildApp(db);
        authCookie = await getAuthCookie(app);
    });
    afterEach(async () => {
        await app?.close();
        db?.close();
    });
    it('POST /api/email/campaigns — creates a campaign', async () => {
        const res = await app.inject({
            method: 'POST',
            url: '/api/email/campaigns',
            headers: { cookie: authCookie },
            payload: {
                name: 'Test Campaign',
                subject: 'Hello',
                body_html: '<p>Hi</p>',
                from_email: 'noreply@test.com',
            },
        });
        expect(res.statusCode).toBe(200);
        const body = JSON.parse(res.payload);
        expect(body.campaign.name).toBe('Test Campaign');
        expect(body.campaign.status).toBe('draft');
    });
    it('GET /api/email/campaigns — lists campaigns', async () => {
        await app.inject({
            method: 'POST',
            url: '/api/email/campaigns',
            headers: { cookie: authCookie },
            payload: { name: 'C1', subject: 'S', body_html: '<p>H</p>', from_email: 'a@b.com' },
        });
        const res = await app.inject({
            method: 'GET',
            url: '/api/email/campaigns',
            headers: { cookie: authCookie },
        });
        expect(res.statusCode).toBe(200);
        const body = JSON.parse(res.payload);
        expect(body.data.length).toBe(1);
    });
    it('GET /api/email/campaigns/:id — returns a campaign', async () => {
        const createRes = await app.inject({
            method: 'POST',
            url: '/api/email/campaigns',
            headers: { cookie: authCookie },
            payload: { name: 'C1', subject: 'S', body_html: '<p>H</p>', from_email: 'a@b.com' },
        });
        const id = JSON.parse(createRes.payload).campaign.id;
        const res = await app.inject({
            method: 'GET',
            url: `/api/email/campaigns/${id}`,
            headers: { cookie: authCookie },
        });
        expect(res.statusCode).toBe(200);
        expect(JSON.parse(res.payload).campaign.id).toBe(id);
    });
    it('POST /:id/enqueue — enqueues recipients', async () => {
        await app.inject({
            method: 'POST',
            url: '/api/email/leads',
            headers: { cookie: authCookie },
            payload: { email: 'recipient@test.com', name: 'Bob' },
        });
        const createRes = await app.inject({
            method: 'POST',
            url: '/api/email/campaigns',
            headers: { cookie: authCookie },
            payload: { name: 'C1', subject: 'S', body_html: '<p>H</p>', from_email: 'a@b.com' },
        });
        const id = JSON.parse(createRes.payload).campaign.id;
        const res = await app.inject({
            method: 'POST',
            url: `/api/email/campaigns/${id}/enqueue`,
            headers: { cookie: authCookie },
            payload: { filters: {} },
        });
        expect(res.statusCode).toBe(200);
        const body = JSON.parse(res.payload);
        expect(body.campaign.status).toBe('queued');
        expect(body.campaign.total_recipients).toBe(1);
    });
    it('POST /:id/start — starts a queued campaign', async () => {
        await app.inject({
            method: 'POST',
            url: '/api/email/leads',
            headers: { cookie: authCookie },
            payload: { email: 'r@t.com' },
        });
        const createRes = await app.inject({
            method: 'POST',
            url: '/api/email/campaigns',
            headers: { cookie: authCookie },
            payload: { name: 'C1', subject: 'S', body_html: '<p>H</p>', from_email: 'a@b.com' },
        });
        const id = JSON.parse(createRes.payload).campaign.id;
        await app.inject({
            method: 'POST',
            url: `/api/email/campaigns/${id}/enqueue`,
            headers: { cookie: authCookie },
            payload: { filters: {} },
        });
        const res = await app.inject({
            method: 'POST',
            url: `/api/email/campaigns/${id}/start`,
            headers: { cookie: authCookie },
        });
        expect(res.statusCode).toBe(200);
        expect(JSON.parse(res.payload).campaign.status).toBe('sending');
    });
    it('POST /:id/cancel — cancels a campaign', async () => {
        await app.inject({
            method: 'POST',
            url: '/api/email/leads',
            headers: { cookie: authCookie },
            payload: { email: 'r@t.com' },
        });
        const createRes = await app.inject({
            method: 'POST',
            url: '/api/email/campaigns',
            headers: { cookie: authCookie },
            payload: { name: 'C1', subject: 'S', body_html: '<p>H</p>', from_email: 'a@b.com' },
        });
        const id = JSON.parse(createRes.payload).campaign.id;
        await app.inject({
            method: 'POST',
            url: `/api/email/campaigns/${id}/enqueue`,
            headers: { cookie: authCookie },
            payload: { filters: {} },
        });
        const res = await app.inject({
            method: 'POST',
            url: `/api/email/campaigns/${id}/cancel`,
            headers: { cookie: authCookie },
        });
        expect(res.statusCode).toBe(200);
        expect(JSON.parse(res.payload).campaign.status).toBe('cancelled');
    });
    it('GET /:id/queue — returns queue items', async () => {
        await app.inject({
            method: 'POST',
            url: '/api/email/leads',
            headers: { cookie: authCookie },
            payload: { email: 'r@t.com' },
        });
        const createRes = await app.inject({
            method: 'POST',
            url: '/api/email/campaigns',
            headers: { cookie: authCookie },
            payload: { name: 'C1', subject: 'S', body_html: '<p>H</p>', from_email: 'a@b.com' },
        });
        const id = JSON.parse(createRes.payload).campaign.id;
        await app.inject({
            method: 'POST',
            url: `/api/email/campaigns/${id}/enqueue`,
            headers: { cookie: authCookie },
            payload: { filters: {} },
        });
        const res = await app.inject({
            method: 'GET',
            url: `/api/email/campaigns/${id}/queue`,
            headers: { cookie: authCookie },
        });
        expect(res.statusCode).toBe(200);
        const body = JSON.parse(res.payload);
        expect(body.data.length).toBe(1);
        expect(body.total).toBe(1);
    });
    it('rejects unauthenticated requests', async () => {
        const res = await app.inject({
            method: 'GET',
            url: '/api/email/campaigns',
        });
        expect(res.statusCode).toBe(401);
    });
});
//# sourceMappingURL=campaign-routes.test.js.map