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

const ROUTINE_NAME = 'ReorderTestRoutine'
const ROUTINE_POINTS = 10
const ITEM_A = 'Alpha Task'
const ITEM_B = 'Beta Task'
const ITEM_C = 'Gamma Task'

async function createRoutine(
  request: APIRequestContext,
  name: string,
  points: number,
): Promise<string> {
  const pre = await request.get('/api/routine/list')
  for (const r of (await pre.json()).routines ?? []) {
    if (r.name === name) await request.delete(`/api/routine/${r.id}`)
  }
  const res = await request.put('/api/routine/add', { data: { name, points } })
  return (await res.json()).routine?.id ?? ''
}

test.describe('Routine item drag-to-reorder', () => {
  test.describe.configure({ mode: 'serial' })

  let routineId = ''

  test.beforeAll(async ({ request }) => {
    routineId = await createRoutine(request, ROUTINE_NAME, ROUTINE_POINTS)
    await request.put(`/api/routine/${routineId}/item/add`, { data: { name: ITEM_A, order: 0 } })
    await request.put(`/api/routine/${routineId}/item/add`, { data: { name: ITEM_B, order: 1 } })
    await request.put(`/api/routine/${routineId}/item/add`, { data: { name: ITEM_C, order: 2 } })
  })

  test.afterAll(async ({ request }) => {
    if (routineId) await request.delete(`/api/routine/${routineId}`)
  })

  test('items load in correct initial order', async ({ page }) => {
    await page.goto(`/parent/tasks/routines/${routineId}/edit`)
    await page.locator('.item-row').first().waitFor({ state: 'visible' })

    const names = await page.locator('.item-name').allTextContents()
    expect(names).toEqual([ITEM_A, ITEM_B, ITEM_C])
  })

  test('dragging first item to last position reorders the list in the UI', async ({ page }) => {
    await page.goto(`/parent/tasks/routines/${routineId}/edit`)
    await page.locator('.item-row').first().waitFor({ state: 'visible' })

    await page.locator('.item-row').nth(0).locator('.drag-handle').dragTo(page.locator('.item-row').nth(2))

    const names = await page.locator('.item-name').allTextContents()
    expect(names).toEqual([ITEM_B, ITEM_C, ITEM_A])
  })

  test('reordered item order persists after saving', async ({ page }) => {
    await page.goto(`/parent/tasks/routines/${routineId}/edit`)
    await page.locator('.item-row').first().waitFor({ state: 'visible' })

    // Drag first to last: [A, B, C] → [B, C, A]
    await page.locator('.item-row').nth(0).locator('.drag-handle').dragTo(page.locator('.item-row').nth(2))

    // Confirm the drag updated the DOM before saving
    const afterDrag = await page.locator('.item-name').allTextContents()
    expect(afterDrag).toEqual([ITEM_B, ITEM_C, ITEM_A])

    await page.getByRole('button', { name: 'Save' }).click()
    await page.waitForURL(/\/parent\/tasks\/routines$/, { timeout: 5000 })

    // Reload edit view — should now show the saved order
    await page.goto(`/parent/tasks/routines/${routineId}/edit`)
    await page.locator('.item-row').first().waitFor({ state: 'visible' })

    const names = await page.locator('.item-name').allTextContents()
    expect(names).toEqual([ITEM_B, ITEM_C, ITEM_A])
  })
})
