const test = require('node:test')
const assert = require('node:assert/strict')
const request = require('supertest')

const env = require('../../src/config/env')
const { createApp } = require('../../src/index')
const userService = require('../../src/services/userService')

test('POST /api/health 返回统一结构', async () => {
    const app = createApp()
    const response = await request(app).post('/api/health').send({})

    assert.equal(response.status, 200)
    assert.equal(response.body.code, 200)
    assert.equal(response.body.msg, '服务运行正常')
    assert.equal(response.body.data.status, 'healthy')
})

test('POST /api/test-helloworld 返回统一结构', async () => {
    const app = createApp()
    const response = await request(app).post('/api/test-helloworld').send({})

    assert.equal(response.status, 200)
    assert.equal(response.body.code, 200)
    assert.equal(response.body.msg, '请求成功')
    assert.equal(response.body.data.message, 'Hello, World!')
})

test('未匹配路由返回统一 404', async () => {
    const app = createApp()
    const response = await request(app).get('/not-found-route')

    assert.equal(response.status, 404)
    assert.equal(response.body.code, 404)
    assert.equal(response.body.msg, 'Route not found')
    assert.equal(response.body.data.path, '/not-found-route')
})

test('POST /api/wechat/login 未注册用户返回 404', async (t) => {
    const origin = userService.authenticateWechatUser
    userService.authenticateWechatUser = async () => {
        const error = new Error('未注册用户')
        error.statusCode = 404
        throw error
    }

    t.after(() => {
        userService.authenticateWechatUser = origin
    })

    const app = createApp()
    const response = await request(app)
        .post('/api/wechat/login')
        .send({ users_wx_code: 'mock-code-success' })

    assert.equal(response.status, 404)
    assert.equal(response.body.code, 404)
    assert.equal(response.body.msg, '未注册用户')
})

test('POST /api/wechat/login 非 JSON 请求体返回 415', async () => {
    const app = createApp()
    const response = await request(app)
        .post('/api/wechat/login')
        .set('Content-Type', 'application/x-www-form-urlencoded')
        .send('users_wx_code=mock-code')

    assert.equal(response.status, 415)
    assert.equal(response.body.code, 415)
    assert.equal(response.body.msg, '请求体必须为 application/json')
})

test('POST /api/wechat/login 成功时返回 is_info_complete', async (t) => {
    const origin = userService.authenticateWechatUser
    userService.authenticateWechatUser = async () => ({
        is_info_complete: true,
        status: 'login_success',
        token: 'mock-token',
        user: {
            users_id: 'U1003',
            users_type: '注册用户',
            users_name: '李四',
        },
    })

    t.after(() => {
        userService.authenticateWechatUser = origin
    })

    const app = createApp()
    const response = await request(app)
        .post('/api/wechat/login')
        .send({ users_wx_code: 'mock-code' })

    assert.equal(response.status, 200)
    assert.equal(response.body.code, 200)
    assert.equal(response.body.msg, '登录成功')
    assert.equal(response.body.data.is_info_complete, true)
    assert.equal(response.body.data.user.users_type, '注册用户')
})

test('POST /api/wechat/profile 更新成功后返回脱敏手机号', async (t) => {
    const origin = userService.updateWechatUserProfile
    userService.updateWechatUserProfile = async () => ({
        status: 'update_success',
        user: {
            users_id: 'U1002',
            users_type: '注册用户',
            users_name: '张三',
            users_phone: '13800138000',
            users_phone_masked: '138****8000',
            users_picture: 'https://example.com/a.png',
        },
    })

    t.after(() => {
        userService.updateWechatUserProfile = origin
    })

    const token = require('jsonwebtoken').sign({ users_id: 'U1002', users_wx_openid: 'openid-1' }, env.jwtSecret, {
        expiresIn: env.jwtExpiresIn,
    })

    const app = createApp()
    const response = await request(app)
        .post('/api/wechat/profile')
        .set('users_wx_openid', 'openid-1')
        .set('Authorization', `Bearer ${token}`)
        .send({
            users_name: '张三',
            users_phone_code: 'phone-code',
            users_picture: 'https://example.com/a.png',
        })

    assert.equal(response.status, 200)
    assert.equal(response.body.code, 200)
    assert.equal(response.body.msg, '信息更新成功')
    assert.equal(response.body.data.user.users_phone_masked, '138****8000')
    assert.equal(response.body.data.user.users_type, '注册用户')
})

test('POST /api/wechat/profile 缺少 token 返回 401', async () => {
    const app = createApp()
    const response = await request(app)
        .post('/api/wechat/profile')
        .set('users_wx_openid', 'openid-1')
        .send({
            users_name: '张三',
            users_phone_code: 'phone-code',
            users_picture: 'https://example.com/a.png',
        })

    assert.equal(response.status, 401)
    assert.equal(response.body.code, 401)
})

test('POST /api/wechat/refresh-token 返回 token', async (t) => {
    const origin = userService.refreshWechatToken
    userService.refreshWechatToken = async () => ({
        token: 'new-token',
    })

    t.after(() => {
        userService.refreshWechatToken = origin
    })

    const app = createApp()
    const response = await request(app)
        .post('/api/wechat/refresh-token')
        .set('users_wx_openid', 'openid-1')
        .send({})

    assert.equal(response.status, 200)
    assert.equal(response.body.code, 200)
    assert.equal(response.body.msg, '刷新成功')
    assert.equal(response.body.data.token, 'new-token')
})

test('POST /api/wechat/refresh-token 缺少 users_wx_openid 返回 401', async () => {
    const app = createApp()
    const response = await request(app)
        .post('/api/wechat/refresh-token')
        .send({})

    assert.equal(response.status, 401)
    assert.equal(response.body.code, 401)
    assert.equal(response.body.msg, '请求头缺少 users_wx_openid')
})
