"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.leaveBalanceResponseArraySchema = exports.leavesResponseSchema = exports.bulkUpdateLeaveStatusSchema = exports.leaveBalanceResponseSchema = exports.leaveResponseSchema = exports.leaveFilterSchema = exports.updateLeaveStatusSchema = exports.updateLeaveSchema = exports.createLeaveSchema = 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 optionalUuid = zod_1.z.preprocess((value) => {
    if (typeof value === 'string' && value.trim() === '')
        return undefined;
    return value;
}, zod_1.z.string().uuid().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 leaveStatusSchema = zod_1.z.enum([
    'pending',
    'approved',
    'rejected',
    'cancelled',
]);
const approverTypeSchema = zod_1.z.enum(['owner', 'member']);
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: shared_dto_1.imageSchema.nullable().optional(),
    role: zod_1.z.enum(['owner', 'admin', 'member']).optional(),
    department: zod_1.z
        .object({
        id: zod_1.z.string().uuid(),
        name: zod_1.z.string(),
    })
        .nullable()
        .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();
exports.createLeaveSchema = zod_1.z
    .object({
    member_id: zod_1.z.string().uuid({ message: 'Member ID is required' }),
    start_date: zod_1.z.coerce.date({ message: 'Start date is required' }),
    end_date: zod_1.z.coerce.date({ message: 'End date is required' }),
    approver_id: optionalUuid,
    approver_type: approverTypeSchema.optional(),
    leave_type: zod_1.z
        .enum([
        'annual',
        'sick',
        'casual',
        'maternity',
        'paternity',
        'personal',
        'compensatory',
        'unpaid',
        'day_off',
    ], {
        message: 'Invalid leave type',
    })
        .optional(),
    reason: optionalString,
    status: leaveStatusSchema.optional(),
    document: optionalFileSchema,
})
    .superRefine((data, ctx) => {
    if (data.end_date < data.start_date) {
        ctx.addIssue({
            code: zod_1.z.ZodIssueCode.custom,
            path: ['end_date'],
            message: 'End date must be after or equal to start date',
        });
    }
});
exports.updateLeaveSchema = zod_1.z
    .object({
    member_id: optionalUuid,
    start_date: optionalDate,
    end_date: optionalDate,
    reason: optionalString,
    approver_id: optionalUuid,
    approver_type: approverTypeSchema.optional(),
    status: leaveStatusSchema.optional(),
    document: optionalFileSchema.nullable(),
})
    .refine((data) => Object.keys(data).length > 0, {
    message: 'At least one field must be provided',
})
    .superRefine((data, ctx) => {
    if (data.start_date && data.end_date && data.end_date < data.start_date) {
        ctx.addIssue({
            code: zod_1.z.ZodIssueCode.custom,
            path: ['end_date'],
            message: 'End date must be after or equal to start date',
        });
    }
});
exports.updateLeaveStatusSchema = zod_1.z
    .object({
    status: leaveStatusSchema,
    approver_type: approverTypeSchema.optional(),
    approver_id: optionalUuid,
})
    .superRefine((data, ctx) => {
    if (data.status === 'approved' || data.status === 'rejected') {
        if (!data.approver_type) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                path: ['approver_type'],
                message: 'Approver type is required when approving or rejecting leave',
            });
        }
        if (!data.approver_id) {
            ctx.addIssue({
                code: zod_1.z.ZodIssueCode.custom,
                path: ['approver_id'],
                message: 'Approver ID is required when approving or rejecting leave',
            });
        }
    }
});
exports.leaveFilterSchema = zod_1.z
    .object({
    member_id: optionalUuid,
    memberId: optionalUuid,
    status: leaveStatusSchema.optional(),
    start_date: optionalString,
    end_date: optionalString,
    department_id: optionalUuid,
    data_scope: zod_1.z.enum(['own', 'all']).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)),
})
    .transform(({ memberId, ...rest }) => ({
    ...rest,
    member_id: rest.member_id ?? memberId,
}));
exports.leaveResponseSchema = zod_1.z.object({
    id: zod_1.z.string().uuid().optional(),
    member_id: zod_1.z.string().uuid().optional(),
    member: memberPreviewSchema.optional().nullable(),
    start_date: zod_1.z
        .date()
        .transform((date) => date.toISOString())
        .optional(),
    end_date: zod_1.z
        .date()
        .transform((date) => date.toISOString())
        .optional(),
    reason: 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}`,
        };
    })
        .nullable()
        .optional(),
    status: leaveStatusSchema.optional(),
    leave_type: optionalString,
    approver_type: approverTypeSchema.optional().nullable(),
    approver_owner_id: zod_1.z.string().uuid().optional().nullable(),
    approver_member_id: zod_1.z.string().uuid().optional().nullable(),
    approver_owner: zod_1.z
        .object({
        id: zod_1.z.string().uuid(),
        name: zod_1.z.string(),
        email: zod_1.z.string().email(),
        image: shared_dto_1.imageSchema.nullable().optional(),
    })
        .optional()
        .nullable(),
    approver_member: memberPreviewSchema.optional().nullable(),
    approved_at: zod_1.z
        .date()
        .transform((date) => date.toISOString())
        .optional()
        .nullable(),
    created_at: shared_dto_1.dateTransformSchema,
    updated_at: shared_dto_1.dateTransformSchema,
});
exports.leaveBalanceResponseSchema = zod_1.z.object({
    id: zod_1.z.string().uuid(),
    member_id: zod_1.z.string().uuid(),
    first_name: zod_1.z.string().optional(),
    last_name: zod_1.z.string().optional(),
    image: shared_dto_1.imageSchema,
    department_id: zod_1.z.string().uuid().optional(),
    department_name: zod_1.z.string().optional(),
    used_leaves: zod_1.z.number().optional(),
    remaining_leaves: zod_1.z.number().optional(),
    total_leaves: zod_1.z.number().optional(),
});
exports.bulkUpdateLeaveStatusSchema = zod_1.z.object({
    leave_ids: zod_1.z.array(zod_1.z.string().uuid()).min(1, {
        message: 'At least one leave ID must be provided',
    }),
    status: leaveStatusSchema,
    approver_type: approverTypeSchema.optional(),
    approver_id: optionalUuid,
});
exports.leavesResponseSchema = zod_1.z.array(exports.leaveResponseSchema);
exports.leaveBalanceResponseArraySchema = zod_1.z.array(exports.leaveBalanceResponseSchema);
//# sourceMappingURL=leaves.dto.js.map