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

// useRouter().push 를 캡처
const { pushMock } = vi.hoisted(() => ({ pushMock: vi.fn() }))
vi.mock('vue-router', () => ({ useRouter: () => ({ push: pushMock }) }))

// 아이디 로그인 플로우 검증용 — 운영에선 숨김(ID_LOGIN_ENABLED=false)이지만 로직은 유지되므로 켜서 테스트
vi.mock('@/config/features', () => ({ ID_LOGIN_ENABLED: true }))

vi.mock('@/api/authApi', () => ({
  authApi: {
    login: vi.fn(),
    signupEnabled: vi.fn(() => Promise.resolve({ enabled: true })),
    googleClientId: vi.fn(() => Promise.resolve({ clientId: '' })),
  },
}))

vi.mock('@capacitor/preferences', () => ({
  Preferences: {
    set: vi.fn(() => Promise.resolve()),
    get: vi.fn(() => Promise.resolve({ value: null })),
    remove: vi.fn(() => Promise.resolve()),
  },
}))

import { authApi } from '@/api/authApi'
import { useUiStore } from '@/stores/ui'
import LoginModal from '@/components/LoginModal.vue'

function mountOpen() {
  const ui = useUiStore()
  return { ui, wrapper: mount(LoginModal, { global: { stubs: { teleport: true } } }) }
}

async function submitLogin(wrapper) {
  await wrapper.find('input[autocomplete="username"]').setValue('u1')
  await wrapper.find('input[autocomplete="current-password"]').setValue('pw')
  await wrapper.find('form').trigger('submit')
  await flushPromises()
}

describe('LoginModal 로그인 플로우', () => {
  beforeEach(() => {
    setActivePinia(createPinia())
    localStorage.clear()
    authApi.login.mockResolvedValue({ token: 'tok', member: { id: 1, loginId: 'u1', name: 'N' } })
  })

  it('redirect 없으면 로그인 후 대시보드(/)로 이동', async () => {
    const { ui, wrapper } = mountOpen()
    ui.openLogin('')
    await wrapper.vm.$nextTick()

    await submitLogin(wrapper)

    expect(authApi.login).toHaveBeenCalledWith({ loginId: 'u1', password: 'pw', rememberMe: true })
    expect(pushMock).toHaveBeenCalledWith('/')
    expect(ui.loginOpen).toBe(false)
  })

  it('redirect 있으면 보존된 목적지로 이동', async () => {
    const { ui, wrapper } = mountOpen()
    ui.openLogin('/account/wallets')
    await wrapper.vm.$nextTick()

    await submitLogin(wrapper)

    expect(pushMock).toHaveBeenCalledWith('/account/wallets')
  })

  it('로그인 실패 시 에러 표시 + 이동 없음', async () => {
    authApi.login.mockRejectedValueOnce({ response: { data: { message: '아이디 또는 비밀번호가 올바르지 않습니다.' } } })
    const { ui, wrapper } = mountOpen()
    ui.openLogin('')
    await wrapper.vm.$nextTick()

    await submitLogin(wrapper)

    expect(pushMock).not.toHaveBeenCalled()
    expect(ui.loginOpen).toBe(true)
    expect(wrapper.text()).toContain('아이디 또는 비밀번호가 올바르지 않습니다.')
  })
})
