<template>
    <div class="position-relative">
        <div class="position-absolute top-0" style="right: 0;" v-if="croppedImage">
            <button type="button" class="btn p-0 bg-body-tertiary rounded-circle m-2" style="width: 40px; height: 40px;"
                @click="deleteImage">
                <i class="fa-regular fa-trash-can text-danger"></i>
            </button>
        </div>

        <button type="button" class="upload-image" @click="showCustomModal">
            <div v-if="!croppedImage">
                <div class="text-center">
                    <i class="fa-solid fa-image text-secondary mb-2 text-opacity-25 fa-2x"></i>
                    <p class="text-secondary">Browse File</p>
                </div>
            </div>
            <img v-else :src="croppedImage" alt="Cropped Image" class="img-fluid" style="max-height: 200px;" />
        </button>

        <div class="custom-modal" :id="`modal-${modalId}`">
            <div class="custom-modal-backdrop"></div>
            <div class="custom-modal-content rounded-4">
                <div class="custom-modal-header">
                    <h5 class="modal-title">Crop Images</h5>
                    <button type="button" class="btn-close rounded-circle bg-light p-3" @click="hideCustomModal"
                        aria-label="Close"></button>
                </div>
                <div class="custom-modal-body p-4" style="min-height: 350px;">
                    <div class="row" v-if="imagePreview">
                        <div class="col-md-8">
                            <div class="cropper-container">
                                <img ref="cropperImage" :src="imagePreview" class="img-fluid" />
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="text-center">
                                <p class="fw-bold my-2">Preview</p>
                                <div class="preview-image border p-1 mx-auto mb-2">
                                    <img :src="previewImage" alt="Image" class="img-fluid" style="object-fit: cover;" />
                                </div>
                                <div v-if="originalImageSize || resultSize">
                                    <p class="text-muted mb-3"><small>{{ originalImageSize }} || {{ resultSize
                                            }}</small></p>
                                </div>
                            </div>
                            <div class="text-center">
                                <button class="btn p-0 bg-body-tertiary rounded-circle"
                                    style="width: 40px; height: 40px;" type="button" @click="resetCrop"
                                    :disabled="!imagePreview">
                                    <i class="fa-solid fa-rotate text-muted"></i>
                                </button>
                            </div>
                        </div>
                    </div>

                    <div v-else>
                        <button type="button" class="w-100 bg-body rounded-3 border-0" @click="triggerFileInput"
                            @dragover.prevent @drop="onDrop">
                            <div class="upload-image">
                                <div v-if="!isLoadingImage" class="text-center">
                                    <i class="fa-solid fa-image text-secondary mb-2 text-opacity-25 fa-2x"></i>
                                    <p class="text-secondary"><span class="text-primary">Upload a file</span> or drag
                                        and drop</p>
                                </div>
                                <div v-else class="text-center">
                                    <p class="text-muted">Processing image...</p>
                                </div>
                            </div>
                        </button>
                        <input type="file" ref="fileInput" class="d-none" @change="onFileChange" accept="image/*" />
                    </div>
                </div>
                <div class="custom-modal-footer pt-0 border-0">
                    <div class="d-flex" v-if="imagePreview">
                        <button @click="backImage" class="btn btn-secondary" type="button">{{ $t('Back') }}</button>
                        <button class="btn btn-success ms-2" type="button" @click="cropImage" :disabled="isLoading">
                            <div v-if="isLoading" class="align-middle">Loading...</div>
                            <span v-else>{{ $t('Save') }}</span>
                        </button>
                    </div>
                    <button v-else class="btn btn-secondary" type="button" @click="hideCustomModal">{{ $t('Cancel')
                        }}</button>
                </div>
            </div>
        </div>
    </div>
</template>
<script>
import Cropper from "cropperjs";
import "cropperjs/dist/cropper.css";

export default {
    props: {
        croppedImage: {
            type: String,
            default: null,
        },
        modalId: {
            type: String,
            required: true,
        },
        aspectRatio: {
            type: Number,
            default: null,
        },
    },
    data() {
        return {
            imagePreview: null,
            previewImage: null,
            originalImageSize: null,
            resultSize: null,
            isLoading: false,
            cropper: null,
            isLoadingImage: false,
        };
    },
    methods: {
        showCustomModal() {
            document.body.style.overflow = 'hidden';
            const modal = document.getElementById(`modal-${this.modalId}`);
            if (modal) modal.classList.add('show');
        },
        hideCustomModal() {
            const modal = document.getElementById(`modal-${this.modalId}`);
            if (modal) modal.classList.remove('show');
            document.body.style.overflow = '';
        },
        triggerFileInput() {
            this.$refs.fileInput.click();
        },
        onFileChange(event) {
            const file = event.target.files ? event.target.files[0] : event.dataTransfer.files[0];
            this.processFile(file);
        },
        onDragOver(event) {
            event.preventDefault();
        },
        onDrop(event) {
            event.preventDefault();
            const file = event.dataTransfer.files[0];
            this.processFile(file);
        },
        processFile(file) {
            if (!file) return;

            this.isLoadingImage = true;
            const reader = new FileReader();

            reader.onload = (e) => {
                const img = new Image();
                img.onload = () => {
                    this.imagePreview = img.src;
                    this.originalImageSize = this.formatFileSize(file.size);
                    this.$nextTick(() => this.initializeCropper());
                    this.isLoadingImage = false;
                };
                img.onerror = () => {
                    console.error("Failed to load image");
                    this.isLoadingImage = false;
                };
                img.src = e.target.result;
            };

            reader.onerror = () => {
                console.error("Failed to read file");
                this.isLoadingImage = false;
            };

            reader.readAsDataURL(file);
        },
        initializeCropper() {
            if (this.cropper) {
                this.cropper.destroy();
            }

            this.$nextTick(() => {
                this.cropper = new Cropper(this.$refs.cropperImage, {
                    aspectRatio: this.aspectRatio,
                    viewMode: 1,
                    dragMode: "move",
                    autoCropArea: 1,
                    cropBoxResizable: true,
                    crop: (event) => {
                        this.updatePreview();
                        this.updateResultSize();
                    },
                    ready: () => this.updatePreview(),
                });
            });
        },
        updatePreview() {
            if (this.cropper) {
                const canvas = this.cropper.getCroppedCanvas();
                this.previewImage = canvas.toDataURL("image/jpg");
            }
        },
        updateResultSize() {
            if (!this.cropper) return;
            const canvas = this.cropper.getCroppedCanvas();
            this.addWhiteBackground(canvas).toBlob(blob => {
                this.resultSize = blob ? this.formatFileSize(blob.size) : null;
            }, 'image/jpeg', 0.9);
        },
        resetCrop() {
            if (this.cropper) {
                this.cropper.reset();
                this.updatePreview();
                this.resultSize = null;
            }
        },
        async cropImage() {
            if (!this.cropper) return;
            this.isLoading = true;

            const canvas = this.cropper.getCroppedCanvas();
            this.addWhiteBackground(canvas).toBlob(blob => {
                if (blob) {
                    this.resultSize = this.formatFileSize(blob.size);
                    const reader = new FileReader();
                    reader.onloadend = () => {
                        const base64data = reader.result;
                        this.$emit("croped", base64data);
                    };
                    reader.readAsDataURL(blob);
                }
                this.isLoading = false;
            }, 'image/jpeg', 0.9);

            this.hideCustomModal();
        },

        addWhiteBackground(canvas) {
            const whiteBg = document.createElement('canvas');
            whiteBg.width = canvas.width;
            whiteBg.height = canvas.height;
            const ctx = whiteBg.getContext('2d');
            ctx.fillStyle = '#ffffff';
            ctx.fillRect(0, 0, whiteBg.width, whiteBg.height);
            ctx.drawImage(canvas, 0, 0);
            return whiteBg;
        },
        formatFileSize(bytes) {
            if (bytes >= 1024 * 1024) {
                return (bytes / (1024 * 1024)).toFixed(2) + " MB";
            } else if (bytes >= 1024) {
                return (bytes / 1024).toFixed(2) + " KB";
            } else {
                return bytes + " bytes";
            }
        },
        deleteImage(event) {
            event.stopPropagation();
            this.resetState();
            this.$emit("croped", null); // Emit null to clear the image
        },
        backImage() {
            this.imagePreview = null;
            this.previewImage = null;
            this.$nextTick(() => {
                this.$refs.fileInput.value = "";
            });
        },
        resetState() {
            this.croppedImage = null;
            this.imagePreview = null;
            this.previewImage = null;
            this.originalImageSize = null;
            this.resultSize = null;

            if (this.cropper) {
                this.cropper.destroy();
                this.cropper = null;
            }

            this.$nextTick(() => {
                this.$refs.fileInput.value = "";
            });
        },
    },
};
</script>

<style>
.cropper-container {
    max-height: 250px;
    overflow: hidden;
}

.preview-image {
    width: min-content;
    max-height: 100px;
}

.preview-image img {
    max-width: 90px;
    max-height: 90px;
}

.upload-image {
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: 10px;
    height: 194px;
    width: 100%;
    overflow: hidden;
    border: 1px dashed var(--bs-border-color);
    background-color: var(--bs-body);
}

.custom-modal {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1050;
    opacity: 0;
    visibility: hidden;
    --bs-modal-bg: var(--bs-body-bg);
    transition: opacity 0.15s ease-out, visibility 0.15s ease-out;
}

.custom-modal-header {
    padding: 1rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-shrink: 0;
}

.custom-modal.show {
    opacity: 1;
    visibility: visible;
}

.custom-modal-backdrop {
    position: fixed;
    width: 100vw;
    height: 100vh;
    background-color: rgba(0, 0, 0, 0.5);
    z-index: 1040;
    opacity: 0;
    transition: opacity 0.15s ease-out;
}

.custom-modal.show .custom-modal-backdrop {
    opacity: 1;
}

.custom-modal-content {
    position: relative;
    z-index: 1050;
    background-color: var(--bs-modal-bg);
    width: 100%;
    max-width: 700px;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
    box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
    transform: scale(0.7);
    opacity: 0;
    transition: transform 0.15s ease-out, opacity 0.15s ease-out;
}

.custom-modal.show .custom-modal-content {
    transform: scale(1);
    opacity: 1;
}

.custom-modal-footer {
    padding: 1rem;
    display: flex;
    justify-content: flex-end;
    flex-shrink: 0;
}
</style>
