// src/tests/integration/budget.integration.test.ts
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import supertest from 'supertest';
import app from '../../../server';
import { createAndLoginUser } from '../utils/testHelpers';
import { cleanupDb } from '../utils/cleanup';
import type { UserProfile, Budget } from '../../types';
import { getPool } from '../../services/db/connection.db';

/**
 * @vitest-environment node
 */

const request = supertest(app);

describe('Budget API Routes Integration Tests', () => {
  let testUser: UserProfile;
  let authToken: string;
  let testBudget: Budget;
  const createdUserIds: string[] = [];
  const createdBudgetIds: number[] = [];

  beforeAll(async () => {
    // 1. Create a user for the tests
    const { user, token } = await createAndLoginUser({
      email: `budget-user-${Date.now()}@example.com`,
      fullName: 'Budget Test User',
      request,
    });
    testUser = user;
    authToken = token;
    createdUserIds.push(user.user.user_id);

    // 2. Seed some budget data for this user directly in the DB for predictable testing
    const budgetToCreate = {
      name: 'Monthly Groceries',
      amount_cents: 50000, // $500.00
      period: 'monthly',
      start_date: '2025-01-01',
    };

    const budgetRes = await getPool().query(
      `INSERT INTO public.budgets (user_id, name, amount_cents, period, start_date) 
       VALUES ($1, $2, $3, $4, $5) 
       RETURNING *`,
      [testUser.user.user_id, budgetToCreate.name, budgetToCreate.amount_cents, budgetToCreate.period, budgetToCreate.start_date],
    );
    testBudget = budgetRes.rows[0];
    createdBudgetIds.push(testBudget.budget_id);
  });

  afterAll(async () => {
    // Clean up all created resources
    await cleanupDb({
      userIds: createdUserIds,
      budgetIds: createdBudgetIds,
    });
  });

  describe('GET /api/budgets', () => {
    it('should fetch budgets for the authenticated user', async () => {
      const response = await request
        .get('/api/budgets')
        .set('Authorization', `Bearer ${authToken}`);

      expect(response.status).toBe(200);
      const budgets: Budget[] = response.body;
      expect(budgets).toBeInstanceOf(Array);
      expect(budgets.some(b => b.budget_id === testBudget.budget_id)).toBe(true);
    });

    it('should return 401 if user is not authenticated', async () => {
      const response = await request.get('/api/budgets');
      expect(response.status).toBe(401);
    });
  });

  it.todo('should allow an authenticated user to create a new budget');
  it.todo('should allow an authenticated user to update their own budget');
  it.todo('should allow an authenticated user to delete their own budget');
  it.todo('should return spending analysis for the authenticated user');
});