/**
 * API Mock 工具
 * 用于单元测试中模拟 API 响应
 */

import { vi } from 'vitest'
import * as fixtures from '../fixtures'

// Mock request 模块的类型
type MockedRequest = {
  get: ReturnType<typeof vi.fn>
  post: ReturnType<typeof vi.fn>
  put: ReturnType<typeof vi.fn>
  del: ReturnType<typeof vi.fn>
}

/**
 * 创建 API mock
 */
export function createApiMock() {
  return {
    get: vi.fn(),
    post: vi.fn(),
    put: vi.fn(),
    del: vi.fn()
  }
}

/**
 * 设置登录 API mock
 */
export function mockLoginApi(request: MockedRequest) {
  // login
  request.post.mockImplementation((url: string, data?: any) => {
    if (url === '/admin/auth/login') {
      if (data?.username === 'admin' && data?.password === '123456') {
        return Promise.resolve(fixtures.wrapResponse(fixtures.mockLoginResponse))
      }
      return Promise.resolve(fixtures.wrapErrorResponse('用户名或密码错误'))
    }
    if (url === '/admin/auth/logout') {
      return Promise.resolve(fixtures.wrapResponse(null))
    }
    if (url === '/admin/auth/password') {
      if (data?.oldPassword === '123456') {
        return Promise.resolve(fixtures.wrapResponse(null))
      }
      return Promise.resolve(fixtures.wrapErrorResponse('原密码错误'))
    }
    return Promise.resolve(fixtures.wrapErrorResponse('Not Found'))
  })

  // getInfo
  request.get.mockImplementation((url: string) => {
    if (url === '/admin/auth/info') {
      return Promise.resolve(fixtures.wrapResponse(fixtures.mockAdminInfo))
    }
    return Promise.resolve(fixtures.wrapErrorResponse('Not Found'))
  })
}

/**
 * 设置机器 API mock
 */
export function mockMachineApi(request: MockedRequest) {
  request.get.mockImplementation((url: string, params?: any) => {
    if (url === '/admin/machines/list') {
      return Promise.resolve(fixtures.wrapListResponse(fixtures.mockMachines))
    }
    if (url === '/admin/machines/detail') {
      const machine = fixtures.mockMachines.find((m) => m.id === params?.id)
      if (machine) {
        return Promise.resolve(fixtures.wrapResponse(machine))
      }
      return Promise.resolve(fixtures.wrapErrorResponse('机器不存在'))
    }
    return Promise.resolve(fixtures.wrapErrorResponse('Not Found'))
  })

  request.post.mockImplementation((url: string, data?: any, _config?: any) => {
    if (url === '/admin/machines/add') {
      const newMachine: (typeof fixtures.mockMachines)[0] = {
        id: fixtures.mockMachines.length + 1,
        machineId: data.machineId,
        name: data.name,
        location: data.location || '',
        description: data.description || '',
        enabled: true,
        cameraCount: 0,
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString()
      }
      return Promise.resolve(fixtures.wrapResponse(newMachine))
    }
    if (url === '/admin/machines/update') {
      const machine = fixtures.mockMachines.find((m) => m.id === data?.id)
      if (machine) {
        return Promise.resolve(fixtures.wrapResponse({ ...machine, ...data }))
      }
      return Promise.resolve(fixtures.wrapErrorResponse('机器不存在'))
    }
    if (url === '/admin/machines/delete') {
      const id = _config?.params?.id
      const machine = fixtures.mockMachines.find((m) => m.id === id)
      if (machine) {
        if (machine.cameraCount > 0) {
          return Promise.resolve(fixtures.wrapErrorResponse('该机器下存在摄像头，无法删除'))
        }
        return Promise.resolve(fixtures.wrapResponse(null))
      }
      return Promise.resolve(fixtures.wrapErrorResponse('机器不存在'))
    }
    return Promise.resolve(fixtures.wrapErrorResponse('Not Found'))
  })
}

/**
 * 设置摄像头 API mock
 */
export function mockCameraApi(request: MockedRequest) {
  request.get.mockImplementation((url: string, params?: any) => {
    if (url === '/admin/cameras/list') {
      let cameras = fixtures.mockCameras
      if (params?.machineId) {
        cameras = cameras.filter((c) => c.machineId === params.machineId)
      }
      return Promise.resolve(fixtures.wrapListResponse(cameras))
    }
    if (url === '/admin/cameras/detail') {
      const camera = fixtures.mockCameras.find((c) => c.id === params?.id)
      if (camera) {
        return Promise.resolve(fixtures.wrapResponse(camera))
      }
      return Promise.resolve(fixtures.wrapErrorResponse('摄像头不存在'))
    }
    if (url === '/camera/list') {
      return Promise.resolve(fixtures.wrapListResponse(fixtures.mockCameras))
    }
    if (url.startsWith('/camera/') && !url.includes('/ptz')) {
      const cameraId = url.split('/')[2]
      const camera = fixtures.mockCameras.find((c) => c.cameraId === cameraId)
      if (camera) {
        return Promise.resolve(fixtures.wrapResponse(camera))
      }
    }
    if (url === '/camera/current') {
      return Promise.resolve(fixtures.wrapResponse(fixtures.mockChannels[0]))
    }
    return Promise.resolve(fixtures.wrapErrorResponse('Not Found'))
  })

  request.post.mockImplementation((url: string, data?: any, config?: any) => {
    if (url === '/admin/cameras/add') {
      const newCamera = {
        id: fixtures.mockCameras.length + 1,
        ...data,
        status: 'OFFLINE',
        channels: [],
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString()
      }
      return Promise.resolve(fixtures.wrapResponse(newCamera))
    }
    if (url === '/admin/cameras/update') {
      const camera = fixtures.mockCameras.find((c) => c.id === data?.id)
      if (camera) {
        return Promise.resolve(fixtures.wrapResponse({ ...camera, ...data }))
      }
      return Promise.resolve(fixtures.wrapErrorResponse('摄像头不存在'))
    }
    if (url === '/admin/cameras/delete') {
      return Promise.resolve(fixtures.wrapResponse(null))
    }
    if (url === '/admin/cameras/check') {
      return Promise.resolve(fixtures.wrapResponse(true))
    }
    if (url === '/camera/switch') {
      const channel = fixtures.mockChannels.find((c) => c.channelId === data?.channelId)
      if (channel) {
        return Promise.resolve(fixtures.wrapResponse(channel))
      }
      return Promise.resolve(fixtures.wrapErrorResponse('通道不存在'))
    }
    if (url.includes('/ptz/start')) {
      return Promise.resolve(fixtures.wrapResponse(null))
    }
    if (url.includes('/ptz/stop')) {
      return Promise.resolve(fixtures.wrapResponse(null))
    }
    return Promise.resolve(fixtures.wrapErrorResponse('Not Found'))
  })
}

/**
 * 设置统计 API mock
 */
export function mockStatsApi(request: MockedRequest) {
  request.get.mockImplementation((url: string) => {
    if (url === '/admin/stats/dashboard') {
      return Promise.resolve(fixtures.wrapResponse(fixtures.mockDashboardStats))
    }
    return Promise.resolve(fixtures.wrapErrorResponse('Not Found'))
  })
}

/**
 * 设置所有 API mock
 */
export function mockAllApis(request: MockedRequest) {
  request.get.mockImplementation((url: string, params?: any) => {
    // Auth
    if (url === '/admin/auth/info') {
      return Promise.resolve(fixtures.wrapResponse(fixtures.mockAdminInfo))
    }
    // Machines
    if (url === '/admin/machines/list') {
      return Promise.resolve(fixtures.wrapListResponse(fixtures.mockMachines))
    }
    if (url === '/admin/machines/detail') {
      const machine = fixtures.mockMachines.find((m) => m.id === params?.id)
      return Promise.resolve(fixtures.wrapResponse(machine))
    }
    // Cameras
    if (url === '/admin/cameras/list') {
      return Promise.resolve(fixtures.wrapListResponse(fixtures.mockCameras))
    }
    if (url === '/camera/list') {
      return Promise.resolve(fixtures.wrapListResponse(fixtures.mockCameras))
    }
    // Stats
    if (url === '/admin/stats/dashboard') {
      return Promise.resolve(fixtures.wrapResponse(fixtures.mockDashboardStats))
    }
    return Promise.resolve(fixtures.wrapErrorResponse('Not Found'))
  })

  request.post.mockImplementation((url: string, data?: any) => {
    if (url === '/admin/auth/login') {
      if (data?.username === 'admin' && data?.password === '123456') {
        return Promise.resolve(fixtures.wrapResponse(fixtures.mockLoginResponse))
      }
      return Promise.resolve(fixtures.wrapErrorResponse('用户名或密码错误'))
    }
    if (url === '/admin/auth/logout') {
      return Promise.resolve(fixtures.wrapResponse(null))
    }
    return Promise.resolve(fixtures.wrapResponse(null))
  })
}
