// src/tests/e2e/user-journey.e2e.test.ts
import { describe, it, expect, afterAll } from 'vitest';
import supertest from 'supertest';
import app from '../../../server';
import { getPool } from '../../services/db/connection.db';

/**
 * @vitest-environment node
 */

const request = supertest(app);

describe('E2E User Journey', () => {
  // Use a unique email for every run to avoid collisions
  const uniqueId = Date.now();
  const userEmail = `e2e-test-${uniqueId}@example.com`;
  const userPassword = 'StrongPassword123!';
  
  let authToken: string;
  let userId: string | null = null;
  let shoppingListId: number;

  afterAll(async () => {
    // Safety cleanup: Ensure the user is deleted from the DB if the test fails mid-way.
    // If the test succeeds, the user deletes their own account, so this acts as a fallback.
    if (userId) {
      try {
        await getPool().query('DELETE FROM public.users WHERE user_id = $1', [userId]);
      } catch (err) {
        console.error('Error cleaning up E2E test user:', err);
      }
    }
  });

  it('should complete a full user lifecycle: Register -> Login -> Manage List -> Delete Account', async () => {
    // 1. Register a new user
    const registerResponse = await request.post('/api/auth/register').send({
      email: userEmail,
      password: userPassword,
      full_name: 'E2E Traveler',
    });

    expect(registerResponse.status).toBe(201);
    expect(registerResponse.body.message).toBe('User registered successfully!');
    
    // 2. Login to get the access token
    const loginResponse = await request.post('/api/auth/login').send({
      email: userEmail,
      password: userPassword,
    });

    expect(loginResponse.status).toBe(200);
    authToken = loginResponse.body.token;
    userId = loginResponse.body.userprofile.user.user_id;
    
    expect(authToken).toBeDefined();
    expect(userId).toBeDefined();

    // 3. Create a Shopping List
    const createListResponse = await request
      .post('/api/users/shopping-lists')
      .set('Authorization', `Bearer ${authToken}`)
      .send({ name: 'E2E Party List' });

    expect(createListResponse.status).toBe(201);
    shoppingListId = createListResponse.body.shopping_list_id;
    expect(shoppingListId).toBeDefined();

    // 4. Add an item to the list
    const addItemResponse = await request
      .post(`/api/users/shopping-lists/${shoppingListId}/items`)
      .set('Authorization', `Bearer ${authToken}`)
      .send({ customItemName: 'Chips' });

    expect(addItemResponse.status).toBe(201);
    expect(addItemResponse.body.custom_item_name).toBe('Chips');

    // 5. Verify the list and item exist via GET
    const getListsResponse = await request
      .get('/api/users/shopping-lists')
      .set('Authorization', `Bearer ${authToken}`);

    expect(getListsResponse.status).toBe(200);
    const myLists = getListsResponse.body;
    const targetList = myLists.find((l: any) => l.shopping_list_id === shoppingListId);
    
    expect(targetList).toBeDefined();
    expect(targetList.items).toHaveLength(1);
    expect(targetList.items[0].custom_item_name).toBe('Chips');

    // 6. Delete the User Account (Self-Service)
    const deleteAccountResponse = await request
      .delete('/api/users/account')
      .set('Authorization', `Bearer ${authToken}`)
      .send({ password: userPassword });

    expect(deleteAccountResponse.status).toBe(200);
    expect(deleteAccountResponse.body.message).toBe('Account deleted successfully.');

    // 7. Verify Login is no longer possible
    const failLoginResponse = await request.post('/api/auth/login').send({
      email: userEmail,
      password: userPassword,
    });

    expect(failLoginResponse.status).toBe(401);
    
    // Mark userId as null so afterAll doesn't attempt to delete it again
    userId = null;
  });
});
