/**
 * CONTOH PENGGUNAAN ERROR HANDLING YANG BARU
 * 
 * File ini berisi contoh-contoh bagaimana menggunakan error handling utilities
 * untuk membuat error messages yang detail dan mudah di-debug
 */

const { 
    createValidationError, 
    createNotFoundError,
    createUnauthorizedError,
    createConflictError 
} = require('./createError');
const ValidationHelper = require('./validationHelper');

// ============================================
// CONTOH 1: Validation Error dengan Field-Specific Messages
// ============================================
async function createUserExample(params) {
    const errors = {};
    
    // Validate required fields
    if (!params.email) {
        errors.email = 'Email is required';
    }
    if (!params.password) {
        errors.password = 'Password is required';
    }
    if (params.password && params.password.length < 8) {
        errors.password = 'Password must be at least 8 characters';
    }
    if (params.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(params.email)) {
        errors.email = 'Invalid email format';
    }
    
    // Throw validation error jika ada errors
    if (Object.keys(errors).length > 0) {
        throw createValidationError(errors, 'User validation failed');
    }
    
    // ... rest of code
}

// ============================================
// CONTOH 2: Menggunakan Validation Helper
// ============================================
async function createItemExample(params) {
    // Validate required fields
    ValidationHelper.validateRequired(params, ['name', 'price', 'category_id']);
    
    // Validate category exists
    await ValidationHelper.validateExists(
        require('../apps/sapps/helpers/db').Category, 
        params.category_id, 
        'Category'
    );
    
    // Validate price range
    ValidationHelper.validateRange(params.price, 0, 1000000, 'price');
    
    // Validate name length
    ValidationHelper.validateLength(params.name, 3, 100, 'name');
    
    // Validate status enum
    if (params.status) {
        ValidationHelper.validateEnum(params.status, ['active', 'inactive'], 'status');
    }
    
    // ... rest of code
}

// ============================================
// CONTOH 3: Not Found Error
// ============================================
async function getUserExample(id) {
    const dbSAPPS = require('../apps/sapps/helpers/db');
    const user = await dbSAPPS.User.findByPk(id);
    
    if (!user) {
        throw createNotFoundError('User', id);
        // Error response akan seperti:
        // {
        //   "success": false,
        //   "message": "User with ID 123 not found",
        //   "error": {
        //     "type": "NOT_FOUND_ERROR",
        //     ...
        //   }
        // }
    }
    
    return user;
}

// ============================================
// CONTOH 4: Unique Constraint Error (Conflict)
// ============================================
async function createCompanyExample(params) {
    const dbSAPPS = require('../apps/sapps/helpers/db');
    
    // Check if company code already exists
    const existing = await dbSAPPS.Company.findOne({
        where: { code: params.code }
    });
    
    if (existing) {
        throw createConflictError(
            `Company with code "${params.code}" already exists`,
            { field: 'code', value: params.code, existingId: existing.id }
        );
    }
    
    // ... rest of code
}

// ============================================
// CONTOH 5: Handle Sequelize Errors
// ============================================
async function createItemWithSequelizeExample(params) {
    const dbSAPPS = require('../apps/sapps/helpers/db');
    
    try {
        const item = await dbSAPPS.Item.create(params);
        return { success: true, data: item };
    } catch (error) {
        // Sequelize ValidationError akan otomatis terformat oleh error handler
        // Tidak perlu wrap atau modify error, cukup throw langsung
        throw error;
        
        // Error handler akan otomatis:
        // 1. Detect bahwa ini SequelizeValidationError
        // 2. Extract field-specific errors
        // 3. Format dengan detail lengkap
        // 4. Include stack trace di development mode
    }
}

// ============================================
// CONTOH 6: Multiple Validations dengan Helper
// ============================================
async function createUserAdvancedExample(params) {
    // Validate multiple fields sekaligus
    ValidationHelper.validateFields(params, {
        email: { 
            required: true, 
            email: true 
        },
        password: { 
            required: true, 
            length: [8, 50] 
        },
        age: { 
            required: false, 
            range: [18, 100] 
        },
        role: { 
            required: true, 
            enum: ['admin', 'user', 'guest'] 
        },
        username: {
            required: true,
            validator: (value, allData) => {
                if (!/^[a-zA-Z0-9_]+$/.test(value)) {
                    return 'Username can only contain letters, numbers, and underscores';
                }
                // Check uniqueness (async example)
                // Note: For async validation, do it separately
                return true;
            }
        }
    });
    
    // Additional async validations
    const dbSAPPS = require('../apps/sapps/helpers/db');
    
    // Check email uniqueness
    await ValidationHelper.validateUnique(dbSAPPS.User, 'email', params.email);
    
    // Check username uniqueness
    await ValidationHelper.validateUnique(dbSAPPS.User, 'username', params.username);
    
    // ... rest of code
}

// ============================================
// CONTOH 7: Update dengan Validations
// ============================================
async function updateUserExample(id, params) {
    const dbSAPPS = require('../apps/sapps/helpers/db');
    
    // Validate user exists
    const user = await ValidationHelper.validateExists(
        dbSAPPS.User, 
        id, 
        'User'
    );
    
    // Validate email if provided
    if (params.email !== undefined) {
        ValidationHelper.validateEmail(params.email, 'email');
        
        // Check uniqueness (exclude current user)
        await ValidationHelper.validateUnique(
            dbSAPPS.User, 
            'email', 
            params.email, 
            id
        );
    }
    
    // Validate password if provided
    if (params.password !== undefined) {
        ValidationHelper.validateLength(params.password, 8, 50, 'password');
    }
    
    // Update user
    try {
        await user.update(params);
        return { success: true, data: user };
    } catch (error) {
        // Sequelize errors akan otomatis terformat
        throw error;
    }
}

// ============================================
// CONTOH 8: Error di Controller
// ============================================
async function createItemControllerExample(req, res, next) {
    try {
        const result = await createItemExample(req.body);
        return res.status(200).json(result);
    } catch (error) {
        // Pass error ke error handler middleware
        // Error handler akan otomatis format dan kirim response
        next(error);
    }
}

// ============================================
// CONTOH 9: Custom Validation dengan Context
// ============================================
async function createOrderExample(params) {
    const dbSAPPS = require('../apps/sapps/helpers/db');
    const errors = {};
    
    // Validate customer exists
    const customer = await dbSAPPS.Customer.findByPk(params.customer_id);
    if (!customer) {
        errors.customer_id = 'Customer not found';
    }
    
    // Validate items
    if (!params.items || params.items.length === 0) {
        errors.items = 'At least one item is required';
    } else {
        // Validate each item
        for (let i = 0; i < params.items.length; i++) {
            const item = params.items[i];
            if (!item.item_id) {
                errors[`items[${i}].item_id`] = 'Item ID is required';
            } else {
                const itemRecord = await dbSAPPS.Item.findByPk(item.item_id);
                if (!itemRecord) {
                    errors[`items[${i}].item_id`] = `Item with ID ${item.item_id} not found`;
                }
            }
            if (!item.quantity || item.quantity <= 0) {
                errors[`items[${i}].quantity`] = 'Quantity must be greater than 0';
            }
        }
    }
    
    // Validate total amount
    if (params.total_amount !== undefined) {
        if (params.total_amount < 0) {
            errors.total_amount = 'Total amount cannot be negative';
        }
    }
    
    if (Object.keys(errors).length > 0) {
        throw createValidationError(errors, 'Order validation failed');
    }
    
    // ... rest of code
}

module.exports = {
    createUserExample,
    createItemExample,
    getUserExample,
    createCompanyExample,
    createItemWithSequelizeExample,
    createUserAdvancedExample,
    updateUserExample,
    createItemControllerExample,
    createOrderExample,
};
