import type { Page } from '@playwright/test';

import { test, expectFixture as expect } from '../helpers/test-fixtures';

const futureDate = (daysAhead = 10): string => {
  const date = new Date();
  date.setDate(date.getDate() + daysAhead);
  return date.toISOString().slice(0, 10);
};

async function ensureOnDashboard(page: Page): Promise<void> {
  await page.goto('/event-admin/dashboard');
  await page.waitForLoadState('networkidle');

  if (page.url().includes('/event-admin/welcome')) {
    const directButton = page.getByRole('button', { name: /Direkt zum Dashboard/i });
    if (await directButton.isVisible()) {
      await directButton.click();
      await page.waitForURL(/\/event-admin\/dashboard$/, { timeout: 15_000 });
    }
  }
}

test.describe('Tenant Admin PWA – end-to-end coverage', () => {
  test.beforeEach(async ({ signInTenantAdmin }) => {
    await signInTenantAdmin();
  });

  test('dashboard highlights core stats and quick actions', async ({ page }) => {
    await ensureOnDashboard(page);

    await expect(page.getByRole('heading', { name: /Hallo/i })).toBeVisible();
    await expect(page.getByRole('button', { name: /Neues Event/i })).toBeVisible();
    await expect(page.getByText(/Schnellaktionen/i)).toBeVisible();
    await expect(page.getByText(/Kommende Events/i)).toBeVisible();
  });

  test('event creation flow and detail subsections', async ({ page }) => {
    const eventName = `Playwright Event ${Date.now()}`;
    const eventDate = futureDate(14);

    await page.goto('/event-admin/events/new');
    await page.waitForLoadState('networkidle');
    await expect(page.getByRole('heading', { name: /Eventdetails/i })).toBeVisible();

    await page.getByLabel(/Eventname/i).fill(eventName);
    await page.getByLabel(/Datum/i).fill(eventDate);

    const eventTypeTrigger = page.getByRole('combobox', { name: /Event-Typ/i });
    await eventTypeTrigger.click();
    const firstOption = page.getByRole('option').first();
    await expect(firstOption).toBeVisible({ timeout: 5_000 });
    await firstOption.click();

    await page.getByRole('button', { name: /^Speichern/i }).click();
    await expect(page).toHaveURL(/\/event-admin\/events\/[a-z0-9-]+$/, { timeout: 20_000 });
    const createdSlug = page.url().split('/').pop() ?? '';

    await expect(page.getByRole('heading', { name: /Eventdetails/i })).toBeVisible();

    await page.goto('/event-admin/events');
    await page.waitForLoadState('networkidle');
    await expect(page.getByText(eventName, { exact: false })).toBeVisible();

    await page.goto(`/event-admin/events/${createdSlug}/photos`);
    await expect(page.getByRole('heading', { name: /Fotos moderieren/i })).toBeVisible();
    await expect(page.getByText(/Noch keine Fotos vorhanden/i)).toBeVisible();

    await page.goto(`/event-admin/events/${createdSlug}/members`);
    await expect(page.getByRole('heading', { name: /Event-Mitglieder/i })).toBeVisible();

    await page.goto(`/event-admin/events/${createdSlug}/tasks`);
    await expect(page.getByRole('heading', { name: /Event-Tasks/i })).toBeVisible();
    await expect(page.getByText(/Noch keine Tasks zugewiesen/i)).toBeVisible();
  });

  test('task library allows creating custom tasks', async ({ page }) => {
    await page.goto('/event-admin/tasks');
    await page.waitForLoadState('networkidle');

    await expect(page.getByRole('heading', { name: /Task Bibliothek/i })).toBeVisible();

    const taskTitle = `Playwright Task ${Date.now()}`;
    await page.getByRole('button', { name: /^Neu$/i }).click();
    await page.getByLabel(/Titel/i).fill(taskTitle);
    await page.getByLabel(/Beschreibung/i).fill('Automatisierter Testfall');
    await page.getByRole('button', { name: /^Speichern$/i }).click();

    await expect(page.getByText(taskTitle)).toBeVisible({ timeout: 10_000 });

    await page.goto('/event-admin/task-collections');
    await page.waitForLoadState('networkidle');
    await expect(page.getByRole('heading', { name: /Aufgabenvorlagen/i })).toBeVisible();
  });

  test('supporting sections (emotions, billing, settings) load successfully', async ({ page }) => {
    await page.goto('/event-admin/emotions');
    await page.waitForLoadState('networkidle');
    await expect(page.getByRole('heading', { name: /Emotionen/i })).toBeVisible();

    await page.goto('/event-admin/billing');
    await page.waitForLoadState('networkidle');
    await expect(page.getByRole('heading', { name: /Pakete & Abrechnung/i })).toBeVisible();

    await page.goto('/event-admin/settings');
    await page.waitForLoadState('networkidle');
    await expect(page.getByRole('heading', { name: /Einstellungen/i })).toBeVisible();
  });

  test('wedding event workflow assigns tasks and exposes join token', async ({ page, fetchJoinToken }) => {
    const eventName = `Playwright Hochzeit ${Date.now()}`;
    const eventDate = futureDate(21);

    await page.goto('/event-admin/events/new');
    await page.waitForLoadState('networkidle');

    await page.getByLabel(/Eventname/i).fill(eventName);
    await page.getByLabel(/Datum/i).fill(eventDate);

    const eventTypeCombo = page.getByRole('combobox', { name: /Event-Typ/i });
    await eventTypeCombo.click();
    const weddingOption = page.getByRole('option', { name: /Hochzeit|Wedding/i }).first();
    await expect(weddingOption).toBeVisible();
    await weddingOption.click();

    await page.getByRole('button', { name: /^Speichern/i }).click();
    await page.waitForURL(/\/event-admin\/events\/[a-z0-9-]+$/i, { timeout: 20_000 });
    const createdSlug = page.url().split('/').pop() ?? '';

    await expect(page.getByText(/Hochzeit|Wedding/i)).toBeVisible();

    await page.goto(`/event-admin/events/${createdSlug}/tasks`);
    await expect(page.getByRole('heading', { name: /Event-Tasks/i })).toBeVisible();

    const librarySection = page
      .locator('section')
      .filter({ hasText: /Tasks aus Bibliothek hinzufügen|Add tasks/i })
      .first();
    const availableTaskLabels = librarySection.locator('label');
    const availableCount = await availableTaskLabels.count();
    test.skip(availableCount === 0, 'No task library entries available to assign');

    const firstLabel = availableTaskLabels.first();
    const taskTitle = ((await firstLabel.locator('p').first().textContent()) ?? '').trim();
    await firstLabel.click();

    await page
      .getByRole('button', { name: /Ausgewählte Tasks zuweisen|Assign selected tasks/i })
      .click();

    await expect(
      page.locator('section').filter({ hasText: /Zugeordnete Tasks|Assigned tasks/i }).getByText(taskTitle, { exact: false }),
    ).toBeVisible({ timeout: 15_000 });

    const joinToken = await fetchJoinToken({ slug: createdSlug });
    expect(joinToken.token).toBeTruthy();
    expect(joinToken.join_url).toContain(joinToken.token);
    expect(joinToken.qr_svg).toContain('<svg');
  });
});
