import { z } from "zod";

export const entityIdSchema = z.string().min(1).max(191);

export const ipv4Schema = z
  .string()
  .trim()
  .regex(
    /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}$/,
    "Must be a valid IPv4 address",
  );

export const optionalTextSchema = z.string().trim().max(5000).nullable().optional();

export const hostnameSchema = z
  .string()
  .trim()
  .min(1)
  .max(253)
  .regex(
    /^(?=.{1,253}$)(?!-)(?:[a-zA-Z0-9-]{1,63}\.)+[a-zA-Z]{2,63}$/,
    "Must be a valid domain or subdomain",
  );

export const serverStatusSchema = z.enum(["active", "maintenance", "inactive"]);
export const serviceTypeSchema = z.enum(["web_app", "mail", "database", "api", "proxy", "other"]);
export const serviceProtocolSchema = z.enum(["http", "https", "tcp", "udp", "other"]);
export const serviceStatusSchema = z.enum(["active", "down", "maintenance"]);
export const domainCheckStatusSchema = z.enum(["MATCH", "MISMATCH", "UNRESOLVED"]);

export const byIdSchema = z.object({
  id: entityIdSchema,
});

export const serverCreateSchema = z.object({
  name: z.string().trim().min(1).max(120),
  primaryIpAddress: ipv4Schema,
  secondaryIpAddress: ipv4Schema.nullable().optional(),
  operatingSystem: z.string().trim().max(120).nullable().optional(),
  location: z.string().trim().max(120).nullable().optional(),
  provider: z.string().trim().max(120).nullable().optional(),
  description: optionalTextSchema,
  status: serverStatusSchema.default("active"),
});

export const serverUpdateSchema = serverCreateSchema.partial().extend({
  id: entityIdSchema,
});

export const serviceListSchema = z
  .object({
    serverId: entityIdSchema.optional(),
  })
  .optional();

export const serviceCreateSchema = z.object({
  serverId: entityIdSchema,
  name: z.string().trim().min(1).max(120),
  type: serviceTypeSchema.default("other"),
  internalPort: z.coerce.number().int().min(1).max(65535).nullable().optional(),
  externalPort: z.coerce.number().int().min(1).max(65535).nullable().optional(),
  protocol: serviceProtocolSchema.default("http"),
  status: serviceStatusSchema.default("active"),
  description: optionalTextSchema,
});

export const serviceUpdateSchema = serviceCreateSchema.partial().extend({
  id: entityIdSchema,
});

export const domainListSchema = z
  .object({
    serviceId: entityIdSchema.optional(),
  })
  .optional();

export const domainCreateSchema = z.object({
  serviceId: entityIdSchema,
  name: hostnameSchema,
  expectedServerIp: ipv4Schema.optional(),
  remarks: optionalTextSchema,
});

export const domainUpdateSchema = z.object({
  id: entityIdSchema,
  serviceId: entityIdSchema.optional(),
  name: hostnameSchema.optional(),
  expectedServerIp: ipv4Schema.optional(),
  remarks: optionalTextSchema,
});

export const noteListSchema = z
  .object({
    serverId: entityIdSchema.optional(),
  })
  .optional();

export const noteCreateSchema = z.object({
  serverId: entityIdSchema,
  title: z.string().trim().min(1).max(160),
  content: z.string().trim().min(1).max(10000),
  category: z.string().trim().max(80).nullable().optional(),
});

export const noteUpdateSchema = noteCreateSchema.partial().extend({
  id: entityIdSchema,
});
