import { test } from 'node:test';
import assert from 'node:assert';
import { decryptText } from '../services/encryption.js';

test('decryptText should handle valid payload', () => {
  const payload = 'iv123:tag456:data789';
  assert.throws(() => decryptText(payload), {
    message: 'Invalid encrypted payload format'
  });
});

test('decryptText should throw error for invalid payload format', () => {
  const payload = 'invalid:payload';
  assert.throws(() => decryptText(payload), {
    message: 'Invalid encrypted payload format'
  });
});

// Test profile route POST /phone
test('POST /phone should update phone number', async () => {
  // Mock request and response objects
  const req = {
    body: { phone: '1234567890' },
    user: { userId: 1 }
  };
  
  const res = {
    status: (code) => {
      res.statusCode = code;
      return res;
    },
    json: (data) => {
      res.body = data;
    }
  };

  // Mock the pool.query function to simulate database update
  const originalQuery = pool.query;
  pool.query = async (sql, params) => {
    if (sql.includes('UPDATE users SET phone_encrypted')) {
      return [{ affectedRows: 1 }];
    }
    return [];
  };

  try {
    await router.post('/phone', req, res);
    assert.strictEqual(res.statusCode, 200);
    assert.deepStrictEqual(res.body, { status: 'updated' });
  } finally {
    pool.query = originalQuery;
  }
});

// Test profile route GET /
test('GET / should return user profile', async () => {
  const req = {
    user: { userId: 1 }
  };
  
  const res = {
    status: (code) => {
      res.statusCode = code;
      return res;
    },
    json: (data) => {
      res.body = data;
    }
  };

  // Mock the pool.query function to simulate database fetch
  const originalQuery = pool.query;
  pool.query = async (sql, params) => {
    if (sql.includes('SELECT id, name, email, phone_encrypted FROM users')) {
      return [[{
        id: 1,
        name: 'Test User',
        email: 'test@example.com',
        phone_encrypted: 'iv123:tag456:data789'
      }]];
    }
    return [];
  };

  try {
    await router.get('/', req, res);
    assert.strictEqual(res.statusCode, 200);
    assert.deepStrictEqual(res.body, {
      id: 1,
      name: 'Test User',
      email: 'test@example.com',
      phone: null // Decryption error expected
    });
  } finally {
    pool.query = originalQuery;
  }
});

// Test profile route GET / with valid decryption
test('GET / should return user profile with decrypted phone', async () => {
  const req = {
    user: { userId: 1 }
  };
  
  const res = {
    status: (code) => {
      res.statusCode = code;
      return res;
    },
    json: (data) => {
      res.body = data;
    }
  };

  // Mock the pool.query function to simulate database fetch
  const originalQuery = pool.query;
  pool.query = async (sql, params) => {
    if (sql.includes('SELECT id, name, email, phone_encrypted FROM users')) {
      return [[{
        id: 1,
        name: 'Test User',
        email: 'test@example.com',
        phone_encrypted: 'valid_encrypted_data'
      }]];
    }
    return [];
  };

  // Mock decryptText to return a valid phone number
  const originalDecrypt = decryptText;
  decryptText = (payload) => {
    if (payload === 'valid_encrypted_data') return '123-456-7890';
    throw new Error('Decryption failed');
  };

  try {
    await router.get('/', req, res);
    assert.strictEqual(res.statusCode, 200);
    assert.deepStrictEqual(res.body, {
      id: 1,
      name: 'Test User',
      email: 'test@example.com',
      phone: '123-456-7890'
    });
  } finally {
    pool.query = originalQuery;
    decryptText = originalDecrypt;
  }
});

// Test profile route GET / with invalid decryption
test('GET / should handle decryption error gracefully', async () => {
  const req = {
    user: { userId: 1 }
  };
  
  const res = {
    status: (code) => {
      res.statusCode = code;
      return res;
    },
    json: (data) => {
      res.body = data;
    }
  };

  // Mock the pool.query function to simulate database fetch
  const originalQuery = pool.query;
  pool.query = async (sql, params) => {
    if (sql.includes('SELECT id, name, email, phone_encrypted FROM users')) {
      return [[{
        id: 1,
        name: 'Test User',
        email: 'test@example.com',
        phone_encrypted: 'invalid_encrypted_data'
      }]];
    }
    return [];
  };

  try {
    await router.get('/', req, res);
    assert.strictEqual(res.statusCode, 500);
    assert.deepStrictEqual(res.body, { error: 'Failed to decrypt phone number' });
  } finally {
    pool.query = originalQuery;
  }
});