/**
 * Test file for Namecheap DNS operations
 */
import { expect, tap } from '@push.rocks/tapbundle';
import { createTestClient, TEST_DOMAINS, hasRealCredentials } from './config.js';

// Skip live API tests if no real credentials
const skipLiveTests = !hasRealCredentials();

// Always run this test to ensure the file doesn't fail when all other tests are skipped
tap.test('DNS - Basic Client Test', async () => {
  // Create a client with mock credentials
  const client = createTestClient(true);

  // Verify the client has the expected methods
  expect(client.dns.getHosts).toBeTypeOf('function');
  expect(client.dns.setHosts).toBeTypeOf('function');
  expect(client.dns.setCustom).toBeTypeOf('function');
  expect(client.dns.getEmailForwarding).toBeTypeOf('function');
  expect(client.dns.setEmailForwarding).toBeTypeOf('function');
  expect(client.dns.getList).toBeTypeOf('function');

  // This test always passes
  expect(true).toBeTrue();
});

// Test DNS host records retrieval
if (skipLiveTests) {
  tap.skip.test('DNS - Get Host Records', async () => {
    console.log('Skipping DNS host records test - no credentials');
  });
} else {
  tap.test('DNS - Get Host Records', async (tools) => {
    // Set a timeout for the test
    tools.timeout(15000); // 15 seconds timeout

    // Create a new client instance
    const client = createTestClient();

    // Get DNS host records for a domain
    const hosts = await client.dns.getHosts(TEST_DOMAINS.DNS);

    // Validate the result
    expect(Array.isArray(hosts)).toBeTrue();

    // Log the host records with colored output
    console.log(await tools.coloredString(
      `Found ${hosts.length} DNS records for ${TEST_DOMAINS.DNS}`,
      'cyan'
    ));

    for (const host of hosts) {
      console.log(await tools.coloredString(
        `- ${host.name} (${host.type}): ${host.address} (TTL: ${host.ttl})`,
        host.type === 'A' ? 'green' :
        host.type === 'CNAME' ? 'blue' :
        host.type === 'MX' ? 'red' : 'cyan'
      ));
    }
  });
}

// Test DNS host records modification
if (skipLiveTests) {
  tap.skip.test('DNS - Set Host Records', async () => {
    console.log('Skipping DNS host modification test - no credentials');
  });
} else {
  tap.test('DNS - Set Host Records', async (tools) => {
    // Set a timeout for the test
    tools.timeout(30000); // 30 seconds timeout

    // Create a new client instance
    const client = createTestClient();

    try {
      // First, get the current host records
      const currentHosts = await client.dns.getHosts(TEST_DOMAINS.DNS);

      // Create a new test record
      const testRecordName = `test-${Date.now()}`;
      const newHosts = [
        {
          hostName: testRecordName,
          recordType: 'A' as const,
          address: '192.168.1.1',
          ttl: 300
        },
        // Include all existing records to avoid losing them
        ...currentHosts.map(host => ({
          hostName: host.name,
          recordType: host.type as any,
          address: host.address,
          mxPref: host.type === 'MX' ? host.mxPref : undefined,
          ttl: host.ttl
        }))
      ];

      console.log(await tools.coloredString(
        `Adding test record: ${testRecordName}.${TEST_DOMAINS.DNS} -> 192.168.1.1`,
        'cyan'
      ));

      // Set the host records
      const success = await client.dns.setHosts(TEST_DOMAINS.DNS, newHosts);

      // Validate the result
      expect(success).toBeTrue();

      // Verify the new record was added
      const updatedHosts = await client.dns.getHosts(TEST_DOMAINS.DNS);
      const newRecord = updatedHosts.find(host => host.name === testRecordName);

      expect(newRecord).toBeDefined();
      expect(newRecord?.address).toEqual('192.168.1.1');
      expect(newRecord?.ttl).toEqual(300);

      console.log(await tools.coloredString(
        `Successfully added test record: ${testRecordName}`,
        'green'
      ));

      // Clean up by removing the test record
      const cleanupHosts = currentHosts.map(host => ({
        hostName: host.name,
        recordType: host.type as any,
        address: host.address,
        mxPref: host.type === 'MX' ? host.mxPref : undefined,
        ttl: host.ttl
      }));

      console.log(await tools.coloredString(
        `Cleaning up test record: ${testRecordName}`,
        'cyan'
      ));

      // Restore the original host records
      const cleanupSuccess = await client.dns.setHosts(TEST_DOMAINS.DNS, cleanupHosts);
      expect(cleanupSuccess).toBeTrue();

      console.log(await tools.coloredString(
        `Successfully cleaned up test record`,
        'green'
      ));
    } catch (error) {
      console.error('Error in DNS host records test:', error);
      throw error;
    }
  });
}

// Test email forwarding
if (skipLiveTests) {
  tap.skip.test('DNS - Get Email Forwarding', async () => {
    console.log('Skipping email forwarding test - no credentials');
  });
} else {
  tap.test('DNS - Get Email Forwarding', async (tools) => {
    // Set a timeout for the test
    tools.timeout(15000); // 15 seconds timeout

    // Create a new client instance
    const client = createTestClient();

    try {
      // Get email forwarding settings
      const forwardings = await client.dns.getEmailForwarding(TEST_DOMAINS.DNS);

      // Validate the result
      expect(Array.isArray(forwardings)).toBeTrue();

      // Log the email forwardings with colored output
      console.log(await tools.coloredString(
        `Found ${forwardings.length} email forwardings for ${TEST_DOMAINS.DNS}`,
        'cyan'
      ));

      for (const forward of forwardings) {
        console.log(await tools.coloredString(
          `- ${forward.from}@${TEST_DOMAINS.DNS} → ${forward.to}`,
          'green'
        ));
      }
    } catch (error) {
      // Email forwarding might not be enabled for the domain
      console.log(await tools.coloredString(
        `Email forwarding not available for ${TEST_DOMAINS.DNS}`,
        'blue'
      ));
      console.log(error);
    }
  });
}

// Start the tests
tap.start();