import { z } from "zod"

export const certUsageSchema = z.enum([
  "server",
  "client",
  "ca",
  "crl-sign",
])

export const certStatusSchema = z.enum(["valid", "expired", "revoked"])

export const certificateDtoSchema = z.object({
  id: z.string().min(1),
  name: z.string().min(1),
  serverId: z.string().min(1),
  serverName: z.string().optional(),
  commonName: z.string(),
  sans: z.array(z.string()),
  issuedBy: z.string(),
  validFrom: z.string(),
  validUntil: z.string(),
  daysLeft: z.number().int(),
  keySize: z.number().int().nonnegative(),
  usage: z.array(certUsageSchema),
  trusted: z.boolean(),
  status: certStatusSchema,
  acmeStatus: z.string().optional(),
})

export const certificatesListResponseSchema = z.object({
  certificates: z.array(certificateDtoSchema),
  failures: z.array(z.object({
    serverId: z.string(),
    serverName: z.string().optional(),
    error: z.string(),
  })),
})

export const certificateTrustStoreSchema = z.enum([
  "www",
  "api",
  "sstp",
  "ovpn",
  "ipsec",
  "email",
  "radius",
  "fetch",
  "container",
])

export const certificateIssueRequestSchema = z.object({
  serverId: z.union([z.string(), z.number()]),
  certName: z.string().min(1).max(64),
  domainNames: z.array(z.string().min(1)).min(1),
  keyType: z.enum(["rsa2048", "ec256"]).optional(),
  trustStore: z.array(certificateTrustStoreSchema).optional(),
})

export const certificateIssueJobStatusSchema = z.enum([
  "queued",
  "running",
  "done",
  "failed",
])

export const certificateIssueStepSchema = z.enum([
  "queued",
  "acme_order",
  "dns_challenge",
  "finalize",
  "import",
  "cleanup",
  "done",
])

export const certificateIssueJobSchema = z.object({
  id: z.string().min(1),
  status: certificateIssueJobStatusSchema,
  step: certificateIssueStepSchema,
  serverId: z.string(),
  certName: z.string(),
  domainNames: z.array(z.string()),
  requestedAt: z.string(),
  startedAt: z.string().optional(),
  finishedAt: z.string().optional(),
  error: z.string().optional(),
})

export const acmeCloudflareSettingsDtoSchema = z.object({
  directoryUrl: z.string().url(),
  defaultZoneId: z.string().optional(),
  tokenConfigured: z.boolean(),
  updatedAt: z.string().optional(),
})

export const putAcmeCloudflareSettingsSchema = z.object({
  directoryUrl: z.string().url().optional(),
  defaultZoneId: z.union([z.string(), z.null()]).optional(),
  cloudflareApiToken: z.union([z.string(), z.null()]).optional(),
})

export const testAcmeCloudflareSettingsSchema = z.object({
  cloudflareApiToken: z.string().optional(),
})

export const certificateRenewSettingsDtoSchema = z.object({
  enabled: z.boolean(),
  intervalSec: z.number().int().min(300),
  renewBeforeDays: z.number().int().min(1).max(90),
  lastCollectedAt: z.string().nullable().optional(),
  lastDurationMs: z.number().int().nullable().optional(),
  lastError: z.string().nullable().optional(),
  updatedAt: z.string().optional(),
})

export const putCertificateRenewSettingsSchema = z.object({
  enabled: z.boolean().optional(),
  intervalSec: z.number().int().min(300).optional(),
  renewBeforeDays: z.number().int().min(1).max(90).optional(),
})

export type CertificateDto = z.infer<typeof certificateDtoSchema>
export type CertificatesListResponse = z.infer<typeof certificatesListResponseSchema>
export type CertificateIssueRequest = z.infer<typeof certificateIssueRequestSchema>
export type CertificateIssueJob = z.infer<typeof certificateIssueJobSchema>
export type AcmeCloudflareSettingsDto = z.infer<typeof acmeCloudflareSettingsDtoSchema>
export type CertificateRenewSettingsDto = z.infer<typeof certificateRenewSettingsDtoSchema>
