import { z } from "zod"

export const serverTypeSchema = z.enum(["jump-host", "exit-node", "home-router"])
export const serverStatusSchema = z.enum(["online", "offline"])

export const wanUplinkSchema = z.object({
  id: z.string(),
  name: z.string(),
  isp: z.string(),
  iface: z.string(),
  ip: z.string(),
  maxDl: z.number(),
  maxUl: z.number(),
})

export const serverCreateSchema = z.object({
  host: z.string().min(1, "Host is required"),
  port: z.number().int().positive().default(443),
  username: z.string().default("admin"),
  password: z.string().default(""),
  useSsl: z.boolean().default(true),
  verifySsl: z.boolean().default(false),
  name: z.string().default(""),
  type: serverTypeSchema.default("home-router"),
  site: z.string().default(""),
  country: z.string().default(""),
  asn: z.string().default(""),
  comment: z.string().default(""),
  enabled: z.boolean().default(true),
  lanSubnet: z.string().default(""),
  wanUplinks: z.array(wanUplinkSchema).default([]),
})

export const serverUpdateSchema = serverCreateSchema.partial().omit({ host: true }).extend({
  host: z.string().min(1).optional(),
})

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

export const snapshotsQuerySchema = z.object({
  limit: z.coerce.number().int().positive().max(500).default(50),
})

export const testConnectionSchema = z.object({
  host: z.string().min(1),
  port: z.number().int().positive().default(443),
  useSsl: z.boolean().default(true),
  verifySsl: z.boolean().default(false),
  apiPath: z.string().default("/rest"),
  username: z.string().default("admin"),
  password: z.string().default(""),
})

export const serverReadSchema = z.object({
  id: z.number().int(),
  name: z.string(),
  host: z.string(),
  port: z.number().int(),
  useSsl: z.boolean(),
  verifySsl: z.boolean(),
  username: z.string(),
  password: z.string(),
  type: serverTypeSchema,
  site: z.string(),
  country: z.string(),
  asn: z.string(),
  comment: z.string(),
  enabled: z.boolean(),
  lanSubnet: z.string(),
  wanUplinks: z.array(wanUplinkSchema),
  createdAt: z.string(),
  updatedAt: z.string(),
  status: z.union([serverStatusSchema, z.null()]),
  latency: z.union([z.number(), z.null()]),
  os: z.union([z.string(), z.null()]),
  model: z.union([z.string(), z.null()]),
  uptime: z.union([z.string(), z.null()]),
  cpuLoad: z.union([z.number(), z.null()]),
  freeMemory: z.union([z.number(), z.null()]),
  totalMemory: z.union([z.number(), z.null()]),
  identityName: z.union([z.string(), z.null()]),
  sessions: z.number().int(),
  polledAt: z.union([z.string(), z.null()]),
})

export const snapshotReadSchema = z.object({
  id: z.number().int(),
  serverId: z.number().int(),
  polledAt: z.string(),
  status: serverStatusSchema,
  latencyMs: z.union([z.number(), z.null()]),
  rosVersion: z.union([z.string(), z.null()]),
  boardName: z.union([z.string(), z.null()]),
  uptime: z.union([z.string(), z.null()]),
  cpuLoad: z.union([z.number().int(), z.null()]),
  freeMemory: z.union([z.number().int(), z.null()]),
  totalMemory: z.union([z.number().int(), z.null()]),
  identityName: z.union([z.string(), z.null()]),
})

export const serverListSchema = z.array(serverReadSchema)
export const snapshotListSchema = z.array(snapshotReadSchema)

export type ServerType = z.infer<typeof serverTypeSchema>
export type WanUplink = z.infer<typeof wanUplinkSchema>
export type ServerCreate = z.infer<typeof serverCreateSchema>
export type ServerUpdate = z.infer<typeof serverUpdateSchema>
export type ServerRead = z.infer<typeof serverReadSchema>
export type SnapshotRead = z.infer<typeof snapshotReadSchema>
export type ServerIdParam = z.infer<typeof serverIdParamSchema>
export type SnapshotsQuery = z.infer<typeof snapshotsQuerySchema>
export type TestConnectionRequest = z.infer<typeof testConnectionSchema>
