import { getJson, sendJson } from '@/services/httpClient'
import type {
  AdminAuditLogListFilters,
  AdminAuditLogResult,
  AdminHotelCreateRequest,
  AdminHotelListFilters,
  AdminHotelResult,
  AdminHotelStatusUpdateRequest,
  AdminHotelUpdateRequest,
  AdminMenuCreateRequest,
  AdminMenuListFilters,
  AdminMenuResult,
  AdminMenuUpdateRequest,
  AdminPermissionResult,
  AdminRoleCreateRequest,
  AdminRoleDetailResult,
  AdminRoleListFilters,
  AdminRoleListItemResult,
  AdminRolePermissionAssignmentRequest,
  AdminRoleUpdateRequest,
  AdminUserCreateRequest,
  AdminUserDetailResult,
  AdminUserHotelAssignmentRequest,
  AdminUserListFilters,
  AdminUserListItemResult,
  AdminUserPasswordResetRequest,
  AdminUserPasswordResetResult,
  AdminUserRoleAssignmentRequest,
  AdminUserUpdateRequest,
  PlatformPageResult,
} from '@/types/systemAdmin'

export async function fetchAdminUsers(
  filters: AdminUserListFilters = {},
): Promise<PlatformPageResult<AdminUserListItemResult>> {
  return getJson<PlatformPageResult<AdminUserListItemResult>>(withQuery('/api/admin/users', filters))
}

export async function fetchAdminUserDetail(userId: string): Promise<AdminUserDetailResult> {
  return getJson<AdminUserDetailResult>(`/api/admin/users/${encodeURIComponent(userId)}`)
}

export async function createAdminUser(request: AdminUserCreateRequest): Promise<AdminUserDetailResult> {
  return sendJson<AdminUserDetailResult>('/api/admin/users', 'POST', request)
}

export async function updateAdminUser(
  userId: string,
  request: AdminUserUpdateRequest,
): Promise<AdminUserDetailResult> {
  return sendJson<AdminUserDetailResult>(`/api/admin/users/${encodeURIComponent(userId)}`, 'PUT', request)
}

export async function assignAdminUserRoles(
  userId: string,
  request: AdminUserRoleAssignmentRequest,
): Promise<AdminUserDetailResult> {
  return sendJson<AdminUserDetailResult>(`/api/admin/users/${encodeURIComponent(userId)}/roles`, 'PUT', request)
}

export async function assignAdminUserHotels(
  userId: string,
  request: AdminUserHotelAssignmentRequest,
): Promise<AdminUserDetailResult> {
  return sendJson<AdminUserDetailResult>(`/api/admin/users/${encodeURIComponent(userId)}/hotels`, 'PUT', request)
}

export async function resetAdminUserPassword(
  userId: string,
  request: AdminUserPasswordResetRequest = {},
): Promise<AdminUserPasswordResetResult> {
  return sendJson<AdminUserPasswordResetResult>(
    `/api/admin/users/${encodeURIComponent(userId)}/password-reset`,
    'POST',
    request,
  )
}

export async function fetchAdminRoles(
  filters: AdminRoleListFilters = {},
): Promise<PlatformPageResult<AdminRoleListItemResult>> {
  return getJson<PlatformPageResult<AdminRoleListItemResult>>(withQuery('/api/admin/roles', filters))
}

export async function fetchAdminRoleDetail(roleId: string): Promise<AdminRoleDetailResult> {
  return getJson<AdminRoleDetailResult>(`/api/admin/roles/${encodeURIComponent(roleId)}`)
}

export async function createAdminRole(request: AdminRoleCreateRequest): Promise<AdminRoleDetailResult> {
  return sendJson<AdminRoleDetailResult>('/api/admin/roles', 'POST', request)
}

export async function updateAdminRole(
  roleId: string,
  request: AdminRoleUpdateRequest,
): Promise<AdminRoleDetailResult> {
  return sendJson<AdminRoleDetailResult>(`/api/admin/roles/${encodeURIComponent(roleId)}`, 'PUT', request)
}

export async function assignAdminRolePermissions(
  roleId: string,
  request: AdminRolePermissionAssignmentRequest,
): Promise<AdminRoleDetailResult> {
  return sendJson<AdminRoleDetailResult>(
    `/api/admin/roles/${encodeURIComponent(roleId)}/permissions`,
    'PUT',
    request,
  )
}

export async function fetchAdminPermissions(): Promise<AdminPermissionResult[]> {
  return getJson<AdminPermissionResult[]>('/api/admin/permissions')
}

export async function fetchAdminMenus(
  filters: AdminMenuListFilters = {},
): Promise<PlatformPageResult<AdminMenuResult>> {
  return getJson<PlatformPageResult<AdminMenuResult>>(withQuery('/api/admin/menus', filters))
}

export async function createAdminMenu(request: AdminMenuCreateRequest): Promise<AdminMenuResult> {
  return sendJson<AdminMenuResult>('/api/admin/menus', 'POST', request)
}

export async function updateAdminMenu(menuId: string, request: AdminMenuUpdateRequest): Promise<AdminMenuResult> {
  return sendJson<AdminMenuResult>(`/api/admin/menus/${encodeURIComponent(menuId)}`, 'PUT', request)
}

export async function fetchAdminHotels(
  filters: AdminHotelListFilters = {},
): Promise<PlatformPageResult<AdminHotelResult>> {
  return getJson<PlatformPageResult<AdminHotelResult>>(withQuery('/api/admin/hotels', filters))
}

export async function createAdminHotel(request: AdminHotelCreateRequest): Promise<AdminHotelResult> {
  return sendJson<AdminHotelResult>('/api/admin/hotels', 'POST', request)
}

export async function updateAdminHotel(hotelId: string, request: AdminHotelUpdateRequest): Promise<AdminHotelResult> {
  return sendJson<AdminHotelResult>(`/api/admin/hotels/${encodeURIComponent(hotelId)}`, 'PUT', request)
}

export async function updateAdminHotelStatus(
  hotelId: string,
  request: AdminHotelStatusUpdateRequest,
): Promise<AdminHotelResult> {
  return sendJson<AdminHotelResult>(`/api/admin/hotels/${encodeURIComponent(hotelId)}/status`, 'PUT', request)
}

export async function fetchAdminAudits(
  filters: AdminAuditLogListFilters = {},
): Promise<PlatformPageResult<AdminAuditLogResult>> {
  return getJson<PlatformPageResult<AdminAuditLogResult>>(withQuery('/api/admin/audits', filters))
}

function withQuery(path: string, params: object): string {
  const searchParams = new URLSearchParams()
  Object.entries(params).forEach(([key, value]) => {
    if (
      value === undefined ||
      value === null ||
      value === '' ||
      !['string', 'number', 'boolean'].includes(typeof value)
    ) {
      return
    }
    searchParams.set(key, String(value))
  })
  const query = searchParams.toString()
  return query ? `${path}?${query}` : path
}
