{% load crispy_forms_tags %}
{% with image_url_array_and_count=series.get_image_url_array_and_count %}

    <div class="container my-4">
        <div class="row">
            <div class="col-12 mb-3">
                <div class="card shadow-sm">
                    <div class="card-header d-flex flex-wrap align-items-center justify-content-between gap-2">
                        <div class="small text-uppercase text-muted fw-semibold">Series Navigation</div>
                        <div class="d-flex flex-wrap gap-2">
                            <a class="btn btn-outline-secondary btn-sm" href="{% url 'atlas:series_detail' pk=series.pk %}">Series details</a>
                            {% if can_edit %}
                                <a class="btn btn-outline-secondary btn-sm" href="{% url 'atlas:task_overview' %}">Tasks</a>
                            {% endif %}
                            <button id="reset-viewport-button" class="btn btn-outline-secondary btn-sm">Reset viewport</button>
                        </div>
                    </div>
                    <div class="card-body d-flex flex-column flex-md-row justify-content-between align-items-start gap-3">
                        <div>
                            <h4 class="card-title mb-1">Series: {{ series.modality }} - {{ series.examination }}</h4>
                            <div class="text-muted small">{{ series.plane }}, {{ series.contrast }}</div>
                            <div class="mt-2">Description: <span class="text-break">{{ series.description }}</span></div>
                            <div class="mt-2 text-muted">Author: {{ series.get_author_display }}</div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <div class="row">
            <div class="col-md-8 mb-3">
                <div class="card">
                    <div class="card-body p-2">
                        {% with image_url_array_and_count=series.get_image_url_array_and_count %}
                            <div id="root"
                                 class="dicom-viewer-root w-100 viewer-frame-standard series-viewer-resizable"
                                 style="height: clamp(640px, 78vh, 1200px); min-height: 640px; resize: vertical; overflow: auto;"
                                 data-images="{{ image_url_array_and_count.0 }}"
                                 data-auto-cache-stack=false>
                            </div>
                        {% endwith %}
                    </div>
                    <div class="card-footer bg-white d-flex flex-wrap gap-2 align-items-center">
                        {% if can_edit and editing_finding < 1 %}
                            <button id="add-finding-button" class="btn btn-primary btn-sm">Add finding</button>
                            <button id="clone-finding-button" class="btn btn-outline-primary btn-sm"
                                    title="Clone an existing finding"
                                    hx-get="{% url 'atlas:series_finding_related' series.pk %}"
                                    hx-target="#clone-findings-modal"
                                    hx-trigger="click"
                                    data-bs-toggle="modal"
                                    data-bs-target="#clone-findings-modal">Clone finding</button>
                        {% endif %}
                        <div class="ms-auto text-muted small">{{ series.get_image_count }} images</div>
                    </div>
                </div>
                <div class="mt-3">
                <!-- Finding form moved below the viewport -->
                    <div class="card mt-3">
                        <div class="card-header">Finding form</div>
                        <div class="card-body">
                            <div id="finding-form">
                                <div class="hide" id="hidden-form">
                                    {% if editing_finding > 0 %}
                                        <h5>Editing Finding</h5>
                                        <p class="small">Editing finding with ID: {{editing_finding}}</p>
                                    {% else %}
                                        <h5>Add Finding</h5>
                                        <p class="small">Click the button below to add a new finding.</p>
                                    {% endif %}
                                    <form method="post" id="series_finding_form">
                                        {% csrf_token %}
                                        {{series_finding_form|crispy}}
                                        <div class="d-flex gap-2 mt-2">
                                            <input type="submit" value="Submit" class="btn btn-success btn-sm">
                                            <button id="cancel-add-finding-button" class="btn btn-secondary btn-sm">Cancel</button>
                                        </div>
                                    </form>
                                </div>
                            </div>
                        </div>
                    </div>
                    <details class="styled-detail open">
                        <summary>Findings</summary>
                        <div class="mt-2">
                            {% for finding in series.findings.all %}
                                <div class="card mb-2">
                                    <div class="card-body d-flex flex-column flex-md-row justify-content-between gap-2">
                                        <div>
                                            <button id="finding-{{finding.pk}}-3d" class="btn btn-sm btn-outline-secondary view-finding-button-3d me-2"
                                                    data-annotationjson3d='{{finding.annotation_json_3d}}' data-viewerstatejson='{{finding.viewer_state_3d}}' data-findingid='{{finding.pk}}'>View 3D</button>
                                            <strong>Finding(s):</strong>
                                            {% for f in finding.findings.all %}{{f.get_link}}{% endfor %}<br />
                                            <strong>Structure(s):</strong> {% for s in finding.structures.all %}{{s.get_link}}{% endfor %}<br />
                                            <strong>Condition(s):</strong> {% for s in finding.conditions.all %}{{s.get_link}}{% endfor %}<br />
                                            <div class="mt-2">{{finding.description}}</div>
                                        </div>
                                        <div class="text-end">
                                            {% if request.user.is_superuser %}
                                                <button class="btn btn-sm btn-outline-dark mb-2" type="button" data-bs-toggle="collapse" data-bs-target="#extra-{{finding.pk}}">Raw JSON</button>
                                                <div class="collapse" id="extra-{{finding.pk}}">
                                                <pre class="small bg-light p-2">{{finding.annotation_json}}</pre>
                                                <pre class="small bg-light p-2">{{finding.viewport_json}}</pre>
                                                </div>
                                            {% endif %}
                                            {% if can_edit %}
                                                <div class="d-flex flex-column">
                                                    <a href="{% url 'atlas:series_edit_finding' pk=series.pk finding_pk=finding.pk %}" class="btn btn-sm btn-outline-primary mb-1">Edit</a>
                                                    <a href="{% url 'atlas:delete_finding' pk=finding.pk %}" class="btn btn-sm btn-outline-danger">Delete</a>
                                                </div>
                                            {% endif %}
                                        </div>
                                    </div>
                                </div>
                            {% empty %}
                                <p class="text-muted">No findings available.</p>
                            {% endfor %}
                        </div>
                    </details>
                </div>

            <!-- Images (loaded on demand via HTMX) -->
                <div class="card mt-3">
                    <div class="card-header d-flex justify-content-between align-items-center">
                        <span>Images</span>
                        <div>
                            <button id="load-images-button" class="btn btn-sm btn-outline-primary"
                                    hx-get="{% url 'atlas:series_images' series.pk %}"
                                    hx-target="#series-images-container"
                                    hx-swap="innerHTML"
                                    hx-trigger="click"
                                    hx-on="htmx:beforeRequest: document.getElementById('images-loading-indicator').style.display='inline-block'; htmx:afterSwap: document.getElementById('images-loading-indicator').style.display='none'; document.getElementById('load-images-button').disabled = true">
                                Load images
                            </button>
                            <a href="{% url 'atlas:series_download' series.pk %}" class="btn btn-sm btn-outline-success ms-2" target="_blank" rel="noopener">Download</a>
                            <span id="images-loading-indicator" class="spinner-border spinner-border-sm ms-2" role="status" aria-hidden="true" style="display:none"></span>
                        </div>
                    </div>
                    <div class="card-body">
                        <div id="series-images-container">
                            <p class="text-muted small">Click 'Load images' to fetch.</p>
                        </div>
                    </div>
                </div>

            </div>

            <div class="col-md-4 mb-3">
                <div class="card mb-3">
                    <div class="card-header">Cases</div>
                    <div class="card-body">
                        <div id="cases-list">
                            {% include 'atlas/partials/series_cases_list.html' %}
                        </div>
                        {% if can_edit %}
                            <details id="add-series-to-case-details" class="mt-2">
                                <summary>Add Series to Case</summary>
                                <form hx-post="{% url 'atlas:add_series_to_case' series.pk %}" hx-target="#cases-list" hx-swap="innerHTML" class="mt-2">
                                    {% csrf_token %}
                                    <div class="mb-2">
                                        <label for="case-select" class="form-label">Select Case</label>
                                        <select name="case_id" id="case-select" class="form-select" required>
                                            {% for case in available_cases %}
                                                <option value="{{ case.pk }}">{{ case.title }}</option>
                                            {% endfor %}
                                        </select>
                                    </div>
                                    <div class="d-flex gap-2">
                                        <button type="submit" class="btn btn-primary btn-sm">Add to Case</button>
                                        <button type="button" class="btn btn-outline-secondary btn-sm" onclick="document.getElementById('add-series-to-case-details').open = false">Close</button>
                                    </div>
                                </form>
                            </details>
                        {% endif %}
                    </div>
                </div>

                <div class="card mb-3">
                    <div class="card-header">Images size</div>
                    <div class="card-body">
                        <div id="series-image-size"
                             hx-get="{% url 'atlas:series_image_size' series.pk %}"
                             hx-trigger="load"
                             hx-swap="innerHTML">
                            <p class="text-muted small">Loading size...</p>
                        </div>
                    </div>
                </div>

                <div class="card mb-3">
                    <div class="card-header">Detected Groups</div>
                    <div class="card-body">
                        {% if detected_series_groups %}
                            <div class="d-flex flex-column gap-2">
                                {% for group in detected_series_groups %}
                                    <div class="border rounded p-2">
                                        <div class="fw-semibold small">{{ group.label|default:"Series group" }}</div>
                                        <div class="small text-muted">{{ group.imageIds|length }} images</div>
                                        {% if group.groupValues %}
                                            <div class="small mt-1">
                                                {% for key, value in group.groupValues.items %}
                                                    <span class="badge bg-secondary-subtle text-body border me-1 mb-1">{{ key }}={{ value }}</span>
                                                {% endfor %}
                                            </div>
                                        {% endif %}
                                    </div>
                                {% endfor %}
                            </div>
                        {% else %}
                            <p class="text-muted small mb-0">No detected grouping values for this series.</p>
                        {% endif %}
                    </div>
                </div>

                <div class="card mb-3">
                    <div class="card-header">Actions</div>
                    <div class="card-body d-flex flex-column gap-2">
                        <a class="btn btn-outline-primary btn-sm" href="{% url 'atlas:series_anonymise_dicom' pk=series.pk %}">Anonymise dicoms</a>
                        <div class="dropdown">
                            <button class="btn btn-outline-primary btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
                                Order Images
                            </button>
                            <ul class="dropdown-menu dropdown-menu-dark">
                                <li><a class="dropdown-item" href="{% url 'atlas:series_order_dicom' pk=series.pk %}">By slice location</a></li>
                                <li><a class="dropdown-item" href="{% url 'atlas:series_order_dicom_instance' pk=series.pk %}">By instance number</a></li>
                                <li><a class="dropdown-item" href="{% url 'atlas:series_order_dicom_SeriesInstanceUID' pk=series.pk %}">By SeriesInstanceUID</a></li>
                                <li><a class="dropdown-item" href="{% url 'atlas:series_order_upload_filename' pk=series.pk %}">By uploaded filename</a></li>
                            </ul>
                        </div>
                        <div hx-get="{% url 'atlas:series_split_by_tag' pk=series.pk %}"
                             hx-trigger="load"
                             hx-swap="outerHTML">
                            <span class="text-muted small">Loading split controls…</span>
                        </div>
                        <button class="btn btn-outline-info btn-sm"
                                hx-get="{% url 'atlas:series_tag_consistency' pk=series.pk %}?analyze=1"
                                hx-target="#series-tag-consistency-modal .modal-content"
                                hx-swap="innerHTML"
                                hx-indicator="#series-tag-consistency-load-indicator"
                                data-bs-toggle="modal"
                                data-bs-target="#series-tag-consistency-modal">
                            Analyze tag consistency
                        </button>
                        <span id="series-tag-consistency-load-indicator" class="spinner-border spinner-border-sm text-info htmx-indicator" role="status" aria-hidden="true"></span>
                        {% if can_edit %}
                            <button class="btn btn-outline-warning btn-sm"
                                    data-bs-toggle="modal"
                                    data-bs-target="#truncate-series-modal">
                                <i class="bi bi-sliders"></i> Series tools
                            </button>

                            <div class="card mt-2">
                                <div class="card-header d-flex align-items-center justify-content-between">
                                    <span class="small fw-semibold">Background Task Progress</span>
                                    <div class="d-flex gap-2">
                                        <a class="btn btn-outline-info btn-sm" href="{% url 'atlas:task_overview' %}">Task Overview</a>
                                        <button id="clear-recon-monitors-btn" type="button" class="btn btn-outline-secondary btn-sm">Clear</button>
                                    </div>
                                </div>
                                <div class="card-body p-2">
                                    <div id="persistent-recon-tasks" class="d-flex flex-column gap-2">
                                        <div id="persistent-recon-empty" class="small text-muted">No tracked reconstruction tasks yet.</div>
                                    </div>
                                </div>
                            </div>
                        {% endif %}
                    </div>
                </div>
            </div>
        </div>
    </div>


    <div id="clone-findings-modal" class="modal modal-blur fade" tabindex="-1">
        <div class="modal-dialog modal-dialog-centered related-finding-modal modal-wide-md">
            <div class="modal-content"></div>
        </div>
    </div>

    <div id="series-tag-consistency-modal" class="modal modal-blur fade" tabindex="-1">
        <div class="modal-dialog modal-dialog-centered modal-xl modal-wide-xl">
            <div class="modal-content"></div>
        </div>
    </div>

    <!-- Series Optimization Modal -->
    {% if can_edit %}
        <div id="truncate-series-modal" class="modal modal-blur fade" tabindex="-1">
            <div class="modal-dialog modal-dialog-centered modal-xl">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title">Series Tools</h5>
                        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                    </div>
                    <div class="modal-body">
                        <div class="row g-3">
                            <div class="col-md-6">
                                <div class="card h-100">
                                    <div class="card-header fw-semibold">Viewer / Compare Preview</div>
                                    <div class="card-body p-2 d-flex flex-column gap-2">
                                        <div id="truncate_viewer" class="dicom-viewer-root w-100"
                                             style="height: 460px; min-height: 360px; resize: vertical; overflow: auto; background: #222;"
                                             data-images="{{ image_url_array_and_count.0 }}"
                                             data-auto-cache-stack="false">
                                        </div>
                                        <div class="small text-muted">Downsample compare preview loads into this viewer as stack options.</div>
                                    </div>
                                </div>
                            </div>

                            <div class="col-md-6">
                                <div class="card">
                                    <div class="card-header fw-semibold">Operations</div>
                                    <div class="card-body">
                                        <div class="alert alert-warning" role="alert">
                                            <strong>Warning:</strong> Destructive actions cannot be undone.
                                        </div>

                                        <form id="series-optimize-form"
                                              hx-post="{% url 'atlas:series_optimize' series_id=series.pk %}"
                                              hx-target="#series-optimize-feedback"
                                              hx-swap="innerHTML"
                                              hx-indicator="#series-optimize-indicator">
                                            {% csrf_token %}
                                            <input type="hidden" name="start" id="opt-start-hidden" value="1">
                                            <input type="hidden" name="end" id="opt-end-hidden" value="{{ image_url_array_and_count.1 }}">

                                            <div class="mb-3">
                                                <label class="form-label">Start image</label>
                                                <div class="input-group">
                                                    <input id="truncate-lower-input" type="number" class="form-control form-control-sm" value="1" min="1" max="{{image_url_array_and_count.1}}">
                                                    <button id="truncate-set-lower-btn" class="btn btn-outline-secondary btn-sm" type="button">Set from viewer</button>
                                                </div>
                                            </div>

                                            <div class="mb-3">
                                                <label class="form-label">End image</label>
                                                <div class="input-group">
                                                    <input id="truncate-upper-input" type="number" class="form-control form-control-sm" value="{{image_url_array_and_count.1}}" min="1" max="{{image_url_array_and_count.1}}">
                                                    <button id="truncate-set-upper-btn" class="btn btn-outline-secondary btn-sm" type="button">Set from viewer</button>
                                                </div>
                                            </div>

                                            <div class="d-flex flex-wrap gap-2 mb-3">
                                                <button id="truncate-test-modal-btn" class="btn btn-sm btn-outline-primary" type="button">Test preview</button>
                                                <button id="truncate-apply-btn" class="btn btn-sm btn-danger" type="submit" name="operation" value="truncate">Apply truncate</button>
                                                <button class="btn btn-sm btn-outline-warning" type="submit" name="operation" value="remove_empty">Remove empty DICOMs</button>
                                            </div>

                                            <div id="truncate-progress" class="d-none mb-3">
                                                <div class="small text-warning mb-1">Applying truncate. Please wait...</div>
                                                <div class="progress" style="height: 8px;">
                                                    <div class="progress-bar progress-bar-striped progress-bar-animated bg-warning" style="width: 100%" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"></div>
                                                </div>
                                            </div>

                                            <div class="small text-muted mb-3">Truncate is a dedicated step. Downsample and reconstruction always run on the full active series.</div>

                                            <hr>

                                            <div class="mb-3">
                                                <label for="downsample-pct" class="form-label">Downsample percentage</label>
                                                <select id="downsample-pct" name="downsample_pct" class="form-select form-select-sm">
                                                    <option value="25">25% reduction</option>
                                                    <option value="40">40% reduction</option>
                                                    <option value="50" selected>50% reduction</option>
                                                    <option value="60">60% reduction</option>
                                                    <option value="75">75% reduction</option>
                                                </select>
                                                <small class="text-muted">Original hash is preserved after downsampling.</small>
                                            </div>

                                            <div class="d-flex flex-wrap gap-2 mb-3">
                                                <button class="btn btn-sm btn-outline-info" type="submit" name="operation" value="downsample_preview">Preview downsample compare</button>
                                                <button class="btn btn-sm btn-outline-success" type="submit" name="operation" value="downsample">Apply downsample</button>
                                            </div>

                                            <hr>

                                            <div class="mb-2">
                                                <div class="fw-semibold small mb-2">Generate reconstructions</div>
                                                <div class="d-flex flex-wrap gap-3 mb-2">
                                                    <div class="form-check">
                                                        <input class="form-check-input" type="checkbox" id="recon-axial" name="recon_planes" value="axial" checked>
                                                        <label class="form-check-label" for="recon-axial">Axial</label>
                                                    </div>
                                                    <div class="form-check">
                                                        <input class="form-check-input" type="checkbox" id="recon-coronal" name="recon_planes" value="coronal" checked>
                                                        <label class="form-check-label" for="recon-coronal">Coronal</label>
                                                    </div>
                                                    <div class="form-check">
                                                        <input class="form-check-input" type="checkbox" id="recon-sagittal" name="recon_planes" value="sagittal" checked>
                                                        <label class="form-check-label" for="recon-sagittal">Sagittal</label>
                                                    </div>
                                                </div>

                                                <div class="row g-2">
                                                    <div class="col-6">
                                                        <label class="form-label small mb-1" for="recon-slice-thickness">Slice thickness (mm)</label>
                                                        <input type="number" step="0.1" min="0.1" id="recon-slice-thickness" name="recon_slice_thickness" class="form-control form-control-sm" placeholder="e.g. 1.0">
                                                    </div>
                                                    <div class="col-6">
                                                        <label class="form-label small mb-1" for="recon-slice-spacing">Slice spacing (mm)</label>
                                                        <input type="number" step="0.1" min="0.1" id="recon-slice-spacing" name="recon_slice_spacing" class="form-control form-control-sm" placeholder="e.g. 1.0">
                                                    </div>
                                                    <div class="col-12">
                                                        <label class="form-label small mb-1" for="recon-thickness-mode">Thickness merge mode</label>
                                                        <select id="recon-thickness-mode" name="recon_thickness_mode" class="form-select form-select-sm">
                                                            <option value="mean" selected>Mean (default)</option>
                                                            <option value="max">Max intensity</option>
                                                            <option value="min">Min intensity</option>
                                                        </select>
                                                        <small class="text-muted">Thickness controls slab merge depth. Spacing controls distance between generated slices.</small>
                                                    </div>
                                                </div>

                                                <div class="mt-2">
                                                    <button class="btn btn-sm btn-outline-primary" type="submit" name="operation" value="reconstruct">Generate recon series</button>
                                                    <a class="btn btn-sm btn-outline-info ms-1" href="{% url 'atlas:series_reconstruct_advanced' series_id=series.pk %}" target="_blank" rel="noopener">
                                                        Advanced reconstruction page
                                                    </a>
                                                </div>
                                            </div>
                                        </form>
                                    </div>

                                    <div class="card-footer d-flex align-items-center gap-2">
                                        <span id="series-optimize-indicator" class="spinner-border spinner-border-sm text-primary htmx-indicator" role="status" aria-hidden="true"></span>
                                        <small class="text-muted">Processing operations may take time for large stacks.</small>
                                        <button type="button" class="btn btn-secondary btn-sm ms-auto" data-bs-dismiss="modal">Close</button>
                                    </div>
                                    <div class="px-3 pb-3">
                                        <div id="series-optimize-feedback" class="small"></div>
                                        <div id="truncate-modal-output" class="alert alert-info d-none mt-2 mb-0" role="alert"></div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    {% endif %}


    <script>
        $(document).ready(function () {
            const apiKey = "root"
            const truncateApiKey = "truncate_viewer";
            const seriesPk = {{ series.pk }};
            const totalImages = {{ image_url_array_and_count.1 }};
            const viewerHeightKey = `series_viewer_height_${seriesPk}`;
            const truncateViewerHeightKey = `truncate_viewer_height_${seriesPk}`;
            const reconTaskStorageKey = `series_recon_tasks_${seriesPk}`;

            // Restore viewer height from localStorage
            function restoreViewerHeight() {
                const saved = localStorage.getItem(viewerHeightKey);
                if (saved) {
                    const viewer = document.getElementById('root');
                    if (viewer) {
                        viewer.style.height = saved;
                    }
                }
            }

            // Save viewer height to localStorage when resized
            function persistViewerHeight() {
                const viewer = document.getElementById('root');
                if (viewer) {
                    const height = window.getComputedStyle(viewer).height;
                    localStorage.setItem(viewerHeightKey, height);
                }
            }

            // Listen for resize events on the viewer
            const viewer = document.getElementById('root');
            if (viewer) {
                const resizeObserver = new ResizeObserver(() => {
                    persistViewerHeight();
                });
                resizeObserver.observe(viewer);
                restoreViewerHeight();
                requestAnimationFrame(() => {
                    try {
                        if (window.resizeDicomViewers) {
                            window.resizeDicomViewers();
                        }
                        window.dispatchEvent(new Event('resize'));
                    } catch (e) {
                        console.warn('Viewer resize dispatch failed', e);
                    }
                });
            }

            function syncOptimizeBounds() {
                const startInput = document.getElementById('truncate-lower-input');
                const endInput = document.getElementById('truncate-upper-input');
                const startHidden = document.getElementById('opt-start-hidden');
                const endHidden = document.getElementById('opt-end-hidden');
                if (!startInput || !endInput || !startHidden || !endHidden) {
                    return;
                }
                startHidden.value = startInput.value;
                endHidden.value = endInput.value;
            }

            function updateBoundsInputs(startValue, endValue) {
                const startInput = document.getElementById('truncate-lower-input');
                const endInput = document.getElementById('truncate-upper-input');
                if (!startInput || !endInput) {
                    return;
                }
                startInput.value = String(startValue);
                endInput.value = String(endValue);
                startInput.max = String(endValue);
                endInput.max = String(endValue);
                syncOptimizeBounds();
            }

            function getStoredReconTasks() {
                try {
                    const raw = localStorage.getItem(reconTaskStorageKey);
                    if (!raw) {
                        return [];
                    }
                    const parsed = JSON.parse(raw);
                    return Array.isArray(parsed) ? parsed : [];
                } catch (e) {
                    return [];
                }
            }

            function setStoredReconTasks(items) {
                localStorage.setItem(reconTaskStorageKey, JSON.stringify(items));
            }

            function upsertStoredReconTask(taskId, statusUrl) {
                const current = getStoredReconTasks();
                const existing = current.find((t) => t.taskId === taskId);
                if (existing) {
                    existing.statusUrl = statusUrl;
                    existing.addedAt = Date.now();
                } else {
                    current.unshift({ taskId, statusUrl, addedAt: Date.now() });
                }
                setStoredReconTasks(current.slice(0, 25));
            }

            function removeStoredReconTask(taskId) {
                const filtered = getStoredReconTasks().filter((t) => t.taskId !== taskId);
                setStoredReconTasks(filtered);
            }

            function createPersistentTaskMonitor(taskId, statusUrl) {
                const wrap = document.getElementById('persistent-recon-tasks');
                const empty = document.getElementById('persistent-recon-empty');
                if (!wrap) {
                    return;
                }

                const cardId = `persistent-recon-card-${taskId}`;
                if (document.getElementById(cardId)) {
                    return;
                }

                empty?.classList.add('d-none');

                const card = document.createElement('div');
                card.id = cardId;
                card.className = 'border rounded p-2 bg-body-tertiary';

                const statusId = `persistent-recon-status-${taskId}`;
                const statusUrlWithTarget = `${statusUrl}?target_id=${statusId}`;

                card.innerHTML = `
                    <div class="d-flex align-items-center justify-content-between mb-1">
                        <div class="small fw-semibold">Recon task ${taskId}</div>
                        <button type="button" class="btn btn-outline-secondary btn-sm" data-remove-task-id="${taskId}">Hide</button>
                    </div>
                    <div id="${statusId}" hx-get="${statusUrlWithTarget}" hx-trigger="load, every 4s" hx-swap="outerHTML">
                        <div class="small text-muted">Loading task status...</div>
                    </div>
                `;

                wrap.prepend(card);
                card.querySelector('[data-remove-task-id]')?.addEventListener('click', () => {
                    removeStoredReconTask(taskId);
                    card.remove();
                    if (!wrap.querySelector('[id^="persistent-recon-card-"]')) {
                        empty?.classList.remove('d-none');
                    }
                });

                if (window.htmx) {
                    window.htmx.process(card);
                }
            }

            function renderStoredReconTaskMonitors() {
                const tasks = getStoredReconTasks();
                tasks.forEach((task) => {
                    if (task?.taskId && task?.statusUrl) {
                        createPersistentTaskMonitor(task.taskId, task.statusUrl);
                    }
                });
            }

            function getTruncateViewerElement() {
                return document.getElementById(truncateApiKey);
            }

            function persistTruncateViewerHeight() {
                const modalViewer = getTruncateViewerElement();
                if (!modalViewer) {
                    return;
                }
                const height = window.getComputedStyle(modalViewer).height;
                localStorage.setItem(truncateViewerHeightKey, height);
            }

            function applyTruncateViewerHeight(el) {
                if (!el) {
                    return;
                }
                const saved = localStorage.getItem(truncateViewerHeightKey);
                if (saved) {
                    el.style.height = saved;
                }
            }

            function observeTruncateViewerResize() {
                const modalViewer = getTruncateViewerElement();
                if (!modalViewer) {
                    return;
                }
                applyTruncateViewerHeight(modalViewer);
                const observer = new ResizeObserver(() => {
                    persistTruncateViewerHeight();
                });
                observer.observe(modalViewer);
            }

            // Modal optimization handlers
            const truncateModal = document.getElementById('truncate-series-modal');
            if (truncateModal) {
                truncateModal.addEventListener('show.bs.modal', function () {
                    observeTruncateViewerResize();
                    setTimeout(() => {
                        try {
                            if (window.mountDicomViewers) {
                                window.mountDicomViewers();
                            }
                            if (window.resizeDicomViewers) {
                                window.resizeDicomViewers();
                            }
                        } catch (e) {
                            console.warn('Modal viewer init failed', e);
                        }
                    }, 200);
                });

                function getTruncateViewerApi(baseName) {
                    const fn = window[`${baseName}_${truncateApiKey}`];
                    return typeof fn === 'function' ? fn : null;
                }

                document.getElementById('truncate-set-lower-btn')?.addEventListener('click', (e) => {
                    e.preventDefault();
                    const getStackPosition = getTruncateViewerApi('getCurrentStackPosition');
                    if (getStackPosition) {
                        const current = getStackPosition(0);
                        const pos = Number.isFinite(current) ? current + 1 : 1;
                        document.getElementById('truncate-lower-input').value = pos;
                        syncOptimizeBounds();
                    }
                });

                document.getElementById('truncate-set-upper-btn')?.addEventListener('click', (e) => {
                    e.preventDefault();
                    const getStackPosition = getTruncateViewerApi('getCurrentStackPosition');
                    if (getStackPosition) {
                        const current = getStackPosition(0);
                        const pos = Number.isFinite(current) ? current + 1 : 1;
                        document.getElementById('truncate-upper-input').value = pos;
                        syncOptimizeBounds();
                    }
                });

                document.getElementById('truncate-lower-input')?.addEventListener('input', syncOptimizeBounds);
                document.getElementById('truncate-upper-input')?.addEventListener('input', syncOptimizeBounds);

                document.getElementById('truncate-test-modal-btn')?.addEventListener('click', (e) => {
                    e.preventDefault();
                    const lower = parseInt(document.getElementById('truncate-lower-input').value) - 1;
                    const upper = parseInt(document.getElementById('truncate-upper-input').value) - 1;

                    if (lower < 0 || upper >= totalImages || lower > upper) {
                        alert('Invalid range. Please check your bounds.');
                        return;
                    }

                    const truncateFn = getTruncateViewerApi('truncateStack');
                    if (truncateFn) {
                        const ok = truncateFn(lower, upper);
                        if (ok) {
                            document.getElementById('truncate-modal-output').innerHTML = `Preview shows images ${lower + 1} to ${upper + 1} (${upper - lower + 1} total).`;
                            document.getElementById('truncate-modal-output').classList.remove('d-none');
                        }
                    } else {
                        document.getElementById('truncate-modal-output').innerHTML = 'Truncate viewer API not ready yet. Reopen the modal and try again.';
                        document.getElementById('truncate-modal-output').classList.remove('d-none');
                    }
                });
            }

            document.body.addEventListener('htmx:configRequest', function (event) {
                const form = document.getElementById('series-optimize-form');
                if (!form || event.target !== form) {
                    return;
                }
                syncOptimizeBounds();
            });

            document.body.addEventListener('htmx:beforeRequest', function (event) {
                const form = document.getElementById('series-optimize-form');
                if (!form || event.target !== form) {
                    return;
                }
                const op = event.detail?.parameters?.operation || '';
                const truncateProgress = document.getElementById('truncate-progress');
                const truncateApplyBtn = document.getElementById('truncate-apply-btn');
                if (op === 'truncate') {
                    truncateProgress?.classList.remove('d-none');
                    if (truncateApplyBtn) {
                        truncateApplyBtn.disabled = true;
                    }
                }
            });

            document.body.addEventListener('htmx:afterRequest', function (event) {
                const form = document.getElementById('series-optimize-form');
                if (!form || event.target !== form) {
                    return;
                }
                const truncateProgress = document.getElementById('truncate-progress');
                const truncateApplyBtn = document.getElementById('truncate-apply-btn');
                truncateProgress?.classList.add('d-none');
                if (truncateApplyBtn) {
                    truncateApplyBtn.disabled = false;
                }
            });

            document.body.addEventListener('htmx:afterSwap', function (event) {
                if (event.target && event.target.id === 'series-optimize-feedback') {
                    const reconPayload = document.getElementById('recon-task-payload');
                    if (reconPayload) {
                        const taskId = reconPayload.dataset.taskId;
                        const statusUrl = reconPayload.dataset.statusUrl;
                        if (taskId && statusUrl) {
                            upsertStoredReconTask(taskId, statusUrl);
                            createPersistentTaskMonitor(taskId, statusUrl);
                        }
                    }

                    const truncatePayload = document.getElementById('truncate-range-payload');
                    if (truncatePayload) {
                        const start = parseInt(truncatePayload.dataset.start || '1', 10);
                        const end = parseInt(truncatePayload.dataset.end || '1', 10);
                        if (Number.isFinite(start) && Number.isFinite(end) && end >= start) {
                            updateBoundsInputs(start, end);
                        }
                    }

                    const payload = document.getElementById('downsample-compare-payload');
                    if (!payload) {
                        return;
                    }

                    const namedStacks = payload.dataset.namedStacks;
                    if (!namedStacks) {
                        return;
                    }

                    const modalViewer = getTruncateViewerElement();
                    if (!modalViewer) {
                        return;
                    }

                    const existingHeight = window.getComputedStyle(modalViewer).height;

                    // Recreate the same modal viewer element to force a clean remount with compare stacks.
                    const fresh = document.createElement('div');
                    fresh.id = truncateApiKey;
                    fresh.className = 'dicom-viewer-root w-100';
                    fresh.style.height = existingHeight;
                    fresh.style.minHeight = '360px';
                    fresh.style.resize = 'vertical';
                    fresh.style.overflow = 'auto';
                    fresh.style.background = '#222';
                    fresh.setAttribute('data-auto-cache-stack', 'false');
                    fresh.setAttribute('data-named-stacks', namedStacks);

                    modalViewer.replaceWith(fresh);
                    observeTruncateViewerResize();

                    try {
                        if (window.mountDicomViewers) {
                            window.mountDicomViewers();
                        }
                        if (window.resizeDicomViewers) {
                            window.resizeDicomViewers();
                        }
                    } catch (err) {
                        console.warn('Failed to mount downsample compare viewer', err);
                    }
                }
            });

            syncOptimizeBounds();
            renderStoredReconTaskMonitors();

            document.getElementById('clear-recon-monitors-btn')?.addEventListener('click', () => {
                setStoredReconTasks([]);
                const wrap = document.getElementById('persistent-recon-tasks');
                const empty = document.getElementById('persistent-recon-empty');
                wrap?.querySelectorAll('[id^="persistent-recon-card-"]')?.forEach((node) => node.remove());
                empty?.classList.remove('d-none');
            });

            $("#add-finding-button").click(() => {
                $("#hidden-form").show()
                $("#add-finding-button").hide()
                $("#clone-finding-button").hide()
            });
            $("#cancel-add-finding-button").click((e) => {
                $("#hidden-form").hide()
                $("#add-finding-button").show()
                $("#clone-finding-button").show()
                e.preventDefault();
            });

            $("#reset-viewport-button").click(() => {
                resetViewer_root();
            });

            $(".view-finding-button-3d").each((n, el) => {
                $(el).click((e) => {
                    dicom_element = $(".cornerstone-element").get(0);
                    annotationjson3d = JSON.parse(e.currentTarget.dataset.annotationjson3d);
                    viewer_state_json = JSON.parse(e.currentTarget.dataset.viewerstatejson);
                    console.log("Loading 3D annotation and viewer state", annotationjson3d, viewer_state_json);
                    importAnnotations_root(annotationjson3d);
                    importViewerState_root(viewer_state_json);
                    $(el).addClass("active");
                });
            });

            {% if editing_finding > 0 %}
                $("#hidden-form").show()
                setTimeout(function() {
                    $(".view-finding-button-3d[data-findingid={{editing_finding}}]").trigger("click");
                }, 1000)
            {% endif %}

            {% if request.GET.show_finding %}
                function show_finding() {
                    console.log("show finding")
                    $("#finding-{{ request.GET.show_finding }}").trigger("click");
                }
                setTimeout(show_finding, 500);
            {% endif %}
        });

        $(document).on('submit', '#series_finding_form', function (e) {
            e.preventDefault();

            $.ajax({
                type: 'POST',
                url: '{% url "atlas:add_finding" %}',
                data: {
                    series_finding_id: {{ editing_finding }},
                    description: $('#id_description').val(),
                    series: {{ series.pk }},
                    annotation_json_3d: window.exportAnnotations_root(),
                    viewer_state_3d: window.exportViewerState_root(),
                    findings: JSON.stringify($('#finding-form select[name="findings"]').find(":selected")
                            .map((i, el) => {
                                return $(el).val()
                            }).toArray()),
                    structures: JSON.stringify($('#finding-form select[name="structures"]').find(
                        ":selected")
                            .map((i, el) => {
                                return $(el).val()
                            }).toArray()),
                    conditions: JSON.stringify($('#finding-form select[name="conditions"]').find(
                        ":selected")
                            .map((i, el) => {
                                return $(el).val()
                            }).toArray()),
                    csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),
                    action: 'post'
                },
                success: function (json) {
                    $("#finding-form").empty();
                    toastr.info('Finding added.');
                    location.href='{{series.get_absolute_url}}';
                },
                error: function (xhr, errmsg, err) {
                    console.log(xhr.status + ": " + xhr
                            .responseText);
                }
            });
        });
    </script>

{% endwith %}

<style>
    .case-item {
        transition: background-color 0.3s ease;
    }

    .case-item:hover {
        background-color: darkgray;
    }



    .remove-button:hover {
        color: #dc3545; /* Optional: Make the remove button text red on hover */
    }

    .active {
        font-weight: bold; /* Optional: Make the active button text bold */
        border-style: dashed;
    }
    #finding-form #hidden-form {
        background: #23272b;
        border: 2px solid #198754;
        border-radius: 1rem;
        box-shadow: 0 0 16px #19875455;
        padding: 2rem;
        margin: 2rem 0;
        transition: box-shadow 0.3s;
    }
    #finding-form #hidden-form:focus-within {
        box-shadow: 0 0 24px #198754aa;
    }

    #diff-show-all {
        color: red;
        cursor: pointer;
    }
    #diff-show-diff {
        color: #0d6efd;
        cursor: pointer;
    }

    details.styled-detail {
        background: #23272b;
        border-radius: 0.7em;
        margin: 1.2em 0;
        padding: 1.2em 1.5em 1em 1.5em;
        box-shadow: 0 2px 12px rgba(0,0,0,0.10);
        border: 1px solid #343a40;
        transition: box-shadow 0.2s;
    }
    details.styled-detail[open] {
        box-shadow: 0 4px 24px rgba(13,110,253,0.10);
        border-color: #0d6efd;
    }
    details.styled-detail > summary {
        font-size: 1.15em;
        font-weight: 600;
        color: #0d6efd;
        cursor: pointer;
        margin: -1.2em -1.5em 1em -1.5em;
        padding: 1.2em 1.5em 0.5em 1.5em;
        border-bottom: 1px solid #343a40;
        background: linear-gradient(90deg, #23272b 80%, #0d6efd22 100%);
        border-radius: 0.7em 0.7em 0 0;
        transition: background 0.2s, font-size 0.2s;
    }

    details.styled-detail:not([open]) {
        padding-bottom: 0;
        min-height: 0;
    }

    details.styled-detail:not([open]) > *:not(summary) {
        display: none;
    }

    details.styled-detail:not([open]) > summary {
        padding: 0.7em 1.2em 0.3em 1.2em;
    }
    details.styled-detail > summary:hover {
        background: linear-gradient(90deg, #23272b 60%, #0d6efd44 100%);
        color: #198754;
    }
    details.styled-detail > div, details.styled-detail > p, details.styled-detail > form, details.styled-detail > ul {
        margin-top: 0.7em;
    }
    .alert {
        margin-top: 1em;
    }
    /* Nested details */
    details.styled-detail details {
        background: #181a1b;
        border: 1px solid #444;
        margin: 0.7em 0;
        box-shadow: none;
    }
    details.styled-detail details > summary {
        color: #ffc107;
        background: linear-gradient(90deg, #181a1b 80%, #ffc10722 100%);
        border-bottom: 1px solid #444;
    }
    details.styled-detail details > summary:hover {
        color: #0d6efd;
        background: linear-gradient(90deg, #181a1b 60%, #0d6efd22 100%);
    }
</style>