"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.VALID_MBTI_TYPES = void 0;
exports.validateHexColor = validateHexColor;
exports.validateMBTI = validateMBTI;
exports.validateDNA = validateDNA;
exports.fillDefaults = fillDefaults;
const uuid_1 = require("uuid");
// --- Exported constants ---
exports.VALID_MBTI_TYPES = [
    'ISTJ', 'ISFJ', 'INFJ', 'INTJ',
    'ISTP', 'ISFP', 'INFP', 'INTP',
    'ESTP', 'ESFP', 'ENFP', 'ENTP',
    'ESTJ', 'ESFJ', 'ENFJ', 'ENTJ',
];
const HEX_COLOR_REGEX = /^#[0-9A-Fa-f]{6}$/;
const VALID_STATUSES = ['active', 'inactive', 'creating'];
// --- Exported validation helpers ---
function validateHexColor(color) {
    return typeof color === 'string' && HEX_COLOR_REGEX.test(color);
}
function validateMBTI(mbti) {
    return typeof mbti === 'string' && exports.VALID_MBTI_TYPES.includes(mbti.toUpperCase());
}
// --- Internal helpers ---
function isObj(v) {
    return typeof v === 'object' && v !== null && !Array.isArray(v);
}
function reqStr(obj, key, prefix, errors) {
    if (typeof obj[key] !== 'string' || obj[key].length === 0) {
        errors.push(`${prefix}.${key} is required`);
    }
}
function reqNum(obj, key, prefix, errors, min, max) {
    const v = obj[key];
    if (typeof v !== 'number' || !Number.isFinite(v)) {
        errors.push(`${prefix}.${key} must be a number`);
    }
    else {
        if (v < min || v > max)
            errors.push(`${prefix}.${key} must be between ${min} and ${max}`);
    }
}
function reqHex(obj, key, prefix, errors) {
    if (typeof obj[key] !== 'string' || !validateHexColor(obj[key])) {
        errors.push(`${prefix}.${key} must be a valid HEX color (#RRGGBB)`);
    }
}
// --- Main validation ---
function validateDNA(data) {
    const errors = [];
    if (!isObj(data)) {
        return { valid: false, errors: ['DNA must be a non-null object'] };
    }
    const d = data;
    // Top-level fields
    if (typeof d.id !== 'string' || d.id.length === 0)
        errors.push('id is required');
    if (typeof d.createdAt !== 'string' || d.createdAt.length === 0)
        errors.push('createdAt is required');
    if (typeof d.updatedAt !== 'string' || d.updatedAt.length === 0)
        errors.push('updatedAt is required');
    if (!VALID_STATUSES.includes(d.status)) {
        errors.push('status must be one of: active, inactive, creating');
    }
    // 1. Identity
    if (!isObj(d.identity)) {
        errors.push('identity is required');
    }
    else {
        const id = d.identity;
        reqStr(id, 'name', 'identity', errors);
        reqNum(id, 'age', 'identity', errors, 0, 150);
        reqStr(id, 'nationality', 'identity', errors);
        reqStr(id, 'city', 'identity', errors);
        reqStr(id, 'occupation', 'identity', errors);
        if (!Array.isArray(id.personality_tags))
            errors.push('identity.personality_tags must be an array');
        if (typeof id.mbti !== 'string' || !validateMBTI(id.mbti)) {
            errors.push(`identity.mbti must be a valid MBTI type`);
        }
        if (typeof id.backstory !== 'string')
            errors.push('identity.backstory must be a string');
    }
    // 2. Physical Measurements
    if (!isObj(d.physicalMeasurements)) {
        errors.push('physicalMeasurements is required');
    }
    else {
        const pm = d.physicalMeasurements;
        reqNum(pm, 'height_cm', 'physicalMeasurements', errors, 50, 250);
        reqNum(pm, 'weight_kg', 'physicalMeasurements', errors, 20, 300);
        reqStr(pm, 'body_type', 'physicalMeasurements', errors);
        if (!isObj(pm.measurements)) {
            errors.push('physicalMeasurements.measurements is required');
        }
        else {
            const m = pm.measurements;
            reqNum(m, 'bust', 'measurements', errors, 50, 200);
            reqNum(m, 'waist', 'measurements', errors, 40, 200);
            reqNum(m, 'hips', 'measurements', errors, 50, 200);
        }
    }
    // 3. Skin Map HEX
    if (!isObj(d.skinMap)) {
        errors.push('skinMap is required');
    }
    else {
        const sm = d.skinMap;
        reqHex(sm, 'base', 'skinMap', errors);
        reqHex(sm, 'shadow', 'skinMap', errors);
        reqHex(sm, 'highlight', 'skinMap', errors);
    }
    // 4. Face Anatomy
    if (!isObj(d.faceAnatomy)) {
        errors.push('faceAnatomy is required');
    }
    else {
        const fa = d.faceAnatomy;
        for (const k of ['eye_shape', 'eye_color', 'eyebrow_shape', 'nose_type', 'lip_shape', 'cheekbones', 'jawline']) {
            reqStr(fa, k, 'faceAnatomy', errors);
        }
        if (!Array.isArray(fa.distinctive_marks))
            errors.push('faceAnatomy.distinctive_marks must be an array');
    }
    // 5. Hair DNA
    if (!isObj(d.hairDNA)) {
        errors.push('hairDNA is required');
    }
    else {
        const h = d.hairDNA;
        for (const k of ['style', 'length', 'texture'])
            reqStr(h, k, 'hairDNA', errors);
        for (const k of ['root_color', 'mid_color', 'highlight_color'])
            reqHex(h, k, 'hairDNA', errors);
    }
    // 6. Body Biometrics
    if (!isObj(d.bodyBiometrics)) {
        errors.push('bodyBiometrics is required');
    }
    else {
        const bb = d.bodyBiometrics;
        for (const k of ['body_type_detail', 'posture', 'skin_texture'])
            reqStr(bb, k, 'bodyBiometrics', errors);
    }
    // 7. Profile View
    if (!isObj(d.profileView)) {
        errors.push('profileView is required');
    }
    else {
        const pv = d.profileView;
        reqStr(pv, 'best_angle', 'profileView', errors);
        reqStr(pv, 'signature_pose', 'profileView', errors);
    }
    // 8. Expression & Motion
    if (!isObj(d.expressionMotion)) {
        errors.push('expressionMotion is required');
    }
    else {
        const em = d.expressionMotion;
        for (const k of ['default_expression', 'smile_type', 'gaze_style'])
            reqStr(em, k, 'expressionMotion', errors);
    }
    // 9. Makeup Style
    if (!isObj(d.makeupStyle)) {
        errors.push('makeupStyle is required');
    }
    else {
        const ms = d.makeupStyle;
        reqStr(ms, 'philosophy', 'makeupStyle', errors);
        reqStr(ms, 'skin_finish', 'makeupStyle', errors);
        if (!isObj(ms.colors)) {
            errors.push('makeupStyle.colors is required');
        }
        else {
            const c = ms.colors;
            reqHex(c, 'primary', 'makeupStyle.colors', errors);
            reqHex(c, 'secondary', 'makeupStyle.colors', errors);
            reqHex(c, 'accent', 'makeupStyle.colors', errors);
        }
    }
    // 10. Fashion Style
    if (!isObj(d.fashionStyle)) {
        errors.push('fashionStyle is required');
    }
    else {
        const fs = d.fashionStyle;
        reqStr(fs, 'aesthetic', 'fashionStyle', errors);
        if (!Array.isArray(fs.main_colors)) {
            errors.push('fashionStyle.main_colors must be an array');
        }
        else {
            fs.main_colors.forEach((c, i) => {
                if (!validateHexColor(c))
                    errors.push(`fashionStyle.main_colors[${i}] must be a valid HEX color`);
            });
        }
        if (!Array.isArray(fs.signature_pieces))
            errors.push('fashionStyle.signature_pieces must be an array');
    }
    // 11. Technical Settings
    if (!isObj(d.technicalSettings)) {
        errors.push('technicalSettings is required');
    }
    else {
        const ts = d.technicalSettings;
        for (const k of ['camera_body', 'portrait_lens', 'full_body_lens', 'film_stock'])
            reqStr(ts, k, 'technicalSettings', errors);
    }
    return { valid: errors.length === 0, errors };
}
// --- Fill defaults ---
function fillDefaults(partial) {
    const now = new Date().toISOString();
    return {
        id: partial.id ?? (0, uuid_1.v4)(),
        createdAt: partial.createdAt ?? now,
        updatedAt: partial.updatedAt ?? now,
        status: partial.status ?? 'creating',
        identity: {
            name: partial.identity?.name ?? 'Unnamed Character',
            age: partial.identity?.age ?? 25,
            nationality: partial.identity?.nationality ?? 'Turkish',
            city: partial.identity?.city ?? 'Istanbul',
            occupation: partial.identity?.occupation ?? 'Model',
            personality_tags: partial.identity?.personality_tags ?? [],
            mbti: partial.identity?.mbti ?? 'ENFP',
            backstory: partial.identity?.backstory ?? '',
        },
        physicalMeasurements: {
            height_cm: partial.physicalMeasurements?.height_cm ?? 170,
            weight_kg: partial.physicalMeasurements?.weight_kg ?? 55,
            body_type: partial.physicalMeasurements?.body_type ?? 'slim',
            measurements: {
                bust: partial.physicalMeasurements?.measurements?.bust ?? 85,
                waist: partial.physicalMeasurements?.measurements?.waist ?? 60,
                hips: partial.physicalMeasurements?.measurements?.hips ?? 90,
            },
        },
        skinMap: {
            base: partial.skinMap?.base ?? '#F5D0A9',
            shadow: partial.skinMap?.shadow ?? '#D4A574',
            highlight: partial.skinMap?.highlight ?? '#FDE8D0',
        },
        faceAnatomy: {
            eye_shape: partial.faceAnatomy?.eye_shape ?? 'almond',
            eye_color: partial.faceAnatomy?.eye_color ?? '#8B4513',
            eyebrow_shape: partial.faceAnatomy?.eyebrow_shape ?? 'arched',
            nose_type: partial.faceAnatomy?.nose_type ?? 'straight',
            lip_shape: partial.faceAnatomy?.lip_shape ?? 'full',
            cheekbones: partial.faceAnatomy?.cheekbones ?? 'high',
            jawline: partial.faceAnatomy?.jawline ?? 'soft',
            distinctive_marks: partial.faceAnatomy?.distinctive_marks ?? [],
        },
        hairDNA: {
            style: partial.hairDNA?.style ?? 'wavy',
            length: partial.hairDNA?.length ?? 'long',
            texture: partial.hairDNA?.texture ?? 'silky',
            root_color: partial.hairDNA?.root_color ?? '#1A1A1A',
            mid_color: partial.hairDNA?.mid_color ?? '#2C2C2C',
            highlight_color: partial.hairDNA?.highlight_color ?? '#4A3728',
        },
        bodyBiometrics: {
            body_type_detail: partial.bodyBiometrics?.body_type_detail ?? 'athletic slim',
            posture: partial.bodyBiometrics?.posture ?? 'upright',
            skin_texture: partial.bodyBiometrics?.skin_texture ?? 'smooth',
        },
        profileView: {
            best_angle: partial.profileView?.best_angle ?? 'three-quarter left',
            signature_pose: partial.profileView?.signature_pose ?? 'hand on hip',
        },
        expressionMotion: {
            default_expression: partial.expressionMotion?.default_expression ?? 'soft smile',
            smile_type: partial.expressionMotion?.smile_type ?? 'closed lip',
            gaze_style: partial.expressionMotion?.gaze_style ?? 'direct',
        },
        makeupStyle: {
            philosophy: partial.makeupStyle?.philosophy ?? 'natural glam',
            skin_finish: partial.makeupStyle?.skin_finish ?? 'dewy',
            colors: {
                primary: partial.makeupStyle?.colors?.primary ?? '#C48A6A',
                secondary: partial.makeupStyle?.colors?.secondary ?? '#8B5E3C',
                accent: partial.makeupStyle?.colors?.accent ?? '#D4756B',
            },
        },
        fashionStyle: {
            aesthetic: partial.fashionStyle?.aesthetic ?? 'casual chic',
            main_colors: partial.fashionStyle?.main_colors ?? ['#000000', '#FFFFFF', '#C48A6A'],
            signature_pieces: partial.fashionStyle?.signature_pieces ?? [],
        },
        technicalSettings: {
            camera_body: partial.technicalSettings?.camera_body ?? 'Sony A7IV',
            portrait_lens: partial.technicalSettings?.portrait_lens ?? '85mm f/1.4',
            full_body_lens: partial.technicalSettings?.full_body_lens ?? '35mm f/1.4',
            film_stock: partial.technicalSettings?.film_stock ?? 'Kodak Portra 400',
        },
    };
}
//# sourceMappingURL=dna-schema.js.map