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

/**
 * E2E tests for Product Category CRUD operations.
 *
 * Prerequisites:
 * - Frontend running on http://localhost:3001 (npm run dev)
 * - Backend running on http://localhost:8081 (docker compose up)
 * - Auth setup must run first (profile selected)
 */

const UNIQUE = Date.now()
const CATEGORY_NAME = `E2E Catégorie Produit ${UNIQUE}`
const CATEGORY_NOTES = `Notes de test automatisé ${UNIQUE}`
const CATEGORY_NAME_UPDATED = `${CATEGORY_NAME} modifié`
const CATEGORY_NOTES_UPDATED = `${CATEGORY_NOTES} — mis à jour`

test.describe('Product Category CRUD', () => {
  test.describe.configure({ mode: 'serial' })

  // ──────────────────────────────────────────────
  // CREATE
  // ──────────────────────────────────────────────

  test('should display the product category list page', async ({ page }) => {
    await page.goto('/product-category')
    await expect(page.getByRole('heading', { name: 'Catégories de produit' })).toBeVisible({ timeout: 10_000 })
    await expect(page.getByText('Catégories enregistrées')).toBeVisible()
  })

  test('should navigate to the create form', async ({ page }) => {
    await page.goto('/product-category')
    // The toolbar button text is "Créer" (with a plus icon)
    await page.getByRole('button', { name: /créer/i }).click()
    await expect(page).toHaveURL('/product-category/new')
    await expect(page.getByRole('heading', { name: 'Nouvelle catégorie de produit' })).toBeVisible()
  })

  test('should show validation error for short name', async ({ page }) => {
    await page.goto('/product-category/new')
    await page.locator('#model-type-name').fill('A')
    // The form submit button in ModelTypeForm is also "Créer"
    await page.locator('button[type="submit"]').click()
    await expect(page.getByText('Le nom doit contenir au moins 2 caractères')).toBeVisible()
  })

  test('should create a new product category', async ({ page }) => {
    await page.goto('/product-category/new')
    await page.locator('#model-type-name').fill(CATEGORY_NAME)
    await page.locator('#model-type-notes').fill(CATEGORY_NOTES)

    // Verify category is locked to PRODUCT
    const categorySelect = page.locator('#model-type-category')
    await expect(categorySelect).toBeDisabled()
    await expect(categorySelect).toHaveValue('PRODUCT')

    await page.locator('button[type="submit"]').click()

    // Should redirect to list and show success toast
    await expect(page).toHaveURL('/product-category', { timeout: 10_000 })
    await expect(page.getByText('Catégorie de produit créée avec succès')).toBeVisible()
  })

  // ──────────────────────────────────────────────
  // READ
  // ──────────────────────────────────────────────

  test('should display the created category in the list', async ({ page }) => {
    await page.goto('/product-category')
    // Target the table cell specifically (desktop view also renders a mobile card)
    await expect(page.getByRole('cell', { name: CATEGORY_NAME })).toBeVisible({ timeout: 10_000 })
  })

  test('should find the category via search', async ({ page }) => {
    await page.goto('/product-category')

    // Type in search input (placeholder: "Rechercher par nom…")
    const searchInput = page.getByPlaceholder('Rechercher par nom…')
    await searchInput.fill(UNIQUE.toString())
    // Wait for debounce (300ms) + API response
    await page.waitForTimeout(500)

    await expect(page.getByRole('cell', { name: CATEGORY_NAME })).toBeVisible({ timeout: 5_000 })
  })

  // ──────────────────────────────────────────────
  // UPDATE
  // ──────────────────────────────────────────────

  test('should navigate to the edit page', async ({ page }) => {
    await page.goto('/product-category')
    await expect(page.getByRole('cell', { name: CATEGORY_NAME })).toBeVisible({ timeout: 10_000 })

    // Find the row with our category and click "Éditer"
    const row = page.getByRole('row').filter({ hasText: CATEGORY_NAME })
    await row.getByRole('button', { name: 'Éditer' }).click()

    await expect(page.getByRole('heading', { name: /modifier/i })).toBeVisible({ timeout: 10_000 })
  })

  test('should edit the category name and notes', async ({ page }) => {
    await page.goto('/product-category')
    await expect(page.getByRole('cell', { name: CATEGORY_NAME })).toBeVisible({ timeout: 10_000 })

    const row = page.getByRole('row').filter({ hasText: CATEGORY_NAME })
    await row.getByRole('button', { name: 'Éditer' }).click()
    await expect(page.getByRole('heading', { name: /modifier/i })).toBeVisible({ timeout: 10_000 })

    // Update name
    const nameInput = page.locator('#model-type-name')
    await nameInput.clear()
    await nameInput.fill(CATEGORY_NAME_UPDATED)

    // Update notes
    const notesTextarea = page.locator('#model-type-notes')
    await notesTextarea.clear()
    await notesTextarea.fill(CATEGORY_NOTES_UPDATED)

    await page.locator('button[type="submit"]').click()

    // Should redirect and show success
    await expect(page).toHaveURL('/product-category', { timeout: 10_000 })
    await expect(page.getByText('Catégorie de produit mise à jour avec succès')).toBeVisible()
  })

  test('should display updated category in the list', async ({ page }) => {
    await page.goto('/product-category')
    await expect(page.getByRole('cell', { name: CATEGORY_NAME_UPDATED })).toBeVisible({ timeout: 10_000 })
  })

  // ──────────────────────────────────────────────
  // DELETE
  // ──────────────────────────────────────────────

  test('should cancel deletion when clicking Annuler', async ({ page }) => {
    await page.goto('/product-category')
    await expect(page.getByRole('cell', { name: CATEGORY_NAME_UPDATED })).toBeVisible({ timeout: 10_000 })

    const row = page.getByRole('row').filter({ hasText: CATEGORY_NAME_UPDATED })
    await row.getByRole('button', { name: 'Supprimer' }).click()

    // Confirmation modal should appear
    await expect(page.getByText('Supprimer ce type ?')).toBeVisible()
    await page.getByRole('button', { name: 'Annuler' }).click()

    // Category should still be present
    await expect(page.getByRole('cell', { name: CATEGORY_NAME_UPDATED })).toBeVisible()
  })

  test('should delete the category', async ({ page }) => {
    await page.goto('/product-category')
    await expect(page.getByRole('cell', { name: CATEGORY_NAME_UPDATED })).toBeVisible({ timeout: 10_000 })

    const row = page.getByRole('row').filter({ hasText: CATEGORY_NAME_UPDATED })
    await row.getByRole('button', { name: 'Supprimer' }).click()

    // Confirm deletion in modal
    await expect(page.getByText('Supprimer ce type ?')).toBeVisible()
    // Click the confirm "Supprimer" button inside the modal (btn-error style)
    await page.locator('button.btn-error').filter({ hasText: 'Supprimer' }).click()

    // Should show success toast and category should disappear
    await expect(page.getByText(/supprimé avec succès/i)).toBeVisible({ timeout: 10_000 })
    await expect(page.getByRole('cell', { name: CATEGORY_NAME_UPDATED })).not.toBeVisible()
  })
})
