import { z } from 'zod';
import { OsType, AuthType, ServerStatus, AlertType } from './types';

/**
 * 服务器分类表单校验
 */
export const serverCategoryFormSchema = z.object({
    name: z.string().min(1, '分类名称不能为空').max(50, '分类名称不能超过50个字符'),
    code: z.string().min(1, '分类编码不能为空').max(50, '分类编码不能超过50个字符'),
    icon: z.string().max(50, '图标不能超过50个字符').optional(),
    description: z.string().max(500, '描述不能超过500个字符').optional(),
    sort: z.number().min(0, '排序不能小于0').default(0),
    enabled: z.boolean().default(true),
});

/**
 * 服务器表单校验
 */
export const serverFormSchema = z.object({
    serverName: z.string().min(1, '服务器名称不能为空').max(100, '服务器名称不能超过100个字符'),
    hostIp: z.string()
        .min(1, 'IP地址不能为空')
        .regex(/^(\d{1,3}\.){3}\d{1,3}$/, 'IP地址格式不正确')
        .refine((ip) => {
            const parts = ip.split('.');
            return parts.every((part) => {
                const num = parseInt(part, 10);
                return num >= 0 && num <= 255;
            });
        }, 'IP地址范围必须在0-255之间'),
    sshPort: z.number()
        .min(1, 'SSH端口不能小于1')
        .max(65535, 'SSH端口不能大于65535')
        .default(22),
    sshUser: z.string().min(1, 'SSH用户名不能为空').max(50, 'SSH用户名不能超过50个字符'),
    authType: z.nativeEnum(AuthType, {
        errorMap: () => ({ message: '请选择认证方式' })
    }),
    sshPassword: z.string().max(200, 'SSH密码不能超过200个字符').optional(),
    sshPrivateKey: z.string().optional(),
    sshPassphrase: z.string().max(200, '私钥密码不能超过200个字符').optional(),
    categoryId: z.number().optional(),
    osType: z.nativeEnum(OsType, {
        errorMap: () => ({ message: '请选择操作系统类型' })
    }),
    osVersion: z.string().max(100, '操作系统版本不能超过100个字符').optional(),
    hostname: z.string().max(100, '主机名不能超过100个字符').optional(),
    status: z.nativeEnum(ServerStatus).optional(),
    description: z.string().max(500, '描述不能超过500个字符').optional(),
    cpuCores: z.union([z.number().min(1, 'CPU核心数必须大于0'), z.null(), z.undefined()]).optional(),
    memorySize: z.union([z.number().min(1, '内存大小必须大于0'), z.null(), z.undefined()]).optional(),
    diskSize: z.union([z.number().min(1, '磁盘大小必须大于0'), z.null(), z.undefined()]).optional(),
    tags: z.string().optional(),
}).superRefine((data, ctx) => {
    // 如果选择密码认证，必须填写密码
    if (data.authType === AuthType.PASSWORD && !data.sshPassword) {
        ctx.addIssue({
            code: 'custom',
            message: 'SSH密码不能为空',
            path: ['sshPassword'],
        });
    }
    // 如果选择密钥认证，必须填写私钥
    if (data.authType === AuthType.KEY && !data.sshPrivateKey) {
        ctx.addIssue({
            code: 'custom',
            message: 'SSH私钥不能为空',
            path: ['sshPrivateKey'],
        });
    }
});

export type ServerCategoryFormValues = z.infer<typeof serverCategoryFormSchema>;
export type ServerFormValues = z.infer<typeof serverFormSchema>;

/**
 * 告警规则表单校验
 */
export const alertRuleFormSchema = z.object({
    serverId: z.union([z.number(), z.null()]).default(null),
    ruleName: z.string().min(1, '规则名称不能为空').max(100, '规则名称不能超过100个字符'),
    alertType: z.nativeEnum(AlertType, {
        errorMap: () => ({ message: '请选择告警类型' })
    }),
    warningThreshold: z.number().min(0, '警告阈值不能小于0'),
    criticalThreshold: z.number().min(0, '严重阈值不能小于0'),
    durationMinutes: z.number()
        .min(1, '持续时长至少为1分钟'),
    enabled: z.boolean().default(true),
    description: z.string().max(500, '描述不能超过500个字符').optional(),
}).superRefine((data, ctx) => {
    // 根据告警类型验证阈值范围
    const isPercentageType = [AlertType.CPU, AlertType.MEMORY, AlertType.DISK].includes(data.alertType);
    const isNetworkType = data.alertType === AlertType.NETWORK;
    
    if (isPercentageType) {
        // CPU/内存/磁盘使用率：0-100
        if (data.warningThreshold > 100) {
            ctx.addIssue({
                code: 'custom',
                message: '警告阈值不能大于100',
                path: ['warningThreshold'],
            });
        }
        if (data.criticalThreshold > 100) {
            ctx.addIssue({
                code: 'custom',
                message: '严重阈值不能大于100',
                path: ['criticalThreshold'],
            });
        }
    } else if (isNetworkType) {
        // 网络流量：0-10000 MB/s
        if (data.warningThreshold > 10000) {
            ctx.addIssue({
                code: 'custom',
                message: '警告阈值不能大于10000',
                path: ['warningThreshold'],
            });
        }
        if (data.criticalThreshold > 10000) {
            ctx.addIssue({
                code: 'custom',
                message: '严重阈值不能大于10000',
                path: ['criticalThreshold'],
            });
        }
    }
    
    // 严重阈值必须大于警告阈值
    if (data.criticalThreshold <= data.warningThreshold) {
        ctx.addIssue({
            code: 'custom',
            message: '严重阈值必须大于警告阈值',
            path: ['criticalThreshold'],
        });
    }
    
    // 服务器状态告警的阈值必须是整数
    if (data.alertType === AlertType.SERVER_STATUS) {
        if (!Number.isInteger(data.warningThreshold)) {
            ctx.addIssue({
                code: 'custom',
                message: '服务器状态告警的警告阈值必须是整数',
                path: ['warningThreshold'],
            });
        }
        if (!Number.isInteger(data.criticalThreshold)) {
            ctx.addIssue({
                code: 'custom',
                message: '服务器状态告警的严重阈值必须是整数',
                path: ['criticalThreshold'],
            });
        }
    }
});

export type AlertRuleFormValues = z.infer<typeof alertRuleFormSchema>;

