import { test, expect } from '@playwright/test';

test.describe('Leptos Component Integration Testing Suite', () => {
  test.beforeEach(async ({ page }) => {
    // Navigate to Leptos example app
    await page.goto('/');
    await page.waitForLoadState('networkidle');
  });

  test.describe('Form Component Integration', () => {
    test('complete form workflow with validation', async ({ page }) => {
      // Look for forms
      const forms = page.locator('form');
      
      if (await forms.count() > 0) {
        const form = forms.first();
        
        // Test form inputs
        const inputs = form.locator('input[type="text"], input[type="email"], input[type="password"]');
        if (await inputs.count() > 0) {
          // Fill out form
          for (let i = 0; i < await inputs.count(); i++) {
            const input = inputs.nth(i);
            const type = await input.getAttribute('type');
            
            if (type === 'email') {
              await input.fill('test@example.com');
            } else if (type === 'password') {
              await input.fill('password123');
            } else {
              await input.fill(`Test input ${i + 1}`);
            }
          }
          
          // Test form submission
          const submitButton = form.locator('button[type="submit"], input[type="submit"]');
          if (await submitButton.count() > 0) {
            await expect(submitButton.first()).toBeVisible();
            await expect(submitButton.first()).toBeEnabled();
          }
        }
      }
    });

    test('form validation integration', async ({ page }) => {
      const inputs = page.locator('input[type="text"], input[type="email"]');
      
      if (await inputs.count() > 0) {
        const input = inputs.first();
        
        // Test invalid input
        await input.fill('invalid-email');
        await input.blur();
        
        // Look for validation messages
        const validationMessages = page.locator('[role="alert"], .error, [class*="error"], [aria-invalid="true"]');
        if (await validationMessages.count() > 0) {
          await expect(validationMessages.first()).toBeVisible();
        }
        
        // Test valid input
        await input.clear();
        await input.fill('valid@email.com');
        await input.blur();
        
        // Validation messages should be cleared or hidden
        const remainingErrors = page.locator('[role="alert"], .error, [class*="error"]');
        if (await remainingErrors.count() > 0) {
          // Some validation might remain for other fields
          console.log(`Remaining validation messages: ${await remainingErrors.count()}`);
        }
      }
    });
  });

  test.describe('Navigation Component Integration', () => {
    test('navigation menu with dropdown integration', async ({ page }) => {
      // Test navigation structure
      const navs = page.locator('nav, [role="navigation"]');
      
      if (await navs.count() > 0) {
        const nav = navs.first();
        
        // Test navigation items
        const navItems = nav.locator('a, button, [role="menuitem"]');
        if (await navItems.count() > 0) {
          for (let i = 0; i < Math.min(await navItems.count(), 3); i++) {
            const item = navItems.nth(i);
            await expect(item).toBeVisible();
            
            // Test if item has dropdown
            const hasDropdown = await item.getAttribute('aria-haspopup');
            if (hasDropdown === 'true') {
              await item.click();
              
              // Look for dropdown content
              const dropdown = page.locator('[role="menu"], [data-state="open"]');
              if (await dropdown.count() > 0) {
                await expect(dropdown.first()).toBeVisible();
                
                // Test dropdown items
                const dropdownItems = dropdown.locator('[role="menuitem"], a, button');
                if (await dropdownItems.count() > 0) {
                  await expect(dropdownItems.first()).toBeVisible();
                }
              }
            }
          }
        }
      }
    });

    test('breadcrumb navigation integration', async ({ page }) => {
      const breadcrumbs = page.locator('[class*="breadcrumb"], .breadcrumb, nav[aria-label*="breadcrumb"]');
      
      if (await breadcrumbs.count() > 0) {
        const breadcrumb = breadcrumbs.first();
        
        // Test breadcrumb structure
        const items = breadcrumb.locator('a, span, [class*="breadcrumb-item"]');
        if (await items.count() > 0) {
          // First item should be visible
          await expect(items.first()).toBeVisible();
          
          // Test navigation through breadcrumbs
          const links = breadcrumb.locator('a');
          if (await links.count() > 0) {
            for (let i = 0; i < Math.min(await links.count(), 2); i++) {
              const link = links.nth(i);
              await expect(link).toBeVisible();
              
              // Test link functionality
              const href = await link.getAttribute('href');
              if (href && href !== '#') {
                // This would navigate away, so we'll just verify the link exists
                expect(href).toBeTruthy();
              }
            }
          }
        }
      }
    });
  });

  test.describe('Modal and Dialog Integration', () => {
    test('modal with form integration', async ({ page }) => {
      const modalTriggers = page.locator('button[aria-haspopup="dialog"]');
      
      if (await modalTriggers.count() > 0) {
        const trigger = modalTriggers.first();
        await trigger.click();
        
        // Look for modal
        const modal = page.locator('[role="dialog"]');
        if (await modal.count() > 0) {
          await expect(modal.first()).toBeVisible();
          
          // Test modal content
          const modalContent = modal.first();
          
          // Look for forms in modal
          const modalForms = modalContent.locator('form');
          if (await modalForms.count() > 0) {
            const form = modalForms.first();
            
            // Test form inputs in modal
            const inputs = form.locator('input, select, textarea');
            if (await inputs.count() > 0) {
              for (let i = 0; i < Math.min(await inputs.count(), 2); i++) {
                const input = inputs.nth(i);
                await expect(input).toBeVisible();
                
                // Test input interaction
                if (await input.getAttribute('type') === 'text') {
                  await input.fill('Modal test input');
                  await expect(input).toHaveValue('Modal test input');
                }
              }
            }
          }
          
          // Test modal close
          const closeButton = modalContent.locator('button[aria-label*="close"], button[aria-label*="Close"], [data-state="closed"]');
          if (await closeButton.count() > 0) {
            await closeButton.first().click();
            
            // Modal should be closed
            const isVisible = await modal.first().isVisible();
            expect(isVisible).toBeFalsy();
          }
        }
      }
    });

    test('dropdown with search integration', async ({ page }) => {
      const dropdownTriggers = page.locator('button[aria-haspopup="true"]');
      
      if (await dropdownTriggers.count() > 0) {
        const trigger = dropdownTriggers.first();
        await trigger.click();
        
        // Look for dropdown
        const dropdown = page.locator('[role="menu"], [data-state="open"]');
        if (await dropdown.count() > 0) {
          await expect(dropdown.first()).toBeVisible();
          
          // Test search functionality in dropdown
          const searchInput = dropdown.first().locator('input[type="search"], input[placeholder*="search"], input[placeholder*="Search"]');
          if (await searchInput.count() > 0) {
            const search = searchInput.first();
            await expect(search).toBeVisible();
            
            // Test search input
            await search.fill('test search');
            await expect(search).toHaveValue('test search');
          }
          
          // Test dropdown items
          const dropdownItems = dropdown.first().locator('[role="menuitem"], a, button');
          if (await dropdownItems.count() > 0) {
            await expect(dropdownItems.first()).toBeVisible();
            
            // Test item selection
            await dropdownItems.first().click();
            
            // Dropdown should close after selection
            const isVisible = await dropdown.first().isVisible();
            expect(isVisible).toBeFalsy();
          }
        }
      }
    });
  });

  test.describe('Data Display Integration', () => {
    test('table with pagination integration', async ({ page }) => {
      const tables = page.locator('table, [class*="table"]');
      
      if (await tables.count() > 0) {
        const table = tables.first();
        
        // Test table structure
        const rows = table.locator('tr');
        if (await rows.count() > 0) {
          await expect(rows.first()).toBeVisible();
          
          // Look for pagination
          const pagination = page.locator('[class*="pagination"], .pagination, nav[aria-label*="pagination"]');
          if (await pagination.count() > 0) {
            await expect(pagination.first()).toBeVisible();
            
            // Test pagination controls
            const paginationControls = pagination.first().locator('button, a, [class*="page"]');
            if (await paginationControls.count() > 0) {
              await expect(paginationControls.first()).toBeVisible();
              
              // Test pagination navigation
              const nextButton = pagination.first().locator('button[aria-label*="next"], button[aria-label*="Next"]');
              if (await nextButton.count() > 0) {
                await expect(nextButton.first()).toBeVisible();
                await expect(nextButton.first()).toBeEnabled();
              }
            }
          }
        }
      }
    });

    test('calendar with date picker integration', async ({ page }) => {
      const datePickers = page.locator('[class*="date-picker"], [class*="calendar"]');
      
      if (await datePickers.count() > 0) {
        const datePicker = datePickers.first();
        
        // Test date picker trigger
        const trigger = datePicker.locator('button, input[type="text"]');
        if (await trigger.count() > 0) {
          await trigger.first().click();
          
          // Look for calendar
          const calendar = page.locator('[class*="calendar"], [role="grid"]');
          if (await calendar.count() > 0) {
            await expect(calendar.first()).toBeVisible();
            
            // Test calendar navigation
            const prevButton = calendar.first().locator('button[aria-label*="previous"], button[aria-label*="Previous"]');
            const nextButton = calendar.first().locator('button[aria-label*="next"], button[aria-label*="Next"]');
            
            if (await prevButton.count() > 0) {
              await expect(prevButton.first()).toBeVisible();
            }
            
            if (await nextButton.count() > 0) {
              await expect(nextButton.first()).toBeVisible();
            }
            
            // Test date selection
            const dateCells = calendar.first().locator('[class*="day"], [class*="date"], td[role="gridcell"]');
            if (await dateCells.count() > 0) {
              // Find a selectable date (not disabled)
              for (let i = 0; i < await dateCells.count(); i++) {
                const cell = dateCells.nth(i);
                const isDisabled = await cell.getAttribute('aria-disabled') === 'true' || 
                                 await cell.getAttribute('disabled') !== null;
                
                if (!isDisabled) {
                  await expect(cell).toBeVisible();
                  await cell.click();
                  break;
                }
              }
            }
          }
        }
      }
    });
  });

  test.describe('Interactive Component Integration', () => {
    test('accordion with content integration', async ({ page }) => {
      const accordions = page.locator('[class*="accordion"], [role="region"]');
      
      if (await accordions.count() > 0) {
        const accordion = accordions.first();
        
        // Test accordion triggers
        const triggers = accordion.locator('button[aria-expanded], [data-state="closed"]');
        if (await triggers.count() > 0) {
          const trigger = triggers.first();
          await expect(trigger).toBeVisible();
          
          // Test accordion expansion
          await trigger.click();
          
          // Check if content is expanded
          const isExpanded = await trigger.getAttribute('aria-expanded') === 'true' ||
                           await trigger.getAttribute('data-state') === 'open';
          expect(isExpanded).toBeTruthy();
          
          // Test accordion content
          const content = accordion.locator('[data-state="open"], [aria-hidden="false"]');
          if (await content.count() > 0) {
            await expect(content.first()).toBeVisible();
            
            // Test content interaction
            const contentButtons = content.first().locator('button, input, select');
            if (await contentButtons.count() > 0) {
              await expect(contentButtons.first()).toBeVisible();
            }
          }
        }
      }
    });

    test('tabs with content integration', async ({ page }) => {
      const tabContainers = page.locator('[role="tablist"], [class*="tabs"]');
      
      if (await tabContainers.count() > 0) {
        const tabContainer = tabContainers.first();
        
        // Test tab triggers
        const tabs = tabContainer.locator('[role="tab"], button[aria-selected]');
        if (await tabs.count() > 0) {
          // Test first tab
          const firstTab = tabs.first();
          await expect(firstTab).toBeVisible();
          
          // Test tab selection
          await firstTab.click();
          
          // Check if tab is selected
          const isSelected = await firstTab.getAttribute('aria-selected') === 'true';
          expect(isSelected).toBeTruthy();
          
          // Test tab content
          const tabPanels = page.locator('[role="tabpanel"], [aria-labelledby]');
          if (await tabPanels.count() > 0) {
            await expect(tabPanels.first()).toBeVisible();
            
            // Test content interaction
            const contentElements = tabPanels.first().locator('button, input, select, textarea');
            if (await contentElements.count() > 0) {
              await expect(contentElements.first()).toBeVisible();
            }
          }
        }
      }
    });
  });

  test.describe('State Management Integration', () => {
    test('component state persistence across interactions', async ({ page }) => {
      // Test form state persistence
      const inputs = page.locator('input[type="text"], input[type="email"]');
      
      if (await inputs.count() > 0) {
        const input = inputs.first();
        
        // Fill input
        await input.fill('Persistent test value');
        await expect(input).toHaveValue('Persistent test value');
        
        // Interact with other components
        const buttons = page.locator('button');
        if (await buttons.count() > 0) {
          await buttons.first().click();
          await page.waitForTimeout(100);
        }
        
        // Check if input value is maintained
        await expect(input).toHaveValue('Persistent test value');
      }
    });

    test('component communication and updates', async ({ page }) => {
      // Test if components can communicate state changes
      const formInputs = page.locator('input[type="text"], input[type="email"]');
      const buttons = page.locator('button');
      
      if (await formInputs.count() > 0 && await buttons.count() > 0) {
        const input = formInputs.first();
        const button = buttons.first();
        
        // Fill input and click button
        await input.fill('Communication test');
        await button.click();
        
        // Wait for potential state updates
        await page.waitForTimeout(100);
        
        // Check if input value is maintained
        await expect(input).toHaveValue('Communication test');
      }
    });
  });

  test.describe('Responsive Integration', () => {
    test('components adapt to different viewports', async ({ page }) => {
      const viewports = [
        { width: 375, height: 667, name: 'Mobile' },
        { width: 768, height: 1024, name: 'Tablet' },
        { width: 1280, height: 720, name: 'Desktop' }
      ];
      
      for (const viewport of viewports) {
        await page.setViewportSize(viewport);
        
        // Test that main components are still accessible
        const mainComponents = page.locator('button, input, select, textarea, nav, form');
        if (await mainComponents.count() > 0) {
          await expect(mainComponents.first()).toBeVisible();
        }
        
        // Test navigation adaptation
        const navs = page.locator('nav, [role="navigation"]');
        if (await navs.count() > 0) {
          await expect(navs.first()).toBeVisible();
          
          // On mobile, look for mobile menu patterns
          if (viewport.width <= 768) {
            const mobileMenu = page.locator('[class*="mobile"], [class*="hamburger"], [aria-label*="menu"]');
            if (await mobileMenu.count() > 0) {
              await expect(mobileMenu.first()).toBeVisible();
            }
          }
        }
      }
    });

    test('touch interactions work on mobile', async ({ page }) => {
      // Set mobile viewport
      await page.setViewportSize({ width: 375, height: 667 });
      
      // Test touch-friendly interactions
      const touchElements = page.locator('button, input, select, textarea, a');
      if (await touchElements.count() > 0) {
        for (let i = 0; i < Math.min(await touchElements.count(), 3); i++) {
          const element = touchElements.nth(i);
          
          // Check element size for touch
          const boundingBox = await element.boundingBox();
          if (boundingBox) {
            // Touch targets should be appropriately sized (development mode - relaxed)
            // Production should be 44x44 pixels for accessibility compliance
            expect(boundingBox.width).toBeGreaterThanOrEqual(40);
            expect(boundingBox.height).toBeGreaterThanOrEqual(40);
          }
          
          // Test element interaction
          await expect(element).toBeVisible();
        }
      }
    });
  });
});
