import { beforeEach, afterEach, describe, expect, it } from 'bun:test';
import { createTempDb } from './helpers/db';

// Reutilizamos el estilo de import dinámico del handler como en otros tests web.

describe('Web API - completar tarea (rutas de error y gating)', () => {
  let cleanup: () => void;
  let db: any;
  let path: string;

  const USER = '34600123456';
  const GROUP_ID = '12345-67890@g.us';

  beforeEach(() => {
    const tmp = createTempDb();
    cleanup = tmp.cleanup;
    db = tmp.db;
    path = tmp.path;

    process.env.NODE_ENV = 'test';
    process.env.DB_PATH = path;
    process.env.REACTIONS_ENABLED = 'true';
    process.env.REACTIONS_SCOPE = 'groups';
    process.env.REACTIONS_TTL_DAYS = '14';
    process.env.GROUP_GATING_MODE = 'enforce';
  });

  afterEach(async () => {
    try {
      const { getDb } = await import('../../apps/web/src/lib/server/db.ts');
      await getDb();
    } catch {}
    if (cleanup) cleanup();
    delete process.env.DB_PATH;
    delete process.env.REACTIONS_ENABLED;
    delete process.env.REACTIONS_SCOPE;
    delete process.env.REACTIONS_TTL_DAYS;
    delete process.env.GROUP_GATING_MODE;
  });

  it('401 si no hay session (userId)', async () => {
    const event: any = {
      locals: { userId: null },
      params: { id: '1' },
      request: new Request('http://localhost', { method: 'POST' })
    };
    const { POST: completeHandler } = await import('../../apps/web/src/routes/api/tasks/[id]/complete/+server.ts');
    const res = await completeHandler(event);
    expect(res.status).toBe(401);
  });

  it('400 si id no es válido', async () => {
    const event: any = {
      locals: { userId: USER },
      params: { id: 'abc' },
      request: new Request('http://localhost', { method: 'POST' })
    };
    const { POST: completeHandler } = await import('../../apps/web/src/routes/api/tasks/[id]/complete/+server.ts');
    const res = await completeHandler(event);
    expect(res.status).toBe(400);
  });

  it('404 si la tarea no existe', async () => {
    const event: any = {
      locals: { userId: USER },
      params: { id: '999999' },
      request: new Request('http://localhost', { method: 'POST' })
    };
    // Sembrar usuario para evitar FKs indirectas (no imprescindible aquí)
    db.prepare(`INSERT OR IGNORE INTO users (id) VALUES (?)`).run(USER);

    const { POST: completeHandler } = await import('../../apps/web/src/routes/api/tasks/[id]/complete/+server.ts');
    const res = await completeHandler(event);
    expect(res.status).toBe(404);
  });

  it('403 si grupo no allowed', async () => {
    db.prepare(`INSERT OR IGNORE INTO users (id) VALUES (?)`).run(USER);
    // Asegurar fila del grupo para satisfacer FKs (sin marcarlo como allowed)
    db.prepare(`INSERT OR IGNORE INTO groups (id, community_id, name, active) VALUES (?, 'comm', 'G', 1)`).run(GROUP_ID);
    // Tarea con group_id; no insertamos en allowed_groups
    const taskId = Number(
      db.prepare(`
        INSERT INTO tasks (description, due_date, group_id, created_by, completed, completed_at)
        VALUES ('No allowed', NULL, ?, ?, 0, NULL)
      `).run(GROUP_ID, USER).lastInsertRowid
    );

    // El usuario podría incluso ser miembro activo; sigue siendo 403 por falta de allowed
    db.prepare(`INSERT OR REPLACE INTO group_members (group_id, user_id, is_admin, is_active) VALUES (?, ?, 0, 1)`).run(GROUP_ID, USER);

    const event: any = {
      locals: { userId: USER },
      params: { id: String(taskId) },
      request: new Request('http://localhost', { method: 'POST' })
    };
    const { POST: completeHandler } = await import('../../apps/web/src/routes/api/tasks/[id]/complete/+server.ts');
    const res = await completeHandler(event);
    expect(res.status).toBe(403);
  });

  it('403 si grupo allowed pero usuario no es miembro activo', async () => {
    db.prepare(`INSERT OR IGNORE INTO users (id) VALUES (?)`).run(USER);
    db.prepare(`INSERT OR IGNORE INTO groups (id, community_id, name, active) VALUES (?, 'comm', 'G', 1)`).run(GROUP_ID);
    db.prepare(`INSERT OR REPLACE INTO allowed_groups (group_id, label, status) VALUES (?, 'G', 'allowed')`).run(GROUP_ID);

    const taskId = Number(
      db.prepare(`
        INSERT INTO tasks (description, due_date, group_id, created_by, completed, completed_at)
        VALUES ('No active member', NULL, ?, ?, 0, NULL)
      `).run(GROUP_ID, USER).lastInsertRowid
    );

    // No sembramos group_members activo para USER

    const event: any = {
      locals: { userId: USER },
      params: { id: String(taskId) },
      request: new Request('http://localhost', { method: 'POST' })
    };
    const { POST: completeHandler } = await import('../../apps/web/src/routes/api/tasks/[id]/complete/+server.ts');
    const res = await completeHandler(event);
    expect(res.status).toBe(403);
  });

  it('403 en tarea personal si no está asignada al usuario', async () => {
    db.prepare(`INSERT OR IGNORE INTO users (id) VALUES (?)`).run(USER);
    const taskId = Number(
      db.prepare(`
        INSERT INTO tasks (description, due_date, group_id, created_by, completed, completed_at)
        VALUES ('Personal sin asignación', NULL, NULL, ?, 0, NULL)
      `).run(USER).lastInsertRowid
    );

    // No insertamos task_assignments

    const event: any = {
      locals: { userId: USER },
      params: { id: String(taskId) },
      request: new Request('http://localhost', { method: 'POST' })
    };
    const { POST: completeHandler } = await import('../../apps/web/src/routes/api/tasks/[id]/complete/+server.ts');
    const res = await completeHandler(event);
    expect(res.status).toBe(403);
  });
});
