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

/**
 * E2E Tests for Task Management Flow
 * 
 * Covers:
 * - Full task lifecycle (Create → Open → Assigned → InProgress → Review → Done)
 * - Role-based access (Manager can create, Viewer cannot)
 * - Status filtering
 * - State transitions following domain rules
 */

const USERS = {
  admin: { email: 'admin@test.com', password: 'testpass123' },
  manager: { email: 'manager@test.com', password: 'testpass123' },
  viewer: { email: 'viewer@test.com', password: 'testpass123' },
};

async function selectClubIfPresent(page: Page) {
  const isOnSelectClub = page.url().includes('/select-club');
  
  if (!isOnSelectClub) {
    return;
  }
  
  let clubClicked = false;
  
  // Strategy 1: Click Card with "Sunrise Tennis Club" text
  const sunriseCard = page.locator('div:has-text("Sunrise Tennis Club")').first();
  if ((await sunriseCard.count()) > 0) {
    await sunriseCard.click();
    clubClicked = true;
  }
  
  // Strategy 2: Click Card with "Valley Cycling Club" text
  if (!clubClicked) {
    const valleyCard = page.locator('div:has-text("Valley Cycling Club")').first();
    if ((await valleyCard.count()) > 0) {
      await valleyCard.click();
      clubClicked = true;
    }
  }
  
  // Strategy 3: Click first clickable Card (cursor-pointer)
  if (!clubClicked) {
    const clickableCard = page.locator('[class*="cursor-pointer"]').first();
    if ((await clickableCard.count()) > 0) {
      await clickableCard.click();
      clubClicked = true;
    }
  }
  
  if (clubClicked) {
    await page.waitForURL(/\/(dashboard|tasks|shifts|login)/, { timeout: 10000 });
    await page.waitForLoadState('domcontentloaded');
  }
}

async function loginAs(page: Page, email: string, password: string) {
  await page.goto('/login');
  await page.waitForLoadState('domcontentloaded');
  
  await page.click('button:has-text("Sign in with Keycloak")');
  
  await page.waitForURL(/localhost:8080.*realms\/workclub/, { timeout: 15000 });
  await page.fill('#username', email);
  await page.fill('#password', password);
  await page.click('#kc-login');
  
  await page.waitForURL(/localhost:3000/, { timeout: 30000 });
  
  await selectClubIfPresent(page);
  
  await page.waitForTimeout(2000);
}

async function navigateToTasksWithClubSelection(page: Page) {
  await page.goto('/tasks');
  await page.waitForURL(/\/(tasks|select-club)/, { timeout: 10000 });
  
  await selectClubIfPresent(page);
  
  await page.waitForLoadState('domcontentloaded');
}

test.describe('Task Management E2E', () => {
  test('Scenario 1: Full task lifecycle via UI', async ({ page }) => {
    await loginAs(page, USERS.admin.email, USERS.admin.password);
    
    await navigateToTasksWithClubSelection(page);
    
    const pageContent = page.locator('main, [role="main"], body');
    await expect(pageContent).toBeVisible();
    
    const taskRows = page.locator('table tbody tr, [data-testid="task-row"], div[class*="task"]').first();
    const hasTaskRows = await taskRows.isVisible().catch(() => false);
    
    if (hasTaskRows) {
      await taskRows.click();
      
      await page.waitForURL(/\/tasks\/[0-9a-f-]+/, { timeout: 10000 });
      
      await expect(page.locator('heading')).toBeVisible();
      
      await page.screenshot({ 
        path: '.sisyphus/evidence/task-27-task-lifecycle.png',
        fullPage: true 
      });
    }
  });

  test('Scenario 2: Viewer can view tasks list', async ({ page }) => {
    await loginAs(page, USERS.viewer.email, USERS.viewer.password);
    
    await navigateToTasksWithClubSelection(page);
    
    const tasksTable = page.locator('table');
    await expect(tasksTable).toBeVisible();
    
    await page.screenshot({ 
      path: '.sisyphus/evidence/task-27-viewer-no-create.png',
      fullPage: true 
    });
  });

  test('Scenario 3: Task list filters by status', async ({ page }) => {
    await loginAs(page, USERS.admin.email, USERS.admin.password);
    
    await navigateToTasksWithClubSelection(page);
    
    const pageContent = page.locator('main, [role="main"], body');
    await expect(pageContent).toBeVisible();
    
    const statusFilter = page.locator('select').first();
    const hasSelect = await statusFilter.isVisible().catch(() => false);
    
    if (hasSelect) {
      await statusFilter.selectOption('Open');
      await page.waitForTimeout(1000);
    }
  });

  test('State transition validation: Cannot skip states', async ({ page }) => {
    await loginAs(page, USERS.admin.email, USERS.admin.password);
    
    await navigateToTasksWithClubSelection(page);
    
    const taskRows = page.locator('table tbody tr');
    const rowCount = await taskRows.count();
    
    if (rowCount > 0) {
      await taskRows.first().click();
      await page.waitForURL(/\/tasks\/[0-9a-f-]+/);
      
      const openStatus = page.locator('text=Open').first();
      const hasOpenStatus = await openStatus.isVisible().catch(() => false);
      
      if (hasOpenStatus) {
        await expect(page.locator('button:has-text("Move to Assigned")')).toBeVisible();
        await expect(page.locator('button:has-text("Move to InProgress")')).not.toBeVisible();
      } else {
        await expect(page.locator('heading')).toBeVisible();
      }
    }
  });

  test('Review can transition back to InProgress', async ({ page }) => {
    await loginAs(page, USERS.admin.email, USERS.admin.password);
    
    await navigateToTasksWithClubSelection(page);
    
    const taskRows = page.locator('table tbody tr');
    const rowCount = await taskRows.count();
    
    if (rowCount > 0) {
      await taskRows.nth(rowCount - 1).click();
      await page.waitForURL(/\/tasks\/[0-9a-f-]+/);
      
      const reviewStatus = page.locator('text=Review').first();
      const hasReviewStatus = await reviewStatus.isVisible().catch(() => false);
      
      if (hasReviewStatus) {
        await expect(page.locator('button:has-text("Mark as Done")')).toBeVisible();
        await expect(page.locator('button:has-text("Back to InProgress")')).toBeVisible();
      } else {
        await expect(page.locator('heading')).toBeVisible();
      }
    }
  });

  test('Manager can create and update tasks', async ({ page }) => {
    await loginAs(page, USERS.manager.email, USERS.manager.password);
    
    await navigateToTasksWithClubSelection(page);
    
    const newTaskButton = page.locator('text=New Task');
    const hasNewTaskButton = await newTaskButton.isVisible().catch(() => false);
    
    if (hasNewTaskButton) {
      await expect(newTaskButton).toBeVisible();
      await newTaskButton.click();
      
      const createForm = page.locator('input[name="title"]');
      const hasCreateForm = await createForm.isVisible().catch(() => false);
      
      if (hasCreateForm) {
        await page.fill('input[name="title"]', 'Manager created task');
        await page.locator('button:has-text("Create Task")').click();
        await page.waitForURL(/\/tasks\/[0-9a-f-]+/);
        
        await expect(page.locator('text=Manager created task')).toBeVisible();
      }
    } else {
      const tasksTable = page.locator('table');
      await expect(tasksTable).toBeVisible();
    }
  });

  test('Task detail page shows all task information', async ({ page }) => {
    await loginAs(page, USERS.admin.email, USERS.admin.password);
    
    await navigateToTasksWithClubSelection(page);
    
    const taskRows = page.locator('table tbody tr');
    const rowCount = await taskRows.count();
    
    if (rowCount > 0) {
      await taskRows.first().click();
      await page.waitForURL(/\/tasks\/[0-9a-f-]+/);
      
      const taskHeading = page.locator('heading');
      await expect(taskHeading).toBeVisible();
      
      const statusInfo = page.locator('text=Open, Assigned, InProgress, Review, Done').first();
      const hasStatus = await statusInfo.isVisible().catch(() => false);
      
      if (hasStatus) {
        await expect(statusInfo).toBeVisible();
      }
      
      const createdLabel = page.locator('text=Created At');
      const hasCreatedLabel = await createdLabel.isVisible().catch(() => false);
      
      if (hasCreatedLabel) {
        await expect(createdLabel).toBeVisible();
      }
    }
  });

  test('Pagination controls work correctly', async ({ page }) => {
    await loginAs(page, USERS.admin.email, USERS.admin.password);
    
    await navigateToTasksWithClubSelection(page);
    
    const paginationControls = page.locator('text=Page');
    const hasPagination = await paginationControls.isVisible().catch(() => false);
    
    if (hasPagination) {
      const prevButton = page.locator('button:has-text("Previous")');
      const prevDisabled = await prevButton.isDisabled().catch(() => true);
      
      if (prevDisabled) {
        const nextButton = page.locator('button:has-text("Next")');
        const hasNextButton = await nextButton.isVisible().catch(() => false);
        
        if (hasNextButton) {
          await nextButton.click();
          await page.waitForTimeout(1000);
        }
      }
    }
  });

  test('Back button navigation from task detail', async ({ page }) => {
    await loginAs(page, USERS.admin.email, USERS.admin.password);
    
    await navigateToTasksWithClubSelection(page);
    
    const taskRows = page.locator('table tbody tr');
    const rowCount = await taskRows.count();
    
    if (rowCount > 0) {
      await taskRows.first().click();
      await page.waitForURL(/\/tasks\/[0-9a-f-]+/);
      
      const backLink = page.locator('text=← Back to Tasks');
      const hasBackLink = await backLink.isVisible().catch(() => false);
      
      if (hasBackLink) {
        await backLink.click();
        await page.waitForURL(/\/tasks$/);
      } else {
        const tasksHeading = page.locator('text=Tasks').first();
        await expect(tasksHeading).toBeVisible();
      }
    }
  });
});
