@php
    $id          = $attributes->get('id', 'cropper_' . Str::random(6));
    $width       = (int) $attributes->get('width', 300);
    $height      = (int) $attributes->get('height', 300);
    $shape       = $attributes->get('shape', 'circle');    // 'circle' or 'square'
    $folder      = $attributes->get('folder', 'uploads');
    $filename    = $attributes->get('filename', 'image_' . time());
    $callback    = $attributes->get('callback', '');       // JS function called with (url) after server upload
    $updateUrl   = $attributes->get('update-url', '');     // POST {path} here after server upload
    $title       = $attributes->get('title', $shape === 'circle' ? 'Change Photo' : 'Crop Image');
    $outputWidth = (int) $attributes->get('output-width', 0); // final output px width (0 = viewport size)
    $targetInput = $attributes->get('target-input', '');   // form mode: ID of file input to set result on
    $previewImg  = $attributes->get('preview-img', '');    // ID of img to update with preview
    $resultCallback = $attributes->get('result-callback', ''); // callback mode: JS fn called with the cropped File
@endphp

{{-- Cropme assets + .tc-* styles now live in layouts/app.blade.php <head>
     so they survive SPA-nav innerHTML swaps on #main. --}}

{{-- Modal --}}
<div class="tc-overlay" id="tcOverlay_{{ $id }}" role="dialog" aria-modal="true">
    <div class="tc-modal">
        <div class="tc-modal-header">
            <span class="tc-modal-title">
                <i class="bi bi-crop"></i>
                {{ $title }}
            </span>
            <button class="tc-modal-close" onclick="closeCropperModal('{{ $id }}')" aria-label="Close">
                <i class="bi bi-x-lg"></i>
            </button>
        </div>
        <div class="tc-modal-body">
            <div class="tc-file-row">
                <label class="tc-file-label" for="tcInput_{{ $id }}">
                    <i class="bi bi-upload"></i>
                    Choose image
                </label>
                <span class="tc-file-name" id="tcFileName_{{ $id }}">No file chosen</span>
                <input type="file" id="tcInput_{{ $id }}" accept="image/*" style="display:none" aria-label="Select image file">
            </div>

            <div class="tc-canvas" id="tcCanvas_{{ $id }}">
                <div class="tc-placeholder" id="tcPlaceholder_{{ $id }}">
                    <i class="bi bi-image"></i>
                    <span>Upload an image to start cropping</span>
                </div>
            </div>

            <div class="tc-controls">
                <div class="tc-control">
                    <label class="tc-control-label" for="tcZoom_{{ $id }}">
                        <i class="bi bi-zoom-in"></i> Zoom
                    </label>
                    <input type="range" class="tc-range" id="tcZoom_{{ $id }}" min="0" max="100" step="1" value="0">
                </div>
                <div class="tc-control">
                    <label class="tc-control-label" for="tcRot_{{ $id }}">
                        <i class="bi bi-arrow-clockwise"></i> Rotate
                    </label>
                    <input type="range" class="tc-range" id="tcRot_{{ $id }}" min="-180" max="180" step="1" value="0">
                </div>
            </div>
        </div>
        <div class="tc-modal-footer">
            <button class="tc-btn tc-btn-as-is" id="tcAsIsBtn_{{ $id }}" disabled
                onclick="tcUploadAsIs_{{ $id }}()">
                <i class="bi bi-image"></i>
                Upload as-is
            </button>
            <button class="tc-btn tc-btn-ghost" onclick="closeCropperModal('{{ $id }}')">
                Cancel
            </button>
            <button class="tc-btn tc-btn-primary" id="tcSaveBtn_{{ $id }}" disabled
                onclick="tcSave_{{ $id }}()">
                <i class="bi bi-check-lg"></i>
                <span id="tcSaveBtnText_{{ $id }}">Crop & Save</span>
            </button>
        </div>
    </div>
</div>

<script>
(function () {
    var cropperInst  = null;
    var originalFile = null;
    var _intercept   = false;         // flag: we are programmatically setting the file, skip interceptor
    var zoomMin = 0.01, zoomMax = 3;

    var id           = '{{ $id }}';
    var vw           = {{ $width }};
    var vh           = {{ $height }};
    var shape        = '{{ $shape }}';
    var folder       = '{{ $folder }}';
    var filename     = '{{ $filename }}';
    var uploadUrl    = '{{ route('image.upload') }}';
    var updateUrl    = '{{ $updateUrl }}';
    var callbackFn   = '{{ $callback }}';
    var outputWidth  = {{ $outputWidth > 0 ? $outputWidth : 0 }};
    var targetInputId = '{{ $targetInput }}';   // form mode: ID of the file input to intercept
    var previewImgId  = '{{ $previewImg }}';
    var resultCbName  = '{{ $resultCallback }}'; // callback mode: name of a global fn given the cropped File

    var isFormMode     = targetInputId !== '';
    var isCallbackMode = resultCbName !== '';

    // In callback mode the host function decides when to close / advance, so we
    // never auto-close here — we just hand the File back and reset the button.
    function deliverResult(file) {
        if (typeof window[resultCbName] === 'function') window[resultCbName](file);
        var sb = document.getElementById('tcSaveBtn_' + id);
        var st = document.getElementById('tcSaveBtnText_' + id);
        var ab = document.getElementById('tcAsIsBtn_' + id);
        if (sb) sb.disabled = false;
        if (ab) ab.disabled = false;
        if (st) st.textContent = 'Crop & Save';
    }

    function getCsrf() {
        var m = document.querySelector('meta[name="csrf-token"]');
        return m ? m.content : '';
    }

    /* ── Open / close ── */
    function openModal() {
        document.getElementById('tcOverlay_' + id).classList.add('open');
        document.body.style.overflow = 'hidden';
    }
    window['openCropperModal_' + id] = openModal;

    window.closeCropperModal = window.closeCropperModal || function (i) {
        var el = document.getElementById('tcOverlay_' + i);
        if (el) { el.classList.remove('open'); document.body.style.overflow = ''; }
    };
    document.getElementById('tcOverlay_' + id).addEventListener('click', function (e) {
        if (e.target === this) window.closeCropperModal(id);
    });

    /* ── Preload a File into the cropper ── */
    function preloadFile(file) {
        if (!file) return;
        originalFile = file;
        document.getElementById('tcFileName_' + id).textContent = file.name;
        var reader = new FileReader();
        reader.onload = function (e) { initCropper(e.target.result); };
        reader.readAsDataURL(file);
    }
    window['tcPreload_' + id] = preloadFile;

    function initCropper(dataUrl) {
        document.getElementById('tcPlaceholder_' + id).style.display = 'none';
        document.getElementById('tcSaveBtn_' + id).disabled = false;
        document.getElementById('tcAsIsBtn_' + id).disabled = false;

        var canvas = document.getElementById('tcCanvas_' + id);
        if (cropperInst) { cropperInst.destroy(); cropperInst = null; }

        cropperInst = new Cropme(canvas, {
            container: { width: '100%', height: 320 },
            viewport: {
                width: vw, height: vh,
                type: shape,
                border: { enable: true, width: 2, color: '#ef4444' }
            },
            transformOrigin: 'viewport',
            zoom: { min: zoomMin, max: zoomMax, enable: true, mouseWheel: true, slider: false },
            rotation: { enable: true, slider: false }
        });
        cropperInst.bind({ url: dataUrl }).then(function () {
            document.getElementById('tcZoom_' + id).value = 0;
            document.getElementById('tcRot_' + id).value = 0;
        });
    }

    /* ── Internal file input (the "Choose image" button inside the modal) ── */
    document.getElementById('tcInput_' + id).addEventListener('change', function () {
        if (this.files && this.files[0]) preloadFile(this.files[0]);
    });

    /* ── Form-mode: expose open helper for external callers ── */
    // Callers should invoke window['openCropperModal_' + id]() directly from their
    // dropzone click/drop handlers rather than relying on event interception.

    /* ── Zoom / rotate sliders ── */
    document.getElementById('tcZoom_' + id).addEventListener('input', function () {
        if (!cropperInst || !cropperInst.properties.image) return;
        var p = parseFloat(this.value) / 100;
        cropperInst.properties.scale = zoomMin + (zoomMax - zoomMin) * p;
        var s = cropperInst.properties;
        s.image.style.transform = 'translate3d(' + s.x + 'px,' + s.y + 'px,0) scale(' + s.scale + ') rotate(' + s.deg + 'deg)';
    });
    document.getElementById('tcRot_' + id).addEventListener('input', function () {
        if (cropperInst) cropperInst.rotate(parseInt(this.value, 10));
    });

    /* ── Helpers ── */
    function base64ToFile(base64, name) {
        var arr  = base64.split(',');
        var mime = (arr[0].match(/:(.*?);/) || [])[1] || 'image/png';
        var bin  = atob(arr[1]);
        var u8   = new Uint8Array(bin.length);
        for (var i = 0; i < bin.length; i++) u8[i] = bin.charCodeAt(i);
        return new File([u8], name || 'cropped.png', { type: mime });
    }

    function setOnTargetInput(file) {
        var el = document.getElementById(targetInputId);
        if (!el) return;
        try {
            var dt = new DataTransfer();
            dt.items.add(file);
            _intercept = true;
            el.files = dt.files;
            el.dispatchEvent(new Event('change', { bubbles: true }));
        } finally {
            _intercept = false;
        }
        if (previewImgId) {
            var prev = document.getElementById(previewImgId);
            if (prev) prev.src = URL.createObjectURL(file);
        }
    }

    function uploadToServer(base64, onDone, onFail) {
        fetch(uploadUrl, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': getCsrf() },
            body: JSON.stringify({ image: base64, folder: folder, filename: filename })
        })
        .then(function (r) { return r.json(); })
        .then(function (res) {
            if (!res.success) throw new Error(res.message || 'Upload failed');
            if (updateUrl) {
                return fetch(updateUrl, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': getCsrf() },
                    body: JSON.stringify({ path: res.path })
                }).then(function () { return res; });
            }
            return res;
        })
        .then(onDone)
        .catch(onFail);
    }

    /* ── Crop & Save ── */
    window['tcSave_' + id] = function () {
        if (!cropperInst) return;
        var btn = document.getElementById('tcSaveBtn_' + id);
        var txt = document.getElementById('tcSaveBtnText_' + id);
        btn.disabled = true;
        txt.textContent = 'Saving…';

        var cropOpts = outputWidth > 0 ? { type: 'base64', width: outputWidth } : { type: 'base64' };

        cropperInst.crop(cropOpts).then(function (base64) {
            if (isCallbackMode) {
                var cbName = originalFile ? originalFile.name : 'cropped.png';
                deliverResult(base64ToFile(base64, cbName));
                return;
            }
            if (isFormMode) {
                var fname = originalFile ? originalFile.name : 'cropped.png';
                setOnTargetInput(base64ToFile(base64, fname));
                window.closeCropperModal(id);
                if (typeof window.showToast === 'function') window.showToast('Image ready!', 'success');
                btn.disabled = false;
                txt.textContent = 'Crop & Save';
            } else {
                uploadToServer(base64, function (res) {
                    window.closeCropperModal(id);
                    if (typeof window.showToast === 'function') window.showToast('Saved!', 'success');
                    if (callbackFn && typeof window[callbackFn] === 'function') window[callbackFn](res.url);
                    btn.disabled = false;
                    txt.textContent = 'Crop & Save';
                }, function (err) {
                    if (typeof window.showToast === 'function') window.showToast(err.message || 'Upload failed', 'error');
                    btn.disabled = false;
                    txt.textContent = 'Crop & Save';
                });
            }
        });
    };

    /* ── Upload as-is ── */
    window['tcUploadAsIs_' + id] = function () {
        if (!originalFile) { window.closeCropperModal(id); return; }

        if (isCallbackMode) {
            deliverResult(originalFile);
        } else if (isFormMode) {
            // Put the original (un-cropped) file on the target input so the form sees it.
            setOnTargetInput(originalFile);
            window.closeCropperModal(id);
        } else {
            // Server mode: read original file as base64 and upload unchanged
            var btn = document.getElementById('tcSaveBtn_' + id);
            var txt = document.getElementById('tcSaveBtnText_' + id);
            var aisBtn = document.getElementById('tcAsIsBtn_' + id);
            btn.disabled = true;
            aisBtn.disabled = true;
            txt.textContent = 'Uploading…';

            var reader = new FileReader();
            reader.onload = function (e) {
                uploadToServer(e.target.result, function (res) {
                    window.closeCropperModal(id);
                    if (typeof window.showToast === 'function') window.showToast('Saved!', 'success');
                    if (callbackFn && typeof window[callbackFn] === 'function') window[callbackFn](res.url);
                    btn.disabled = false;
                    aisBtn.disabled = false;
                    txt.textContent = 'Crop & Save';
                }, function (err) {
                    if (typeof window.showToast === 'function') window.showToast(err.message || 'Upload failed', 'error');
                    btn.disabled = false;
                    aisBtn.disabled = false;
                    txt.textContent = 'Crop & Save';
                });
            };
            reader.readAsDataURL(originalFile);
        }
    };
})();
</script>
