(function (paw) {
    function CameraCaptureComponent($trigger, onFinished) {
        var self = this;
        this.$trigger = $trigger;
        this.onFinished = onFinished;
        this.$container = null;
        this.$previewContainer = null;
        this.$preloader = null;
        this.cc = null;

        this.handlers = {
            onTrigger: function () {
                self.compileContainer();
                self.cc = new paw.mod.camera.CameraCapture(self.$previewContainer, function () {
                    this.preview();
                });
                self.cc.capture();
            },
            onClose: function () {
                self.destroy();
            },
            onFinish: function () {
                self.cc.finalize().then(function (imageBlob) {
                    self.onFinished(imageBlob);
                });
            },
            onCapture: function () {
                self.cc.capture();
    }
        };
    }

    CameraCaptureComponent.detectDevice = function () {
        var userAgent = navigator.userAgent;
        if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent)) {
            return 'mobile';
        }
        return 'desktop';
    };

    CameraCaptureComponent.create = function($trigger, onFinished){
        var cc = new CameraCaptureComponent($trigger, onFinished);
        cc.init();
        return cc;
    };

    CameraCaptureComponent.createThumbnailPreview = function (blob) {
        var reader = new FileReader();
        var d = paw.utils.async.defer();
        reader.onload = function (event) {
            var img = new Image();
            img.onload = function () {
                $(img).addClass('cc-thumbnail');
                d.resolve(img);
            }
            img.src = reader.result;
            
        };

        // Read the Blob as a data URL
        reader.readAsDataURL(blob);
        return d.promise;
    };

    CameraCaptureComponent.uploadAsForm = function (form, fieldName, captured, cc, invoiceItems = null) {
        return CameraCaptureComponent.createThumbnailPreview(captured.blob).then(function ($thumbnail) {
            cc.showPreloader($thumbnail);

            CameraCaptureComponent.setFormData(form, fieldName, captured, cc, invoiceItems);

            var d = paw.utils.async.defer();
            var request = new XMLHttpRequest();
            request.open('POST', form.action);
            request.onreadystatechange = function () {
                if (request.readyState === 4) {
                    if (request.status === 200) {
                        // Request completed successfully
                        d.resolve();
                    } else {
                        // Request failed
                        console.error('Request failed with status:', request.status);
                        d.reject();
                    }
                }
            };
            request.send(
                CameraCaptureComponent.setFormData(form, fieldName, captured, cc, invoiceItems)
            );
            return d.promise;
        });
    };

    CameraCaptureComponent.setFormData = function (form, fieldName, captured, cc, invoiceItems) {
        var formData = new FormData(form);
        formData.set(fieldName, captured.blob, captured.filename);
        if (invoiceItems)
            formData.append('InvoiceItemsJsonString', JSON.stringify(invoiceItems));

        return formData;
    };

    CameraCaptureComponent.resizeImage = function(imgElement, targetWidth, targetHeight) {
        const aspectRatio = imgElement.width / imgElement.height;
    
        // If both targetWidth and targetHeight are specified, use the smaller ratio
        if (targetWidth && targetHeight) {
            if (targetWidth / aspectRatio > targetHeight) {
                imgElement.width = targetHeight * aspectRatio;
                imgElement.height = targetHeight;
            } else {
                imgElement.width = targetWidth;
                imgElement.height = targetWidth / aspectRatio;
            }
        } 
        // If only targetWidth is specified
        else if (targetWidth) {
            imgElement.width = targetWidth;
            imgElement.height = targetWidth / aspectRatio;
        } 
        // If only targetHeight is specified
        else if (targetHeight) {
            imgElement.height = targetHeight;
            imgElement.width = targetHeight * aspectRatio;
        }
    };
    
    CameraCaptureComponent.prototype.init = function(){
        this.$trigger.on('click', this.handlers.onTrigger);
    };

    CameraCaptureComponent.prototype.destroy = function () {
        this.$container.find('button.ccc-close').off('click', this.handlers.onClose);
        this.$container.find('button.ccc-finish').off('click', this.handlers.onFinish);
        this.$previewContainer.find('button.ccc-btn-camera-capture').off('click', this.handlers.onCapture);
        this.$container.remove();
    };

    CameraCaptureComponent.prototype.compileContainer = function(){
        var self = this;
        var markup = [
            '<div class="camera-capture-view">',
            '   <div class="cc-area-v cc-height-fit">',
            '      <div class="cc-header cc-col cc-area-h">',
            '         <div class="cc-col-d">',
            '            <button class="cc-btn-header ccc-close btn-transparent" type="button"><i class="fal fa-chevron-left fa-2x"></i></button>',
            '         </div>',
            '         <div class="cc-col">',
            '            <button class="cc-btn-header ccc-finish btn-transparent text-primary" type="button"><span class="fal fa-upload fa-2x"></span></button>',
            '         </div>',
            '      </div>',
            '      <div class="cc-body cc-col-d">',
            '         <div class="ccc-preview-holder">',
            '            <div class="ccc-preview-stage">',
            '               <button class="ccc-btn-camera-capture btn-transparent text-primary"><i class="fal fa-camera fa-4x"></i></button>',
            '            </div>',
            '         </div>',
            '      </div>',
            '   </div>',
            '   <div style="flex-grow: 2; overflow: auto; padding: 16px;">',
            '      <div class="ccc-preview-holder"></div>',
            '   </div>',
            '</div>'
        ]
        this.$container = $(markup.join('\n'));
        this.$previewContainer = this.$container.find('.ccc-preview-stage');        

        this.$container.find('button.ccc-close').on('click', this.handlers.onClose);
        this.$container.find('button.ccc-finish').on('click', this.handlers.onFinish);
        this.$previewContainer.find('button.ccc-btn-camera-capture').on('click', this.handlers.onCapture);

        $('body').append(this.$container);
    };

    CameraCaptureComponent.prototype.showPreloader = function (thumbnailImg) {
        var markup = [
            '<div class="cc-preloader">',
            '   <div class="cc-preloader-spinner fa fa-spinner fa-spin fa-4x">',
            '   </div>',
            '</div>'
        ]
        this.$preloader = $(markup.join('\n'));
        this.$container.append(this.$preloader);

        if (paw.utils.value.isSet(thumbnailImg)) {
            var $tp = $('<div class="cc-thumbnail-holder"><div class="cc-thumbnail-item"></div></div>');
            this.$preloader.prepend($tp);
            var dims = paw.mod.camera.CameraCapture.calcScaledDimensions(thumbnailImg.width, thumbnailImg.height, $tp.innerWidth(), $tp.innerHeight());
            thumbnailImg.width = dims.width;
            thumbnailImg.height = dims.height;
            var $tpi = $tp.find('.cc-thumbnail-item');
            $tpi.append(thumbnailImg);
            $tpi.css('margin-left', (-$tpi.outerWidth() * 0.5) + 'px')
            
        }
        
    };

    paw.com.CameraCaptureComponent = CameraCaptureComponent;
})(paw);
