import {
  appUserReadSchema,
  catalogInterfaceSchema,
  userBindingSchema,
  type AppUserCreate,
  type AppUserRead,
  type AppUserUpdate,
  type CatalogInterface,
  type UserBinding,
  type UserBindingCreate,
} from "@mmapp/contracts/users"
import { z } from "zod"
import { requestJson } from "@/shared/api/http-client"
import type { AppUser, CatalogIface, InterfaceBinding } from "@/lib/users"

const usersListPayload = z.object({ users: z.array(appUserReadSchema) })
const userPayload = z.object({ user: appUserReadSchema })
const bindingPayload = z.object({ binding: userBindingSchema })
const catalogPayload = z.object({ interfaces: z.array(catalogInterfaceSchema) })

export function toFrontendBinding(b: UserBinding): InterfaceBinding {
  return {
    id: b.id,
    userId: b.userId,
    serverId: String(b.serverId),
    serverName: b.serverName,
    serverSite: b.serverSite,
    serverCountry: b.serverCountry,
    interfaceName: b.interfaceName,
    interfaceType: b.interfaceType,
    peerPublicKey: b.peerPublicKey || undefined,
    peerName: b.peerName || undefined,
    comment: b.comment,
  }
}

export function toFrontendUser(u: AppUserRead): AppUser {
  return {
    id: u.id,
    name: u.name,
    login: u.login,
    email: u.email,
    role: u.role,
    last: u.lastSeen ?? "—",
    avatar: u.avatar,
    active: u.active,
    sections: u.sections,
    servers: u.servers,
    bindings: u.bindings.map(toFrontendBinding),
  }
}

export async function listAppUsers(baseUrl: string): Promise<AppUser[]> {
  const payload = await requestJson<unknown>(baseUrl, "/api/users")
  return usersListPayload.parse(payload).users.map(toFrontendUser)
}

export async function createAppUser(baseUrl: string, data: AppUserCreate): Promise<AppUser> {
  const payload = await requestJson<unknown>(baseUrl, "/api/users", {
    method: "POST",
    body: JSON.stringify(data),
  })
  return toFrontendUser(userPayload.parse(payload).user)
}

export async function updateAppUser(baseUrl: string, id: string, data: AppUserUpdate): Promise<AppUser> {
  const payload = await requestJson<unknown>(baseUrl, `/api/users/${id}`, {
    method: "PATCH",
    body: JSON.stringify(data),
  })
  return toFrontendUser(userPayload.parse(payload).user)
}

export async function deleteAppUser(baseUrl: string, id: string): Promise<void> {
  await requestJson<void>(baseUrl, `/api/users/${id}`, { method: "DELETE" })
}

export async function createUserBinding(
  baseUrl: string,
  userId: string,
  data: UserBindingCreate,
): Promise<InterfaceBinding> {
  const payload = await requestJson<unknown>(baseUrl, `/api/users/${userId}/bindings`, {
    method: "POST",
    body: JSON.stringify(data),
  })
  return toFrontendBinding(bindingPayload.parse(payload).binding)
}

export async function deleteUserBinding(
  baseUrl: string,
  userId: string,
  bindingId: string,
): Promise<void> {
  await requestJson<void>(baseUrl, `/api/users/${userId}/bindings/${bindingId}`, { method: "DELETE" })
}

export async function listInterfaceCatalog(
  baseUrl: string,
  serverId: string,
): Promise<CatalogIface[]> {
  const payload = await requestJson<unknown>(
    baseUrl,
    `/api/users/interface-catalog?serverId=${encodeURIComponent(serverId)}`,
  )
  return catalogPayload.parse(payload).interfaces as CatalogInterface[]
}
