// spec: e2e/plans/chore-scheduler.plan.md — Section 2: Schedule Modal Specific Days Mode

import { test, expect } from '@playwright/test'
import {
  createChild,
  createChoreTask,
  assignChore,
  deleteSchedule,
  setDaysSchedule,
  choreCard,
  openScheduleModal,
  setTimePicker,
  nonTodayDayIndex,
} from './helpers'

const CHILD_NAME = 'ScheduleDaysChild'
const CHORE_NAME = 'ScheduleDaysChore'

test.describe('Schedule Modal — Specific Days mode', () => {
  test.describe.configure({ mode: 'serial' })

  let childId = ''
  let choreId = ''

  test.beforeAll(async ({ request }) => {
    childId = await createChild(request, CHILD_NAME)
    choreId = await createChoreTask(request, CHORE_NAME)
    await assignChore(request, childId, [choreId])
  })

  test.afterAll(async ({ request }) => {
    if (childId) await request.delete(`/api/child/${childId}`)
    if (choreId) await request.delete(`/api/task/${choreId}`)
  })

  test.beforeEach(async ({ request }) => {
    await deleteSchedule(request, childId, choreId)
  })

  test('2.1 Clicking day chips toggles them active/inactive', async ({ page }) => {
    await page.goto(`/parent/${childId}`)
    const card = choreCard(page, CHORE_NAME)
    await card.waitFor()
    await openScheduleModal(page, card)

    const moChip = page.locator('.day-chips').getByRole('button', { name: 'Mo' })
    await moChip.click()
    await expect(moChip).toHaveClass(/active/)

    await moChip.click()
    await expect(moChip).not.toHaveClass(/active/)
  })

  test('2.2 Default deadline row appears when at least one day is selected', async ({ page }) => {
    await page.goto(`/parent/${childId}`)
    const card = choreCard(page, CHORE_NAME)
    await card.waitFor()
    await openScheduleModal(page, card)

    await expect(page.locator('.default-deadline-row')).not.toBeVisible()

    await page.locator('.day-chips').getByRole('button', { name: 'Tu' }).click()
    await expect(page.locator('.default-deadline-row')).toBeVisible()
    await expect(page.locator('.default-deadline-row')).toContainText('Deadline')
  })

  test('2.3 Default deadline "Anytime" toggle hides and restores time picker', async ({ page }) => {
    await page.goto(`/parent/${childId}`)
    const card = choreCard(page, CHORE_NAME)
    await card.waitFor()
    await openScheduleModal(page, card)

    // Select a day to show the deadline row
    await page.locator('.day-chips').getByRole('button', { name: 'Tu' }).click()
    await expect(page.locator('.default-deadline-row')).toBeVisible()

    // Time picker is visible by default
    await expect(
      page.locator('.default-deadline-row').locator('.time-picker-popover'),
    ).toBeVisible()

    // Click "Clear (Anytime)" — time picker hides, "Anytime" label appears
    await page
      .locator('.default-deadline-row')
      .getByRole('button', { name: 'Clear (Anytime)' })
      .click()
    await expect(
      page.locator('.default-deadline-row').locator('.time-picker-popover'),
    ).not.toBeVisible()
    await expect(page.locator('.default-deadline-row').getByText('Anytime')).toBeVisible()

    // Click "Set deadline" — time picker reappears
    await page
      .locator('.default-deadline-row')
      .getByRole('button', { name: 'Set deadline' })
      .click()
    await expect(
      page.locator('.default-deadline-row').locator('.time-picker-popover'),
    ).toBeVisible()
  })

  test('2.4 Exception time — "Set different time" creates per-day override', async ({ page }) => {
    await page.goto(`/parent/${childId}`)
    const card = choreCard(page, CHORE_NAME)
    await card.waitFor()
    await openScheduleModal(page, card)

    // Select Monday and Wednesday
    await page.locator('.day-chips').getByRole('button', { name: 'Mo' }).click()
    await page.locator('.day-chips').getByRole('button', { name: 'We' }).click()

    // Wednesday row: click "Set different time"
    const weRow = page.locator('.exception-row').filter({
      has: page.locator('.exception-day-name', { hasText: 'Wednesday' }),
    })
    await weRow.getByRole('button', { name: 'Set different time' }).click()

    // Wednesday now shows its own time picker
    await expect(weRow.locator('.time-picker-popover')).toBeVisible()

    // Monday row still shows the default label (no time picker override)
    const moRow = page.locator('.exception-row').filter({
      has: page.locator('.exception-day-name', { hasText: 'Monday' }),
    })
    await expect(moRow.locator('.default-label')).toBeVisible()
    await expect(moRow.locator('.time-picker-popover')).not.toBeVisible()
  })

  test('2.5 Exception time — "Reset to default" removes the override', async ({ page }) => {
    await page.goto(`/parent/${childId}`)
    const card = choreCard(page, CHORE_NAME)
    await card.waitFor()
    await openScheduleModal(page, card)

    // Set up Monday + Wednesday, add Wednesday exception
    await page.locator('.day-chips').getByRole('button', { name: 'Mo' }).click()
    await page.locator('.day-chips').getByRole('button', { name: 'We' }).click()
    const weRow = page.locator('.exception-row').filter({
      has: page.locator('.exception-day-name', { hasText: 'Wednesday' }),
    })
    await weRow.getByRole('button', { name: 'Set different time' }).click()
    await expect(weRow.locator('.time-picker-popover')).toBeVisible()

    // Reset Wednesday to default
    await weRow.getByRole('button', { name: 'Reset to default' }).click()
    await expect(weRow.locator('.default-label')).toBeVisible()
    await expect(weRow.locator('.time-picker-popover')).not.toBeVisible()
  })

  test('2.6 Save with specific days — schedule persists on reopen', async ({ page }) => {
    await page.goto(`/parent/${childId}`)
    const card = choreCard(page, CHORE_NAME)
    await card.waitFor()
    await openScheduleModal(page, card)

    // Select Monday and Friday
    await page.locator('.day-chips').getByRole('button', { name: 'Mo' }).click()
    await page.locator('.day-chips').getByRole('button', { name: 'Fr' }).click()

    // Set deadline to 03:00 PM
    const timePicker = page.locator('.default-deadline-row').locator('.time-picker-popover')
    await setTimePicker(page, timePicker, 3, 0, 'PM')

    // Save
    await page.getByRole('button', { name: 'Save' }).click()
    await expect(page.locator('.modal-title')).not.toBeVisible()

    // Navigate fresh to reset card ready-state, then reopen to verify
    await page.goto(`/parent/${childId}`)
    await card.waitFor()
    await openScheduleModal(page, card)
    await expect(page.locator('.day-chips').getByRole('button', { name: 'Mo' })).toHaveClass(
      /active/,
    )
    await expect(page.locator('.day-chips').getByRole('button', { name: 'Fr' })).toHaveClass(
      /active/,
    )
    await expect(page.locator('.default-deadline-row').locator('.time-display')).toHaveText(
      '03:00 PM',
    )
  })

  test('2.7 Save with zero days deletes the schedule', async ({ page, request }) => {
    // Seed: create a days schedule so the modal opens with existing days
    await setDaysSchedule(request, childId, choreId, [nonTodayDayIndex()], { hour: 9, minute: 0 })

    await page.goto(`/parent/${childId}`)
    const card = choreCard(page, CHORE_NAME)
    await card.waitFor()
    await openScheduleModal(page, card)

    // Deselect all active chips
    const chips = page.locator('.day-chips').getByRole('button')
    for (const chip of await chips.all()) {
      const cls = await chip.getAttribute('class')
      if (cls?.includes('active')) await chip.click()
    }

    // Save (removing schedule)
    await page.getByRole('button', { name: 'Save' }).click()
    await expect(page.locator('.modal-title')).not.toBeVisible()

    // Navigate fresh to reset card ready-state, then reopen to verify no days selected
    await page.goto(`/parent/${childId}`)
    await card.waitFor()
    await openScheduleModal(page, card)
    for (const chip of await page.locator('.day-chips').getByRole('button').all()) {
      await expect(chip).not.toHaveClass(/active/)
    }
  })

  test('2.8 Dirty detection — changing days enables Save', async ({ page, request }) => {
    const nonToday = nonTodayDayIndex()
    await setDaysSchedule(request, childId, choreId, [nonToday], { hour: 8, minute: 0 })

    await page.goto(`/parent/${childId}`)
    const card = choreCard(page, CHORE_NAME)
    await card.waitFor()
    await openScheduleModal(page, card)

    // Save should be disabled (nothing changed yet)
    await expect(page.getByRole('button', { name: 'Save' })).toBeDisabled()

    // Toggle a different day chip → dirty
    const otherDay = (nonToday + 1) % 7
    const dayLabels = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']
    await page.locator('.day-chips').getByRole('button', { name: dayLabels[otherDay] }).click()
    await expect(page.getByRole('button', { name: 'Save' })).toBeEnabled()
  })
})
