/**
 * Face Detection Helper Functions
 * Provides utilities for face detection and alignment validation
 */

// Global variable to track if face-api.js is loaded
let faceApiLoaded = false;

/**
 * Load face-api.js library dynamically
 */
async function loadFaceApi() {
    return new Promise((resolve, reject) => {
        if (window.faceapi) {
            resolve();
            return;
        }

        // Create script element
        const script = document.createElement('script');
        script.src = 'https://cdn.jsdelivr.net/npm/face-api.js@0.22.2/dist/face-api.min.js';
        
        script.onload = () => {
            faceApiLoaded = true;
            console.log('Face-API.js loaded successfully');
            resolve();
        };
        
        script.onerror = () => {
            console.error('Failed to load Face-API.js');
            reject(new Error('Failed to load face-api.js'));
        };
        
        document.head.appendChild(script);
    });
}

/**
 * Initialize face detection models
 */
async function initializeFaceModels() {
    if (!window.faceapi) {
        console.warn('Face-API.js not loaded, proceeding without face detection');
        return false; // Return false to indicate models not loaded
    }

    // Try multiple sources for the model
    const modelPaths = [
        './assets/models', // Local path
        'https://justadudewhohacks.github.io/face-api.js/weights/tiny_face_detector', // GitHub pages
        'https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights/tiny_face_detector' // Raw GitHub
    ];
    
    for (const path of modelPaths) {
        try {
            console.log(`Attempting to load face models from: ${path}`);
            await faceapi.nets.tinyFaceDetector.loadFromUri(path);
            console.log(`Face models successfully loaded from: ${path}`);
            return true; // Success, return true to indicate models loaded
        } catch (error) {
            console.warn(`Failed to load models from: ${path}`, error.message);
            continue; // Try the next path
        }
    }
    
    // If all paths fail, log a message but don't throw an error
    console.warn('Face detection will be unavailable - all model sources failed');
    return false; // Return false to indicate models not loaded
}

/**
 * Detect faces and validate proper alignment
 * @param {HTMLVideoElement} videoElement - Video element to analyze
 * @returns {Object} Result with detection status and feedback
 */
async function validateFaceAlignment(videoElement) {
    // Check if face-api is available and models are loaded
    if (!window.faceapi || !faceapi.nets.tinyFaceDetector.__paramMappings) {
        console.warn('Face detection models not loaded, proceeding with visual guidance only');
        // Provide basic validation based on visual estimation
        return {
            isValid: true,
            feedback: 'মুখমণ্ডল কেন্দ্রে রেখে ডান-বাম ঠিক করে নিন। আলো ভালো রেখে ক্যামেরার সামনে সরাসরি মুখ রাখুন।',
            detectionCount: 0,
            alignment: {
                isCentered: true,
                isProperSize: true,
                isWithinMargins: true
            }
        };
    }

    try {
        // Detect faces with more tolerant options
        const detections = await faceapi.detectAllFaces(
            videoElement,
            new faceapi.TinyFaceDetectorOptions({
                inputSize: 512,       // Larger input size for better detection
                scoreThreshold: 0.3  // Lower threshold for more lenient detection
            })
        );

        if (detections.length === 0) {
            return {
                isValid: false,
                feedback: 'মুখমণ্ডল সনাক্ত করা যায়নি',
                detectionCount: 0
            };
        }

        // Get the largest face (assumed to be the primary subject)
        const largestFace = detections.reduce((prev, curr) => 
            (curr.detection.box.area > prev.detection.box.area) ? curr : prev
        );

        // Calculate dimensions
        const displaySize = { 
            width: videoElement.videoWidth, 
            height: videoElement.videoHeight 
        };
        
        const scaledDetection = faceapi.resizeResults(largestFace, displaySize);
        const faceBox = scaledDetection.detection.box;
        
        // Calculate face center
        const faceCenterX = faceBox.x + (faceBox.width / 2);
        const centerX = displaySize.width / 2;
        const positionDiff = Math.abs(faceCenterX - centerX);

        // Check if face is centered (within 30% of screen width - more lenient)
        const isCentered = positionDiff < (displaySize.width * 0.3);
        
        // Check if face is large enough (indicating proper proximity) - reduced threshold
        const minFaceSize = displaySize.width * 0.2; // At least 20% of screen width
        const isProperSize = faceBox.width > minFaceSize;
        
        // Check if face is not too close to edges (left/right margins) - reduced margin
        const minMargin = displaySize.width * 0.05; // 5% margin on each side
        const isWithinMargins = faceBox.x > minMargin && (faceBox.x + faceBox.width) < (displaySize.width - minMargin);

        // Overall validity
        const isValid = isCentered && isProperSize && isWithinMargins;

        // Prepare feedback message
        let feedback = '';
        if (!isValid) {
            if (!isCentered) {
                feedback += 'মুখমণ্ডল কেন্দ্রে নেন। ';
            }
            if (!isProperSize) {
                feedback += 'আরও কাছাকাছি আসুন। ';
            }
            if (!isWithinMargins) {
                feedback += 'ডান-বাম সঠিক করে নিন। ';
            }
        } else {
            // Add a small delay indication to let user know capture is imminent
            feedback = 'মুখমণ্ডল সঠিকভাবে সেট করা হয়েছে! ২ সেকেন্ডের মধ্যে ক্যাপচার হবে...';
        }

        return {
            isValid,
            feedback,
            detectionCount: detections.length,
            faceData: scaledDetection,
            alignment: {
                isCentered,
                isProperSize,
                isWithinMargins
            }
        };
    } catch (error) {
        console.error('Error during face detection:', error);
        // If face detection fails, proceed with capture but warn user
        return {
            isValid: true,
            feedback: 'মুখমণ্ডল সনাক্তকরণ ত্রুটি, ক্যাপচার চালিয়ে যাচ্ছে',
            detectionCount: 0,
            alignment: {
                isCentered: true,
                isProperSize: true,
                isWithinMargins: true
            }
        };
    }
}

/**
 * Capture image with face validation
 * @param {HTMLVideoElement} videoElement - Video element to capture from
 * @param {HTMLCanvasElement} canvasElement - Canvas to draw on
 * @returns {Promise<string>} Base64 encoded image data
 */
async function captureWithFaceValidation(videoElement, canvasElement) {
    // Validate face alignment first
    const validationResult = await validateFaceAlignment(videoElement);
    
    if (!validationResult.isValid && validationResult.detectionCount > 0) {
        // Only throw error if face detection was available but validation failed
        throw new Error(validationResult.feedback);
    }

    // Set canvas dimensions to match video
    canvasElement.width = videoElement.videoWidth;
    canvasElement.height = videoElement.videoHeight;
    
    // Draw video frame to canvas
    const context = canvasElement.getContext('2d');
    context.drawImage(videoElement, 0, 0, canvasElement.width, canvasElement.height);
    
    // Return base64 encoded image
    return canvasElement.toDataURL('image/jpeg', 0.8); // 80% quality to reduce size
}

// Export functions if using modules
if (typeof module !== 'undefined' && module.exports) {
    module.exports = {
        loadFaceApi,
        initializeFaceModels,
        validateFaceAlignment,
        captureWithFaceValidation
    };
}