"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.noticesResponseSchema = exports.noticeResponseSchema = exports.noticeFilterSchema = exports.UpdateNoticeAcknowledgmentSchema = exports.updateNoticeSchema = exports.createNoticeSchema = void 0;
const zod_1 = require("zod");
const shared_dto_1 = require("../shared/shared.dto");
const optionalString = zod_1.z.preprocess((value) => {
    if (typeof value === 'string' && value.trim() === '')
        return undefined;
    return value;
}, zod_1.z.string().trim().optional());
const optionalDate = zod_1.z.preprocess((value) => {
    if (value === null || value === undefined || value === '')
        return undefined;
    return value;
}, zod_1.z.coerce.date().optional());
const optionalBool = zod_1.z.preprocess((value) => {
    if (value === null || value === undefined || value === '')
        return undefined;
    if (typeof value === 'boolean')
        return value;
    if (typeof value === 'string') {
        const normalized = value.trim().toLowerCase();
        if (normalized === 'true')
            return true;
        if (normalized === 'false')
            return false;
    }
    return value;
}, zod_1.z.boolean().optional());
const optionalFileSchema = zod_1.z
    .any()
    .transform((value) => {
    if (!value ||
        typeof value !== 'object' ||
        !('file_name' in value) ||
        typeof value.file_name !== 'string' ||
        value.file_name.trim() === '') {
        return undefined;
    }
    const host = process.env.SERVER_HOST ?? '';
    const hasHost = host.length > 0 && value.file_name.startsWith(host);
    return {
        ...value,
        file_name: hasHost ? value.file_name : `${host}/${value.file_name}`,
    };
})
    .optional();
const noticeStatusSchema = zod_1.z.enum(['published', 'draft', 'archived']);
const prioritySchema = zod_1.z.enum(['low', 'medium', 'high', 'critical']);
const legacyStatusSchema = zod_1.z.enum(['active', 'inactive', 'deleted']);
const normalizedStatusSchema = zod_1.z
    .union([noticeStatusSchema, legacyStatusSchema])
    .optional()
    .transform((val) => {
    if (val === undefined)
        return undefined;
    if (val === 'active')
        return 'published';
    if (val === 'inactive')
        return 'draft';
    if (val === 'deleted')
        return 'archived';
    return val;
});
const departmentPreviewSchema = zod_1.z.object({
    id: zod_1.z.string().uuid(),
    name: zod_1.z.string(),
    department_code: zod_1.z.string(),
});
const memberPreviewSchema = zod_1.z.object({
    id: zod_1.z.string().uuid(),
    employee_id: zod_1.z.string(),
    first_name: zod_1.z.string(),
    last_name: shared_dto_1.defaultTransformSchema,
    nickname: shared_dto_1.defaultTransformSchema,
    image: zod_1.z.any().optional(),
});
const targetTypeSchema = zod_1.z.enum(['department', 'individual']);
const validateNoticeTargeting = (data, ctx) => {
    const departmentIds = data.department_ids ?? [];
    const memberIds = data.member_ids ?? [];
    const targetType = data.target_type ??
        (memberIds.length > 0
            ? 'individual'
            : departmentIds.length > 0
                ? 'department'
                : undefined);
    if (!targetType) {
        ctx.addIssue({
            code: zod_1.z.ZodIssueCode.custom,
            path: ['target_type'],
            message: 'Either department_ids or member_ids must be provided',
        });
        return;
    }
    if (targetType === 'department') {
        if (departmentIds.length === 0) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                path: ['department_ids'],
                message: 'At least one department is required',
            });
        }
        if (memberIds.length > 0) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                path: ['member_ids'],
                message: 'member_ids must be empty when targeting departments',
            });
        }
    }
    if (targetType === 'individual') {
        if (memberIds.length === 0) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                path: ['member_ids'],
                message: 'At least one member is required',
            });
        }
        if (departmentIds.length > 0) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                path: ['department_ids'],
                message: 'department_ids must be empty when targeting individuals',
            });
        }
    }
};
exports.createNoticeSchema = zod_1.z
    .object({
    title: zod_1.z.string().trim().min(2, { message: 'Notice title is required' }),
    content: optionalString,
    document: optionalFileSchema,
    status: noticeStatusSchema.optional(),
    priority: prioritySchema.optional(),
    created_by: optionalString,
    published_at: optionalDate,
    expire_at: optionalDate,
    required_acknowledgment: optionalBool,
    target_type: targetTypeSchema.optional(),
    department_ids: zod_1.z.array(zod_1.z.string().uuid()).optional(),
    member_ids: zod_1.z.array(zod_1.z.string().uuid()).optional(),
})
    .superRefine((data, ctx) => {
    validateNoticeTargeting(data, ctx);
    if (data.published_at &&
        data.expire_at &&
        data.expire_at < data.published_at) {
        ctx.addIssue({
            code: zod_1.z.ZodIssueCode.custom,
            path: ['expire_at'],
            message: 'Expire date must be greater than published date',
        });
    }
});
exports.updateNoticeSchema = zod_1.z
    .object({
    title: optionalString,
    content: optionalString,
    document: optionalFileSchema.nullable(),
    status: noticeStatusSchema.optional(),
    priority: prioritySchema.optional(),
    created_by: optionalString,
    published_at: optionalDate,
    expire_at: optionalDate,
    required_acknowledgment: optionalBool,
    target_type: targetTypeSchema.optional(),
    department_ids: zod_1.z.array(zod_1.z.string().uuid()).optional(),
    member_ids: zod_1.z.array(zod_1.z.string().uuid()).optional(),
})
    .refine((data) => Object.keys(data).length > 0, {
    message: 'At least one field must be provided',
})
    .superRefine((data, ctx) => {
    if (data.target_type !== undefined ||
        data.department_ids !== undefined ||
        data.member_ids !== undefined) {
        validateNoticeTargeting({
            target_type: data.target_type,
            department_ids: data.department_ids ?? [],
            member_ids: data.member_ids ?? [],
        }, ctx);
    }
    if (data.published_at &&
        data.expire_at &&
        data.expire_at < data.published_at) {
        ctx.addIssue({
            code: zod_1.z.ZodIssueCode.custom,
            path: ['expire_at'],
            message: 'Expire date must be greater than published date',
        });
    }
});
exports.UpdateNoticeAcknowledgmentSchema = zod_1.z.object({
    member_id: zod_1.z.string().uuid(),
    acknowledgment: zod_1.z.enum(['up', 'down']),
});
exports.noticeFilterSchema = zod_1.z.object({
    status: normalizedStatusSchema,
    priority: prioritySchema.optional(),
    required_acknowledgment: optionalBool,
    from: optionalDate,
    to: optionalDate,
    department_id: zod_1.z.preprocess((value) => {
        if (typeof value === 'string' && value.trim() === '')
            return undefined;
        return value;
    }, zod_1.z.string().uuid().optional()),
    search: zod_1.z.string().trim().optional(),
    page: zod_1.z.preprocess((value) => {
        if (value === undefined || value === null || value === '')
            return 1;
        const parsed = Number(value);
        return Number.isNaN(parsed) ? value : parsed;
    }, zod_1.z.number().int().min(1).default(1)),
    limit: zod_1.z.preprocess((value) => {
        if (value === undefined || value === null || value === '')
            return 10;
        const parsed = Number(value);
        return Number.isNaN(parsed) ? value : parsed;
    }, zod_1.z.number().int().min(1).max(100).default(10)),
    data_scope: zod_1.z.enum(['own', 'all']).optional(),
});
exports.noticeResponseSchema = zod_1.z.object({
    id: zod_1.z.string().uuid().optional(),
    title: zod_1.z.string().optional(),
    content: shared_dto_1.defaultTransformSchema,
    document: zod_1.z
        .any()
        .transform((val) => {
        if (!val || !val?.file_name)
            return null;
        const isHostIncluded = val?.file_name?.includes(process.env.SERVER_HOST);
        return {
            ...val,
            file_name: isHostIncluded
                ? val?.file_name
                : `${process.env.SERVER_HOST}/${val?.file_name}`,
        };
    })
        .optional(),
    status: normalizedStatusSchema,
    priority: prioritySchema.optional(),
    created_by: shared_dto_1.defaultTransformSchema,
    published_at: shared_dto_1.dateTransformSchema.nullable(),
    expire_at: shared_dto_1.dateTransformSchema.nullable(),
    required_acknowledgment: zod_1.z.boolean().optional(),
    target_type: targetTypeSchema.optional(),
    departments: zod_1.z.array(departmentPreviewSchema).optional(),
    recipients: zod_1.z.array(memberPreviewSchema).optional(),
    up_acknowledgment: zod_1.z.array(memberPreviewSchema).optional(),
    down_acknowledgment: zod_1.z.array(memberPreviewSchema).optional(),
    created_at: shared_dto_1.dateTransformSchema,
    updated_at: shared_dto_1.dateTransformSchema,
});
exports.noticesResponseSchema = zod_1.z.array(exports.noticeResponseSchema);
//# sourceMappingURL=notice.dto.js.map