<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>
`
