import { mount, flushPromises } from '@vue/test-utils'
import { describe, expect, it, vi, beforeEach, type Mocked } from 'vitest'

vi.mock('@/api/scheduleCenter', () => ({
  scheduleCenterApi: {
    month: vi.fn(),
    date: vi.fn(),
  },
}))

vi.mock('@/api/todo', () => ({
  todoApi: {
    create: vi.fn(),
    update: vi.fn(),
    delete: vi.fn(),
  },
}))

vi.mock('@/api/task', () => ({
  taskApi: {
    create: vi.fn(),
    update: vi.fn(),
    delete: vi.fn(),
  },
}))

vi.mock('@/api/reminder', () => ({
  reminderApi: {
    create: vi.fn(),
    update: vi.fn(),
    delete: vi.fn(),
  },
}))

vi.mock('@/api/goal', () => ({
  goalApi: {
    create: vi.fn(),
    update: vi.fn(),
    delete: vi.fn(),
  },
}))

import ScheduleCenterPage from './index.vue'
import { scheduleCenterApi } from '@/api/scheduleCenter'
import { todoApi } from '@/api/todo'
import { taskApi } from '@/api/task'
import { reminderApi } from '@/api/reminder'
import { goalApi } from '@/api/goal'

const mockedScheduleCenterApi = scheduleCenterApi as Mocked<typeof scheduleCenterApi>
const mockedTodoApi = todoApi as Mocked<typeof todoApi>
const mockedTaskApi = taskApi as Mocked<typeof taskApi>
const mockedReminderApi = reminderApi as Mocked<typeof reminderApi>
const mockedGoalApi = goalApi as Mocked<typeof goalApi>

const monthPayload = {
  data: {
    month: '2026-03',
    days: [
      {
        date: '2026-03-26',
        todo_total: 1,
        todo_completed: 0,
        task_due_total: 2,
        high_priority_total: 1,
        reminder_total: 1,
        goal_total: 1,
      },
    ],
  },
}

const datePayload = {
  data: {
    date: '2026-03-26',
    todos: [{ id: 'todo-1', title: 'Write plan', is_completed: false, source: 'manual', source_detail: null, todo_date: '2026-03-26', completed_at: null, created_at: '', updated_at: '' }],
    tasks: [{ id: 'task-1', title: 'Ship center', status: 'todo', priority: 'high', created_at: '', updated_at: '' }],
    reminders: [{ id: 'rem-1', title: 'Standup', note: null, reminder_at: '2026-03-26T09:00:00Z', status: 'pending', is_dismissed: false, created_at: '', updated_at: '' }],
    goals: [{ id: 'goal-1', title: 'Launch', note: null, goal_date: '2026-03-26', status: 'active', created_at: '', updated_at: '' }],
    summary: {
      date: '2026-03-26',
      todo_total: 1,
      todo_completed: 0,
      task_due_total: 2,
      high_priority_total: 1,
      reminder_total: 1,
      goal_total: 1,
    },
    generated_at: '2026-03-26T00:00:00Z',
  },
}

describe('ScheduleCenterPage', () => {
  beforeEach(() => {
    mockedScheduleCenterApi.month.mockResolvedValue(monthPayload as never)
    mockedScheduleCenterApi.date.mockResolvedValue(datePayload as never)
    mockedTodoApi.create.mockResolvedValue({ data: {} } as never)
    mockedTodoApi.update.mockResolvedValue({ data: {} } as never)
    mockedTodoApi.delete.mockResolvedValue({ data: {} } as never)
    mockedTaskApi.create.mockResolvedValue({ data: {} } as never)
    mockedTaskApi.update.mockResolvedValue({ data: {} } as never)
    mockedTaskApi.delete.mockResolvedValue({ data: {} } as never)
    mockedReminderApi.create.mockResolvedValue({ data: {} } as never)
    mockedReminderApi.update.mockResolvedValue({ data: {} } as never)
    mockedReminderApi.delete.mockResolvedValue({ data: {} } as never)
    mockedGoalApi.create.mockResolvedValue({ data: {} } as never)
    mockedGoalApi.update.mockResolvedValue({ data: {} } as never)
    mockedGoalApi.delete.mockResolvedValue({ data: {} } as never)
  })

  it('loads month and selected day data on mount', async () => {
    const wrapper = mount(ScheduleCenterPage)
    await flushPromises()

    expect(mockedScheduleCenterApi.month).toHaveBeenCalledTimes(1)
    expect(mockedScheduleCenterApi.date).toHaveBeenCalledTimes(1)
    expect(wrapper.find('.date-panel').exists()).toBe(true)
    expect(wrapper.text()).toContain('SCHEDULE CENTER / TACTICAL CALENDAR MATRIX')
    expect(wrapper.text()).toContain('查看当前设置')
    expect(wrapper.text()).toContain('新增安排')
    expect(wrapper.text()).toContain('Write plan')
    expect(wrapper.text()).toContain('Ship center')
    expect(wrapper.text()).not.toContain('新增 TODO')
  })

  it('keeps the side panel open and refreshes when selecting a calendar cell', async () => {
    const wrapper = mount(ScheduleCenterPage)
    await flushPromises()

    expect(wrapper.find('.date-panel').exists()).toBe(true)

    await wrapper.find('.calendar-cell').trigger('click')
    await flushPromises()
    expect(wrapper.find('.date-panel').exists()).toBe(true)
    expect(mockedScheduleCenterApi.date.mock.calls.length).toBeGreaterThanOrEqual(2)
  })

  it('switches panel to create mode and creates a todo', async () => {
    const wrapper = mount(ScheduleCenterPage)
    await flushPromises()

    const panelTabs = wrapper.findAll('.panel-tab')
    await panelTabs[1].trigger('click')
    await flushPromises()

    expect(wrapper.text()).toContain('新增 TODO')
    expect(wrapper.text()).toContain('新增任务')
    expect(wrapper.text()).toContain('新增提醒')
    expect(wrapper.text()).toContain('新增目标')
    expect(wrapper.text()).not.toContain('Write plan')

    const inputs = wrapper.findAll('input')
    await inputs[0].setValue('New todo item')
    const addButtons = wrapper.findAll('.create-row button')
    await addButtons[0].trigger('click')
    await flushPromises()

    expect(mockedTodoApi.create).toHaveBeenCalledWith({ title: 'New todo item', todo_date: expect.any(String) })
    expect(mockedScheduleCenterApi.date.mock.calls.length).toBeGreaterThanOrEqual(3)
    expect(mockedScheduleCenterApi.month.mock.calls.length).toBeGreaterThanOrEqual(3)
  })
})

