import { get, post, type PageResult, type PageParams } from '@/lib/request'
import { USE_MOCK, delay, paginate, mockId, mockResponse } from '@/mock'
import { mockUsers } from '@/mock/system/users'
import { mockRoles } from '@/mock/system/roles'
import { mockMenuTree } from '@/mock/system/menus'
import { mockClients } from '@/mock/system/clients'
import { mockFiles } from '@/mock/system/files'
import { mockLogs } from '@/mock/system/logs'
import type { SystemUser, SystemRole, SystemMenu, SystemClient, SystemOss, OperationLog } from './system'

// ==================== User ====================

export async function getUserList(data: PageParams & { account?: string; phone?: string }) {
  if (USE_MOCK) {
    await delay()
    let filtered = [...mockUsers]
    if (data.keyword) filtered = filtered.filter(u => u.name.includes(data.keyword!) || u.account.includes(data.keyword!))
    return mockResponse(paginate(filtered, data.current, data.pageSize))
  }
  return post<{ data: PageResult<SystemUser> }>('/user/getUserList', data)
}

export async function saveUser(data: Partial<SystemUser>) {
  if (USE_MOCK) { await delay(); mockUsers.push({ ...data, id: mockId(), createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() } as SystemUser); return mockResponse(null, '创建成功') }
  return post<{ msg: string }>('/user/save', data)
}

export async function updateUser(data: Partial<SystemUser>) {
  if (USE_MOCK) { await delay(); const i = mockUsers.findIndex(u => u.id === data.id); if (i >= 0) Object.assign(mockUsers[i], data); return mockResponse(null, '更新成功') }
  return post<{ msg: string }>('/user/update', data)
}

export async function deleteUser(ids: string[]) {
  if (USE_MOCK) { await delay(); ids.forEach(id => { const i = mockUsers.findIndex(u => u.id === id); if (i >= 0) mockUsers.splice(i, 1) }); return mockResponse(null, '删除成功') }
  return post<{ msg: string }>('/user/delete', { ids })
}

export async function changePassword(data: { id: string; newPwd: string }) {
  if (USE_MOCK) { await delay(); return mockResponse(null, '密码修改成功') }
  return post<{ msg: string }>('/user/changePassword', data)
}

export async function grantRole(data: { userId: string; roleIds: string[] }) {
  if (USE_MOCK) {
    await delay()
    const user = mockUsers.find(u => u.id === data.userId)
    if (user) user.roles = mockRoles.filter(r => data.roleIds.includes(r.id)).map(r => ({ ...r }))
    return mockResponse(null, '角色分配成功')
  }
  return post<{ msg: string }>('/user/grantRole', data)
}

// ==================== Role ====================

export async function getRoleList(data: PageParams & { name?: string }) {
  if (USE_MOCK) {
    await delay()
    let filtered = [...mockRoles]
    if (data.keyword) filtered = filtered.filter(r => r.name.includes(data.keyword!))
    return mockResponse(paginate(filtered, data.current, data.pageSize))
  }
  return post<{ data: PageResult<SystemRole> }>('/role/getRoleList', data)
}

export async function getAllRoles() {
  if (USE_MOCK) { await delay(100); return mockResponse([...mockRoles]) }
  return post<{ data: SystemRole[] }>('/role/getAllRoles', {})
}

export async function saveRole(data: Partial<SystemRole>) {
  if (USE_MOCK) { await delay(); mockRoles.push({ ...data, id: mockId(), createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() } as SystemRole); return mockResponse(null, '创建成功') }
  return post<{ msg: string }>('/role/save', data)
}

export async function updateRole(data: Partial<SystemRole>) {
  if (USE_MOCK) { await delay(); const i = mockRoles.findIndex(r => r.id === data.id); if (i >= 0) Object.assign(mockRoles[i], data); return mockResponse(null, '更新成功') }
  return post<{ msg: string }>('/role/update', data)
}

export async function deleteRole(ids: string[]) {
  if (USE_MOCK) { await delay(); ids.forEach(id => { const i = mockRoles.findIndex(r => r.id === id); if (i >= 0) mockRoles.splice(i, 1) }); return mockResponse(null, '删除成功') }
  return post<{ msg: string }>('/role/delete', { ids })
}

export async function grantMenu(data: { roleId: string; menuIds: string[] }) {
  if (USE_MOCK) {
    await delay()
    const role = mockRoles.find(r => r.id === data.roleId)
    if (role) {
      const flatMenus = (items: SystemMenu[]): SystemMenu[] => items.flatMap(m => [m, ...(m.children ? flatMenus(m.children) : [])])
      role.menus = flatMenus(mockMenuTree).filter(m => data.menuIds.includes(m.id))
    }
    return mockResponse(null, '菜单授权成功')
  }
  return post<{ msg: string }>('/role/grantMenu', data)
}

// ==================== Menu ====================

export async function getAllMenuTree() {
  if (USE_MOCK) { await delay(); return mockResponse(mockMenuTree) }
  return post<{ data: SystemMenu[] }>('/menu/getAllMenuTree', {})
}

export async function getUserMenuTree() {
  if (USE_MOCK) { await delay(); return mockResponse(mockMenuTree) }
  return get<{ data: SystemMenu[] }>('/menu/getUserMenuTree')
}

export async function saveMenu(data: Partial<SystemMenu>) {
  if (USE_MOCK) { await delay(); return mockResponse(null, '创建成功') }
  return post<{ msg: string }>('/menu/save', data)
}

export async function updateMenu(data: Partial<SystemMenu>) {
  if (USE_MOCK) { await delay(); return mockResponse(null, '更新成功') }
  return post<{ msg: string }>('/menu/update', data)
}

export async function deleteMenu(id: string) {
  if (USE_MOCK) { await delay(); return mockResponse(null, '删除成功') }
  return get<{ msg: string }>('/menu/delete', { id })
}

// ==================== Client ====================

export async function getClientList(data: PageParams & { clientId?: string; name?: string }) {
  if (USE_MOCK) {
    await delay()
    let filtered = [...mockClients]
    if (data.keyword) filtered = filtered.filter(c => c.name.includes(data.keyword!) || c.clientId.includes(data.keyword!))
    return mockResponse(paginate(filtered, data.current, data.pageSize))
  }
  return post<{ data: PageResult<SystemClient> }>('/client/getClientList', data)
}

export async function saveClient(data: Partial<SystemClient>) {
  if (USE_MOCK) { await delay(); mockClients.push({ ...data, id: mockId(), createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() } as SystemClient); return mockResponse(null, '创建成功') }
  return post<{ msg: string }>('/client/save', data)
}

export async function updateClient(data: Partial<SystemClient>) {
  if (USE_MOCK) { await delay(); const i = mockClients.findIndex(c => c.id === data.id); if (i >= 0) Object.assign(mockClients[i], data); return mockResponse(null, '更新成功') }
  return post<{ msg: string }>('/client/update', data)
}

export async function deleteClient(ids: string[]) {
  if (USE_MOCK) { await delay(); ids.forEach(id => { const i = mockClients.findIndex(c => c.id === id); if (i >= 0) mockClients.splice(i, 1) }); return mockResponse(null, '删除成功') }
  return post<{ msg: string }>('/client/delete', { ids })
}

// ==================== File ====================

export async function getFileList(data: PageParams & { name?: string }) {
  if (USE_MOCK) {
    await delay()
    let filtered = [...mockFiles]
    if (data.keyword) filtered = filtered.filter(f => f.name.includes(data.keyword!))
    return mockResponse(paginate(filtered, data.current, data.pageSize))
  }
  return post<{ data: PageResult<SystemOss> }>('/oss/getFileList', data)
}

export async function uploadFile(_file: File) {
  if (USE_MOCK) { await delay(800); const f: SystemOss = { id: mockId(), name: _file.name, key: `uploads/${_file.name}`, url: `https://picsum.photos/seed/${Date.now()}/400/300`, suffix: _file.name.split('.').pop() || '', createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() }; mockFiles.unshift(f); return mockResponse({ file: f }, '上传成功') }
  const formData = new FormData(); formData.append('file', _file)
  return post<{ data: { file: SystemOss }; msg: string }>('/oss/upload', formData)
}

export async function deleteFile(ids: string[]) {
  if (USE_MOCK) { await delay(); ids.forEach(id => { const i = mockFiles.findIndex(f => f.id === id); if (i >= 0) mockFiles.splice(i, 1) }); return mockResponse(null, '删除成功') }
  return post<{ msg: string }>('/oss/delete', { ids })
}

// ==================== Operation Log ====================

export async function getOperationLogList(data: PageParams & { clientId?: string; method?: string; statusCode?: number }) {
  if (USE_MOCK) {
    await delay()
    let filtered = [...mockLogs]
    if (data.clientId) filtered = filtered.filter(l => l.clientId === data.clientId)
    if (data.method) filtered = filtered.filter(l => l.method === data.method)
    if (data.statusCode !== undefined) filtered = filtered.filter(l => l.statusCode === data.statusCode)
    if (data.keyword) filtered = filtered.filter(l => l.path.includes(data.keyword!) || l.title.includes(data.keyword!) || l.operatorName.includes(data.keyword!))
    return mockResponse(paginate(filtered, data.current, data.pageSize))
  }
  return post<{ data: PageResult<OperationLog> }>('/log/getOperationLogList', data)
}
