import { z } from "zod"

export const alertTypeSchema = z.enum([
  "gre-tunnel",
  "bgp-peer",
  "bgp-prefix",
  "gre-client",
  "server",
  "rtt",
  "loss",
  "traffic",
])
export const alertSeveritySchema = z.enum(["critical", "warning", "info"])
export const alertCooldownSchema = z.enum(["1м", "5м", "15м", "1ч", "4ч", "24ч"])
export const recoveryModeSchema = z.enum(["always", "never", "conditional"])
export const combineModeSchema = z.enum(["any", "all"])

export const alertGroupSchema = z.object({
  id: z.string().min(1),
  name: z.string().min(1),
  combineMode: combineModeSchema,
  enabled: z.boolean(),
  cooldownOverride: z.union([alertCooldownSchema, z.null()]),
})

export const alertRuleSchema = z
  .object({
    id: z.string().min(1),
    name: z.string().min(1),
    type: alertTypeSchema,
    target: z.string().optional(),
    targets: z.array(z.string().min(1)).optional(),
    groupId: z.string().nullable().optional(),
    condition: z.string().optional(),
    conditions: z.array(z.string().min(1)).optional(),
    severity: alertSeveritySchema,
    enabled: z.boolean(),
    cooldown: alertCooldownSchema,
    confirmStabilitySec: z.union([z.number().int().min(0).max(86400), z.null()]).optional(),
    recoveryMode: recoveryModeSchema.optional(),
    recoveryStabilitySec: z.union([z.number().int().min(0).max(86400), z.null()]).optional(),
    chatId: z.string(),
  })
  .refine((r) => (r.targets != null && r.targets.length > 0) || Boolean(r.target?.trim()), {
    message: "Нужен хотя бы один объект: targets или target",
    path: ["targets"],
  })
  .refine((r) => (r.conditions != null && r.conditions.length > 0) || Boolean(r.condition?.trim()), {
    message: "Нужно хотя бы одно условие: conditions или condition",
    path: ["conditions"],
  })

export const putRulesSchema = z.object({
  rules: z.array(alertRuleSchema),
  groups: z.array(alertGroupSchema).optional(),
})

export const putTelegramSchema = z.object({
  token: z.union([z.string(), z.null()]).optional(),
  chatId: z.string().optional(),
  messageThreadId: z.union([z.number().int().positive(), z.null()]).optional(),
})

export const rulePreviewTelegramSchema = z.object({
  name: z.string().min(1),
  targets: z.array(z.string().min(1)).min(1),
  conditionLine: z.string().min(1),
  severity: alertSeveritySchema,
  cooldown: alertCooldownSchema,
})

export const testTelegramSchema = z.object({
  token: z.string().optional(),
  chatId: z.string().optional(),
  messageThreadId: z.coerce.number().int().positive().optional(),
  rulePreview: rulePreviewTelegramSchema.optional(),
})

export type AlertGroup = z.infer<typeof alertGroupSchema>
export type AlertRule = z.infer<typeof alertRuleSchema>
export type PutRulesBody = z.infer<typeof putRulesSchema>
export type PutTelegramBody = z.infer<typeof putTelegramSchema>
export type RulePreviewTelegram = z.infer<typeof rulePreviewTelegramSchema>
export type TestTelegramBody = z.infer<typeof testTelegramSchema>
