import { test, expect, Page } from '@playwright/test';
import * as path from 'path';

// Test data
const testEmail = `user+profile-${Date.now()}@lab.veza`;
const testPassword = `V3za!profile-${Date.now()}`;
const avatarPath = path.join(__dirname, '../../data/images/avatar.jpg');

// Helper to register and login
async function registerAndLogin(page: Page) {
  await page.goto('/register');
  await page.fill('input[type="email"]', testEmail);
  await page.fill('input[type="password"]', testPassword);
  
  const confirmField = page.locator('input[name="confirmPassword"]');
  if (await confirmField.isVisible()) {
    await confirmField.fill(testPassword);
  }
  
  await page.locator('button[type="submit"]').click();
  await expect(page).toHaveURL(/\/(dashboard|home|app|profile)/, { timeout: 10000 });
}

test.describe('User Profile Management', () => {
  test.beforeEach(async ({ page }) => {
    await registerAndLogin(page);
  });

  test('should load profile page', async ({ page }) => {
    await page.goto('/profile');
    
    // Check main elements
    await expect(page.locator('[data-testid="profile-container"], .profile-container, #profile')).toBeVisible();
    
    // Should show user email
    await expect(page.locator(`text="${testEmail}"`)).toBeVisible();
    
    // Should have edit button
    await expect(page.locator('button:has-text("Edit"), [data-testid="edit-profile"]')).toBeVisible();
  });

  test('should display user information', async ({ page }) => {
    await page.goto('/profile');
    
    // Check for user fields
    await expect(page.locator('text=/email/i').locator('xpath=following-sibling::*')).toContainText(testEmail);
    
    // Check for other profile fields
    const fields = ['nickname', 'username', 'display name', 'bio', 'about'];
    for (const field of fields) {
      const fieldElement = page.locator(`text=/${field}/i`);
      if (await fieldElement.isVisible({ timeout: 1000 }).catch(() => false)) {
        // Field exists in profile
        expect(fieldElement).toBeTruthy();
      }
    }
  });

  test('should edit profile nickname', async ({ page }) => {
    await page.goto('/profile');
    
    // Click edit button
    await page.locator('button:has-text("Edit"), [data-testid="edit-profile"]').click();
    
    // Find nickname field
    const nicknameInput = page.locator('input[name="nickname"], input[placeholder*="nickname"], input[aria-label*="nickname"]');
    
    if (await nicknameInput.isVisible()) {
      const newNickname = `TestUser${Date.now()}`;
      await nicknameInput.fill(newNickname);
      
      // Save changes
      await page.locator('button:has-text("Save"), button[type="submit"]').click();
      
      // Should show success message
      await expect(page.locator('text=/success|updated|saved/i')).toBeVisible({ timeout: 5000 });
      
      // Nickname should be updated
      await expect(page.locator(`text="${newNickname}"`)).toBeVisible();
    }
  });

  test('should upload avatar image', async ({ page }) => {
    await page.goto('/profile');
    
    // Find avatar upload
    const avatarSection = page.locator('[data-testid="avatar-section"], .avatar-section');
    const uploadButton = avatarSection.locator('button:has-text("Upload"), button:has-text("Change"), input[type="file"]');
    
    if (await uploadButton.isVisible()) {
      // Upload avatar
      if (uploadButton.locator('input[type="file"]').isVisible()) {
        await uploadButton.setInputFiles(avatarPath);
      } else {
        await uploadButton.click();
        const fileInput = page.locator('input[type="file"][accept*="image"]');
        await fileInput.setInputFiles(avatarPath);
      }
      
      // Wait for upload
      await expect(page.locator('text=/upload.*success|avatar.*updated/i')).toBeVisible({ timeout: 10000 });
      
      // Avatar should be visible
      const avatarImg = page.locator('img[alt*="avatar"], img[alt*="profile"], .avatar img');
      await expect(avatarImg).toBeVisible();
      
      const src = await avatarImg.getAttribute('src');
      expect(src).not.toContain('default');
      expect(src).not.toContain('placeholder');
    }
  });

  test('should validate profile form inputs', async ({ page }) => {
    await page.goto('/profile');
    
    // Enter edit mode
    await page.locator('button:has-text("Edit")').click();
    
    // Test bio/about character limit
    const bioInput = page.locator('textarea[name="bio"], textarea[name="about"]');
    
    if (await bioInput.isVisible()) {
      // Try to enter very long text
      const longText = 'a'.repeat(1000);
      await bioInput.fill(longText);
      
      // Should show character count or limit
      const charCount = page.locator('.char-count, .character-count, text=/\\d+.*\\/.*\\d+/');
      if (await charCount.isVisible()) {
        const count = await charCount.textContent();
        expect(count).toMatch(/\d+/);
      }
    }
    
    // Test URL field validation
    const websiteInput = page.locator('input[name="website"], input[type="url"]');
    
    if (await websiteInput.isVisible()) {
      await websiteInput.fill('not-a-url');
      await page.locator('button:has-text("Save")').click();
      
      // Should show validation error
      await expect(page.locator('text=/invalid.*url|valid.*url/i')).toBeVisible();
    }
  });

  test('should show account creation date', async ({ page }) => {
    await page.goto('/profile');
    
    // Look for join date/created date
    const datePattern = page.locator('text=/joined|created|member since/i');
    
    if (await datePattern.isVisible()) {
      const dateText = await datePattern.locator('xpath=following-sibling::*').textContent();
      expect(dateText).toMatch(/\d{4}|\d{1,2}.*\d{1,2}/); // Year or date pattern
    }
  });

  test('should handle social media links', async ({ page }) => {
    await page.goto('/profile');
    
    // Enter edit mode
    await page.locator('button:has-text("Edit")').click();
    
    // Check for social media fields
    const socialFields = ['twitter', 'github', 'linkedin', 'facebook'];
    
    for (const platform of socialFields) {
      const input = page.locator(`input[name="${platform}"], input[placeholder*="${platform}"]`);
      
      if (await input.isVisible({ timeout: 1000 }).catch(() => false)) {
        await input.fill(`https://${platform}.com/testuser`);
      }
    }
    
    // Save
    await page.locator('button:has-text("Save")').click();
    
    // Links should be saved
    for (const platform of socialFields) {
      const link = page.locator(`a[href*="${platform}.com"]`);
      if (await link.isVisible({ timeout: 1000 }).catch(() => false)) {
        const href = await link.getAttribute('href');
        expect(href).toContain(`${platform}.com/testuser`);
      }
    }
  });

  test('should change password', async ({ page }) => {
    await page.goto('/profile');
    
    // Look for password change section
    const changePasswordButton = page.locator('button:has-text("Change Password"), a:has-text("Change Password")');
    
    if (await changePasswordButton.isVisible()) {
      await changePasswordButton.click();
      
      // Fill password change form
      const currentPasswordInput = page.locator('input[name="currentPassword"], input[name="current_password"]');
      const newPasswordInput = page.locator('input[name="newPassword"], input[name="new_password"]');
      const confirmPasswordInput = page.locator('input[name="confirmPassword"], input[name="confirm_password"]');
      
      await currentPasswordInput.fill(testPassword);
      const newPassword = `V3za!new-${Date.now()}`;
      await newPasswordInput.fill(newPassword);
      await confirmPasswordInput.fill(newPassword);
      
      // Submit
      await page.locator('button:has-text("Update Password"), button:has-text("Change")').click();
      
      // Should show success
      await expect(page.locator('text=/password.*changed|password.*updated/i')).toBeVisible({ timeout: 5000 });
    }
  });

  test('should show email preferences', async ({ page }) => {
    await page.goto('/profile');
    
    // Look for email preferences or notifications
    const preferencesSection = page.locator('text=/email.*preferences|notifications|subscribe/i');
    
    if (await preferencesSection.isVisible()) {
      // Check for toggles
      const toggles = page.locator('input[type="checkbox"], [role="switch"]');
      const toggleCount = await toggles.count();
      
      if (toggleCount > 0) {
        // Toggle first preference
        const firstToggle = toggles.first();
        const wasChecked = await firstToggle.isChecked();
        await firstToggle.click();
        
        // State should change
        expect(await firstToggle.isChecked()).toBe(!wasChecked);
      }
    }
  });

  test('should handle privacy settings', async ({ page }) => {
    await page.goto('/profile');
    
    // Look for privacy settings
    const privacySection = page.locator('text=/privacy|visibility|public.*profile/i');
    
    if (await privacySection.isVisible()) {
      // Find privacy toggles
      const privacyToggles = privacySection.locator('xpath=following-sibling::*').locator('input[type="checkbox"], select');
      
      if (await privacyToggles.first().isVisible()) {
        // Change a privacy setting
        const firstToggle = privacyToggles.first();
        
        if (await firstToggle.getAttribute('type') === 'checkbox') {
          await firstToggle.click();
        } else {
          // It's a select
          await firstToggle.selectOption({ index: 1 });
        }
        
        // Save if needed
        const saveButton = page.locator('button:has-text("Save")');
        if (await saveButton.isVisible()) {
          await saveButton.click();
          await expect(page.locator('text=/saved|updated/i')).toBeVisible();
        }
      }
    }
  });

  test('should delete avatar', async ({ page }) => {
    await page.goto('/profile');
    
    // First upload an avatar
    const uploadButton = page.locator('button:has-text("Upload"), input[type="file"][accept*="image"]');
    if (await uploadButton.isVisible()) {
      await uploadButton.setInputFiles(avatarPath);
      await page.waitForTimeout(2000);
    }
    
    // Look for delete avatar option
    const deleteAvatarButton = page.locator('button:has-text("Remove Avatar"), button:has-text("Delete Avatar")');
    
    if (await deleteAvatarButton.isVisible()) {
      await deleteAvatarButton.click();
      
      // Confirm if needed
      const confirmButton = page.locator('button:has-text("Confirm"), button:has-text("Yes")');
      if (await confirmButton.isVisible({ timeout: 1000 }).catch(() => false)) {
        await confirmButton.click();
      }
      
      // Avatar should be removed
      await expect(page.locator('text=/avatar.*removed|avatar.*deleted/i')).toBeVisible();
      
      // Should show default avatar
      const avatarImg = page.locator('.avatar img');
      const src = await avatarImg.getAttribute('src');
      expect(src).toMatch(/default|placeholder|gravatar/);
    }
  });

  test('should export user data', async ({ page }) => {
    await page.goto('/profile');
    
    // Look for export data option
    const exportButton = page.locator('button:has-text("Export"), a:has-text("Download.*Data")');
    
    if (await exportButton.isVisible()) {
      // Start download
      const downloadPromise = page.waitForEvent('download');
      await exportButton.click();
      
      try {
        const download = await downloadPromise;
        expect(download.suggestedFilename()).toMatch(/export|data|backup/);
      } catch {
        // Might need confirmation
        const confirmExport = page.locator('button:has-text("Download"), button:has-text("Export")').last();
        if (await confirmExport.isVisible()) {
          const downloadPromise = page.waitForEvent('download');
          await confirmExport.click();
          const download = await downloadPromise;
          expect(download.suggestedFilename()).toMatch(/export|data|backup/);
        }
      }
    }
  });

  test('should handle account deletion', async ({ page }) => {
    await page.goto('/profile');
    
    // Look for delete account option (usually in danger zone)
    const deleteAccountButton = page.locator('button:has-text("Delete Account"), a:has-text("Delete Account")');
    
    if (await deleteAccountButton.isVisible()) {
      await deleteAccountButton.click();
      
      // Should show confirmation dialog
      const confirmDialog = page.locator('[role="dialog"], .modal');
      await expect(confirmDialog).toBeVisible();
      
      // Should require typing confirmation
      const confirmInput = confirmDialog.locator('input[placeholder*="DELETE"], input[placeholder*="confirm"]');
      if (await confirmInput.isVisible()) {
        await confirmInput.fill('DELETE');
      }
      
      // We won't actually delete in test
      const cancelButton = confirmDialog.locator('button:has-text("Cancel")');
      await cancelButton.click();
      
      // Dialog should close
      await expect(confirmDialog).not.toBeVisible();
    }
  });
});