import { z } from "zod"

export const appUserRoleSchema = z.enum(["admin", "operator", "viewer"])
export const permLevelSchema = z.enum(["none", "read", "write"])
export const interfaceTypeSchema = z.enum(["ether", "gre", "wg", "other"])

export const sectionPermSchema = z.object({
  section: z.string().min(1),
  level: permLevelSchema,
})

export const serverPermSchema = z.object({
  serverId: z.string().min(1),
  level: permLevelSchema,
})

export const userBindingSchema = z.object({
  id: z.string().min(1),
  userId: z.string().min(1),
  serverId: z.number().int().positive(),
  serverName: z.string(),
  serverSite: z.string(),
  serverCountry: z.string(),
  interfaceName: z.string().min(1),
  interfaceType: interfaceTypeSchema,
  peerPublicKey: z.string().default(""),
  peerName: z.string().default(""),
  comment: z.string(),
  createdAt: z.string(),
  updatedAt: z.string(),
})

export const appUserReadSchema = z.object({
  id: z.string().min(1),
  name: z.string(),
  login: z.string(),
  email: z.string(),
  role: appUserRoleSchema,
  active: z.boolean(),
  avatar: z.string(),
  lastSeen: z.string().nullable(),
  sections: z.array(sectionPermSchema),
  servers: z.array(serverPermSchema),
  bindings: z.array(userBindingSchema),
  createdAt: z.string(),
  updatedAt: z.string(),
})

export const appUserCreateSchema = z.object({
  name: z.string().min(1),
  login: z.string().min(1),
  email: z.string().min(1),
  role: appUserRoleSchema.default("viewer"),
  active: z.boolean().default(true),
  avatar: z.string().optional(),
  lastSeen: z.string().nullable().optional(),
  sections: z.array(sectionPermSchema).default([]),
  servers: z.array(serverPermSchema).default([]),
})

export const appUserUpdateSchema = appUserCreateSchema.partial()

export const appUserIdParamSchema = z.object({
  id: z.string().min(1),
})

export const bindingIdParamSchema = z.object({
  id: z.string().min(1),
  bindingId: z.string().min(1),
})

export const userBindingCreateSchema = z.object({
  serverId: z.coerce.number().int().positive(),
  interfaceName: z.string().min(1),
  interfaceType: interfaceTypeSchema.optional(),
  peerPublicKey: z.string().optional(),
  peerName: z.string().optional(),
  comment: z.string().optional(),
})

export const interfaceCatalogQuerySchema = z.object({
  serverId: z.coerce.number().int().positive(),
})

export const catalogPeerSchema = z.object({
  publicKey: z.string(),
  name: z.string(),
  comment: z.string(),
  allowedIps: z.array(z.string()),
  latestHandshake: z.string().optional(),
  boundUserId: z.string().nullable(),
  boundUserLogin: z.string().nullable(),
})

export const catalogInterfaceSchema = z.object({
  name: z.string(),
  type: interfaceTypeSchema,
  running: z.boolean(),
  disabled: z.boolean(),
  boundUserId: z.string().nullable(),
  boundUserLogin: z.string().nullable(),
  peers: z.array(catalogPeerSchema).optional(),
  peersError: z.string().optional(),
})

export const appUserListSchema = z.array(appUserReadSchema)

export type AppUserRole = z.infer<typeof appUserRoleSchema>
export type PermLevel = z.infer<typeof permLevelSchema>
export type InterfaceType = z.infer<typeof interfaceTypeSchema>
export type SectionPerm = z.infer<typeof sectionPermSchema>
export type ServerPerm = z.infer<typeof serverPermSchema>
export type UserBinding = z.infer<typeof userBindingSchema>
export type AppUserRead = z.infer<typeof appUserReadSchema>
export type AppUserCreate = z.infer<typeof appUserCreateSchema>
export type AppUserUpdate = z.infer<typeof appUserUpdateSchema>
export type UserBindingCreate = z.infer<typeof userBindingCreateSchema>
export type CatalogPeer = z.infer<typeof catalogPeerSchema>
export type CatalogInterface = z.infer<typeof catalogInterfaceSchema>
