{% extends "shared/frontend/base.html" %}

{% block title %}Sager - BMC Hub{% endblock %}

{% block extra_css %}
<style>
    .search-bar {
        margin-bottom: 0;
        flex: 1 1 380px;
        min-width: 240px;
    }
    
    .search-bar input {
        border-radius: 8px;
        border: 1px solid rgba(0,0,0,0.1);
        padding: 0.45rem 0.85rem;
    }

    .top-controls-row {
        display: flex;
        align-items: center;
        gap: 0.6rem;
        margin-bottom: 0.9rem;
    }

    .top-controls-actions {
        display: inline-flex;
        align-items: center;
        gap: 0.45rem;
        margin-left: auto;
        flex-shrink: 0;
    }

    .top-controls-actions .btn {
        white-space: nowrap;
        padding-top: 0.4rem;
        padding-bottom: 0.4rem;
    }
    
    .table-wrapper {
        background: var(--bg-card);
        border-radius: 12px;
        overflow-x: auto;
        overflow-y: hidden;
        box-shadow: 0 2px 8px rgba(0,0,0,0.05);
    }
    
    .sag-table {
        width: 100%;
        min-width: 1760px;
        margin: 0;
    }
    
    .sag-table thead {
        background: var(--accent);
        color: white;
    }
    
    .sag-table thead th {
        padding: 0.6rem 0.75rem;
        font-weight: 600;
        font-size: 0.78rem;
        text-transform: uppercase;
        letter-spacing: 0.3px;
        border: none;
        white-space: nowrap;
    }

    .sag-table thead th.col-expand,
    .sag-table tbody td.col-expand {
        width: 44px;
        min-width: 44px;
        max-width: 44px;
        text-align: center;
        padding-left: 0.45rem;
        padding-right: 0.45rem;
    }
    
    .sag-table tbody tr {
        border-bottom: 1px solid rgba(0,0,0,0.05);
        transition: all 0.2s;
        cursor: pointer;
    }

    .sag-table tbody tr:nth-child(even) {
        background: rgba(15, 76, 117, 0.04);
    }
    
    .sag-table tbody tr:hover {
        background: var(--accent-light);
    }
    
    .sag-table tbody td {
        padding: 0.5rem 0.75rem;
        vertical-align: top;
        font-size: 0.86rem;
        white-space: nowrap;
    }

    .sag-table td.col-company,
    .sag-table td.col-contact,
    .sag-table td.col-owner,
    .sag-table td.col-group,
    .sag-table td.col-desc {
        white-space: normal;
    }

    .sag-table td.col-company,
    .sag-table td.col-contact,
    .sag-table td.col-owner,
    .sag-table td.col-group {
        max-width: 180px;
    }

    .sag-table td.col-desc {
        min-width: 260px;
        max-width: 360px;
    }
    
    .sag-id {
        font-weight: 700;
        color: var(--accent);
        font-size: 0.95rem;
    }

    .sag-unread-badge {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 1.35rem;
        height: 1.35rem;
        padding: 0 0.35rem;
        margin-left: 0.45rem;
        border-radius: 999px;
        font-size: 0.72rem;
        font-weight: 700;
        color: #fff;
        vertical-align: middle;
        box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.85);
    }

    .sag-unread-fresh {
        background: #2f9e44;
    }

    .sag-unread-warm {
        background: #f08c00;
    }

    .sag-unread-hot {
        background: #c92a2a;
        animation: sagUnreadPulse 1.8s ease-in-out infinite;
    }

    @keyframes sagUnreadPulse {
        0% { transform: scale(1); }
        50% { transform: scale(1.08); }
        100% { transform: scale(1); }
    }
    
    .sag-titel {
        font-weight: 600;
        color: var(--text-primary);
        margin-bottom: 0;
    }
    
    .sag-beskrivelse {
        color: var(--text-secondary);
        font-size: 0.8rem;
        margin-top: 0.2rem;
        display: -webkit-box;
        -webkit-line-clamp: 1;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }
    
    /* Tree view styles */
    .tree-row {
        position: relative;
    }
    
    .tree-row.has-children {
        cursor: pointer;
    }
    
    .tree-row.has-children:before {
        content: none;
    }
    
    .tree-toggle {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 20px;
        height: 20px;
        background: var(--accent-light);
        border-radius: 4px;
        cursor: pointer;
        transition: all 0.2s;
        font-size: 0.75rem;
        color: var(--accent);
        font-weight: bold;
        position: absolute;
        left: 0.5rem;
        top: 50%;
        transform: translateY(-50%);
    }

    .col-expand .tree-toggle {
        position: static;
        transform: none;
    }
    
    .tree-toggle:hover {
        background: var(--accent);
        color: white;
    }
    
    .tree-child {
        background: rgba(0,0,0,0.02);
    }
    
    .tree-child td {
        padding: 0.5rem 1rem !important;
        border-top: none !important;
    }
    
    .tree-child .child-branch {
        color: rgba(0,0,0,0.4);
        font-size: 1rem;
        font-weight: 600;
        line-height: 1;
    }
    
    .relation-badge {
        display: inline-block;
        font-size: 0.65rem;
        padding: 0.25rem 0.6rem;
        background: var(--accent);
        color: white;
        border-radius: 12px;
        margin-right: 0.5rem;
        font-weight: 600;
        vertical-align: middle;
    }
    
    .status-badge {
        display: inline-block;
        padding: 0.35rem 0.8rem;
        border-radius: 20px;
        font-size: 0.75rem;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.5px;
        background: #e9ecef;
        color: #495057;
    }
    
    .status-åben {
        background: #fff3cd;
        color: #856404;
    }
    
    .status-lukket {
        background: #d4edda;
        color: #155724;
    }

    .status-under-behandling,
    .status-i-gang,
    .status-in-progress {
        background: #dbeafe;
        color: #1e3a8a;
    }

    .status-afventer,
    .status-on-hold {
        background: #fef3c7;
        color: #92400e;
    }

    .status-løst,
    .status-afsluttet,
    .status-resolved,
    .status-done,
    .status-closed {
        background: #d1fae5;
        color: #065f46;
    }
    
    .filter-pills {
        display: flex;
        gap: 0.5rem;
        margin-bottom: 1rem;
        flex-wrap: wrap;
    }
    
    .filter-pill {
        padding: 0.5rem 1rem;
        border-radius: 20px;
        border: 1px solid rgba(0,0,0,0.1);
        background: var(--bg-card);
        cursor: pointer;
        transition: all 0.2s;
        font-size: 0.85rem;
    }
    
    .filter-pill:hover {
        background: var(--accent-light);
        border-color: var(--accent);
    }
    
    .filter-pill.active {
        background: var(--accent);
        color: white;
        border-color: var(--accent);
    }
    
    .stats-bar {
        display: inline-flex;
        gap: 0.4rem;
        margin-bottom: 0;
        padding: 0.25rem;
        background: var(--bg-card);
        border-radius: 999px;
        border: 1px solid rgba(0,0,0,0.08);
        flex-shrink: 0;
    }
    
    .stat-item {
        text-align: center;
        padding: 0.2rem 0.5rem;
        border-radius: 999px;
        background: rgba(0,0,0,0.03);
        line-height: 1.15;
    }
    
    .stat-value {
        font-size: 0.92rem;
        font-weight: 700;
        color: var(--accent);
    }
    
    .stat-label {
        font-size: 0.62rem;
        color: var(--text-secondary);
        text-transform: uppercase;
        letter-spacing: 0.35px;
    }

    .type-filter-wrap {
        min-width: 200px;
        max-width: 280px;
    }

    .type-filter-header {
        display: none;
    }

    .type-filter-dropdown .dropdown-toggle {
        width: 100%;
        text-align: left;
        border-radius: 0.375rem;
        border: 1px solid #ced4da;
        background: #fff;
        color: var(--text-primary);
        font-weight: 400;
        font-size: 0.86rem;
        padding: 0.28rem 2rem 0.28rem 0.65rem;
        min-height: calc(1.4em + 0.56rem + 2px);
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 0.6rem;
        box-shadow: none;
    }

    .type-filter-dropdown .dropdown-toggle:hover,
    .type-filter-dropdown .dropdown-toggle:focus,
    .type-filter-dropdown .dropdown-toggle:active,
    .type-filter-dropdown .dropdown-toggle.show {
        border-color: #86b7fe;
        box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
        color: var(--text-primary);
        background: #fff;
    }

    .type-filter-dropdown .dropdown-toggle::after {
        margin-left: 0.5rem;
    }

    .type-filter-dropdown .dropdown-menu {
        width: min(340px, 92vw);
        border-radius: 0.5rem;
        border: 1px solid rgba(0, 0, 0, 0.15);
        padding: 0.45rem;
        box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
    }

    .type-filter-checkbox-list {
        max-height: 12.5rem;
        overflow-y: auto;
        padding-right: 0.2rem;
    }

    .type-filter-checkbox-item {
        display: flex;
        align-items: center;
        gap: 0.55rem;
        padding: 0.34rem 0.42rem;
        border-radius: 10px;
        cursor: pointer;
        margin-bottom: 0.2rem;
        transition: background-color 0.15s ease;
    }

    .type-filter-checkbox-item:hover {
        background: rgba(15, 76, 117, 0.08);
    }

    .type-filter-checkbox-item input {
        margin-top: 0;
        cursor: pointer;
    }

    .type-filter-checkbox-label {
        font-size: 0.8rem;
        font-weight: 600;
        color: #16384f;
        user-select: none;
    }

    .type-filter-menu-actions {
        border-top: 1px solid rgba(0, 0, 0, 0.08);
        margin-top: 0.35rem;
        padding-top: 0.38rem;
        display: flex;
        justify-content: flex-end;
        gap: 0.3rem;
    }

    .type-filter-menu-actions .btn {
        font-size: 0.72rem;
        line-height: 1.2;
        padding: 0.2rem 0.45rem;
    }

    .type-filter-footer {
        display: flex;
        align-items: center;
        justify-content: flex-start;
        gap: 0.6rem;
        margin-top: 0.25rem;
    }

    .type-filter-selection {
        font-size: 0.73rem;
        color: var(--text-secondary);
        min-height: 1rem;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        flex: 1;
    }

    .type-filter-empty {
        font-size: 0.8rem;
        color: var(--text-secondary);
        padding: 0.22rem 0.1rem;
    }

    .mini-filter-wrap {
        min-width: 190px;
        max-width: 260px;
    }

    .mini-filter-dropdown .dropdown-toggle {
        width: 100%;
        text-align: left;
        border-radius: 0.375rem;
        border: 1px solid #ced4da;
        background: #fff;
        color: var(--text-primary);
        font-weight: 400;
        font-size: 0.86rem;
        padding: 0.28rem 2rem 0.28rem 0.65rem;
        min-height: calc(1.4em + 0.56rem + 2px);
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 0.5rem;
        box-shadow: none;
    }

    .mini-filter-dropdown .dropdown-toggle:hover,
    .mini-filter-dropdown .dropdown-toggle:focus,
    .mini-filter-dropdown .dropdown-toggle:active,
    .mini-filter-dropdown .dropdown-toggle.show {
        border-color: #86b7fe;
        box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
        color: var(--text-primary);
        background: #fff;
    }

    .mini-filter-dropdown .dropdown-menu {
        width: min(320px, 92vw);
        border-radius: 0.5rem;
        border: 1px solid rgba(0, 0, 0, 0.15);
        padding: 0.45rem;
        box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
    }

    .mini-filter-list {
        max-height: 12.5rem;
        overflow-y: auto;
        padding-right: 0.2rem;
    }

    .mini-filter-item {
        display: flex;
        align-items: center;
        gap: 0.52rem;
        padding: 0.34rem 0.42rem;
        border-radius: 10px;
        cursor: pointer;
        margin-bottom: 0.15rem;
        transition: background-color 0.15s ease;
    }

    .mini-filter-item:hover {
        background: rgba(15, 76, 117, 0.08);
    }

    .mini-filter-item input {
        margin-top: 0;
        cursor: pointer;
    }

    .mini-filter-label {
        font-size: 0.8rem;
        font-weight: 600;
        color: #16384f;
        user-select: none;
    }

    .mini-filter-footer {
        border-top: 1px solid rgba(0, 0, 0, 0.08);
        margin-top: 0.35rem;
        padding-top: 0.35rem;
        display: flex;
        justify-content: flex-end;
    }

    .mini-filter-clear {
        font-size: 0.72rem;
        line-height: 1.2;
        padding: 0.2rem 0.45rem;
    }

    .owner-cell {
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    .owner-avatar {
        width: 1.75rem;
        height: 1.75rem;
        border-radius: 999px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        font-size: 0.68rem;
        font-weight: 700;
        letter-spacing: 0.02em;
        color: #fff;
        background: var(--accent);
        flex-shrink: 0;
    }

    .owner-avatar.group-avatar {
        background: #7c3aed;
    }

    .owner-avatar.empty-avatar {
        background: #cbd5e1;
        color: #475569;
    }

    .owner-name {
        color: var(--text-secondary);
        font-size: 0.85rem;
        word-break: break-word;
    }

    @media (max-width: 1100px) {
        .top-controls-row {
            flex-wrap: wrap;
        }

        .top-controls-actions {
            margin-left: 0;
        }
    }
    
    .empty-state {
        text-align: center;
        padding: 3rem;
        color: var(--text-secondary);
    }
    
    .empty-state i {
        font-size: 3rem;
        margin-bottom: 1rem;
        opacity: 0.3;
    }

    .sag-top-alerts {
        margin-bottom: 1rem;
    }

    .sag-top-alerts .alert {
        border-left: 6px solid;
        box-shadow: 0 2px 8px rgba(0,0,0,0.08);
    }

    .sag-top-alerts .alert-warning {
        border-left-color: #f59f00;
    }

    .sag-top-alerts .alert-danger {
        border-left-color: #e03131;
    }
</style>
{% endblock %}

{% block content %}
{% macro initials_bubble(label, group=false) -%}
    {% if label %}
        {% set norm = label.strip() %}
        {% set parts = norm.split() %}
        {% set initials = ((parts[0][0] if parts|length > 0 else norm[0]) ~ (parts[1][0] if parts|length > 1 else ''))|upper %}
        <span class="owner-avatar {% if group %}group-avatar{% endif %}" title="{{ norm }}">{{ initials }}</span>
    {% else %}
        <span class="owner-avatar empty-avatar" title="Ikke sat">-</span>
    {% endif %}
{%- endmacro %}

<div class="container-fluid" style="max-width: none; padding-top: 0.65rem;">
    <div id="sagTopAlerts" class="sag-top-alerts d-none"></div>

    <div class="top-controls-row">
        <h1 style="margin: 0; color: var(--accent); flex-shrink: 0;">
            <i class="bi bi-list-check"></i>
        </h1>

        <div class="stats-bar">
            <div class="stat-item">
                <div class="stat-value">{{ sager|length }}</div>
                <div class="stat-label">Total</div>
            </div>
            <div class="stat-item">
                <div class="stat-value">{{ sager|selectattr('status', 'equalto', 'åben')|list|length }}</div>
                <div class="stat-label">Åbne</div>
            </div>
        </div>

        <div class="search-bar">
            <input type="text" 
                   class="form-control" 
                   id="searchInput" 
                   placeholder="🔍 Søg efter sag ID, titel, beskrivelse..."
                   autocomplete="off">
        </div>

        <div class="top-controls-actions">
            <button class="btn btn-outline-primary" onclick="window.location.href='/sag/varekob-salg'">
                <i class="bi bi-basket3 me-2"></i>Varekøb & Salg
            </button>
            <button class="btn btn-primary" style="background: var(--accent); border: none;" onclick="window.location.href='/sag/new'">
                <i class="bi bi-plus-lg me-2"></i>Ny Sag
            </button>
        </div>
    </div>
    
    <div class="d-flex flex-wrap align-items-center gap-2 mb-3">
        <div class="filter-pills">
            <div class="filter-pill active" data-filter="all">Alle</div>
            <div class="filter-pill" data-filter="åben">Åbne</div>
            <div class="filter-pill" data-filter="lukket">Lukkede</div>
        </div>
        <div class="type-filter-wrap">
            <div class="dropdown type-filter-dropdown mb-1">
                <button class="btn dropdown-toggle" type="button" id="typeFilterDropdownBtn" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
                    <span id="typeFilterDropdownLabel">Vælg typer</span>
                </button>
                <div class="dropdown-menu" aria-labelledby="typeFilterDropdownBtn">
                    <div class="type-filter-checkbox-list" id="typeFilterCheckboxList"></div>
                    <div class="type-filter-menu-actions">
                        <button class="btn btn-sm btn-outline-secondary" type="button" id="clearTypeFilterBtn">Ryd</button>
                        <button class="btn btn-sm btn-primary" type="button" id="saveTypeFilterDefaultBtn">Gem</button>
                    </div>
                </div>
            </div>
            <select class="d-none" id="typeFilter" multiple title="Type filter data source"></select>
        </div>
        <div class="mini-filter-wrap">
            <div class="dropdown mini-filter-dropdown mb-1">
                <button class="btn dropdown-toggle" type="button" id="assigneeDropdownBtn" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
                    <span id="assigneeDropdownLabel">Ansvarlig</span>
                </button>
                <div class="dropdown-menu" aria-labelledby="assigneeDropdownBtn">
                    <div class="mini-filter-list" id="assigneeFilterList"></div>
                    <div class="mini-filter-footer">
                        <button class="btn btn-sm btn-outline-secondary mini-filter-clear" type="button" id="clearAssigneeFilterBtn">Ryd</button>
                    </div>
                </div>
            </div>
            <select class="d-none" name="ansvarlig_bruger_id" id="assigneeFilter" multiple>
                    <option value="">Alle medarbejdere</option>
                    <option value="__UNASSIGNED__" {% if current_unassigned %}selected{% endif %}>Uden ansvarlig</option>
                    {% for user in assignment_users or [] %}
                    <option value="{{ user.user_id }}" {% if current_ansvarlig_bruger_id == user.user_id %}selected{% endif %}>{{ user.display_name }}</option>
                    {% endfor %}
            </select>
        </div>
        <div class="mini-filter-wrap">
            <div class="dropdown mini-filter-dropdown mb-1">
                <button class="btn dropdown-toggle" type="button" id="groupDropdownBtn" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
                    <span id="groupDropdownLabel">Grupper</span>
                </button>
                <div class="dropdown-menu" aria-labelledby="groupDropdownBtn">
                    <div class="mini-filter-list" id="groupFilterList"></div>
                    <div class="mini-filter-footer">
                        <button class="btn btn-sm btn-outline-secondary mini-filter-clear" type="button" id="clearGroupFilterBtn">Ryd</button>
                    </div>
                </div>
            </div>
            <select class="d-none" name="assigned_group_id" id="groupFilter" multiple>
                    <option value="">Alle grupper</option>
                    {% for group in assignment_groups or [] %}
                    <option value="{{ group.id }}" {% if current_assigned_group_id == group.id %}selected{% endif %}>{{ group.name }}</option>
                    {% endfor %}
            </select>
        </div>
        <a class="btn btn-sm btn-outline-secondary" href="{{ toggle_include_deferred_url }}">
            {% if include_deferred %}Skjul udsatte{% else %}Vis udsatte{% endif %}
        </a>
    </div>
    
    <!-- Table -->
    <div class="table-wrapper">
        {% if sager %}
        <table class="sag-table">
            <thead>
                <tr>
                    <th class="col-expand"></th>
                    <th style="width: 90px;">SagsID</th>
                    <th style="width: 180px;">Virksom.</th>
                    <th style="width: 150px;">Kontakt</th>
                    <th style="width: 300px;">Beskr.</th>
                    <th style="width: 120px;">Type</th>
                    <th style="width: 110px;">Prioritet</th>
                    <th style="width: 120px;">Status</th>
                    <th style="width: 160px;">Ansvarl.</th>
                    <th style="width: 170px;">Gruppe/Level</th>
                    <th style="width: 240px;">Næste todo</th>
                    <th style="width: 120px;">Opret.</th>
                    <th style="width: 120px;">Arbejdsstart</th>
                    <th style="width: 140px;">Start senest</th>
                    <th style="width: 120px;">Deadline</th>
                </tr>
            </thead>
            <tbody id="sagTableBody">
                {% for sag in sager %}
                {% if sag.id not in child_ids %}
                {% set has_relations = sag.id in relations_map and relations_map[sag.id]|length > 0 %}
                <tr class="tree-row {% if has_relations %}has-children{% endif %}" 
                    data-sag-id="{{ sag.id }}"
                    data-status="{{ sag.status }}"
                    data-type="{{ sag.template_key or sag.type or 'ticket' }}"
                    data-assignee-id="{{ sag.ansvarlig_bruger_id if sag.ansvarlig_bruger_id else '' }}"
                    data-group-id="{{ sag.assigned_group_id if sag.assigned_group_id else '' }}">
                    <td class="col-expand" onclick="event.stopPropagation();">
                        {% if has_relations %}
                        <span class="tree-toggle" onclick="toggleTreeNode(event, {{ sag.id }})">+</span>
                        {% endif %}
                    </td>
                    <td>
                        <span class="sag-id" role="button" onclick="window.location.href='/sag/{{ sag.id }}/v3'">#{{ sag.id }}</span>
                        {% if (sag.unread_email_count or 0) > 0 %}
                        {% set unread_level = sag.unread_email_level or 'fresh' %}
                        <span class="sag-unread-badge sag-unread-{{ unread_level }}" title="{{ sag.unread_email_count }} ulæste e-mails">
                            {{ sag.unread_email_count if sag.unread_email_count <= 99 else '99+' }}
                        </span>
                        {% endif %}
                    </td>
                    <td class="col-company" onclick="window.location.href='/sag/{{ sag.id }}/v3'" style="color: var(--text-secondary); font-size: 0.85rem;">
                        {{ sag.customer_name if sag.customer_name else '-' }}
                    </td>
                    <td class="col-contact" onclick="window.location.href='/sag/{{ sag.id }}/v3'" style="color: var(--text-secondary); font-size: 0.85rem;">
                        {{ sag.kontakt_navn if sag.kontakt_navn and sag.kontakt_navn.strip() else '-' }}
                    </td>
                    <td class="col-desc" onclick="window.location.href='/sag/{{ sag.id }}/v3'">
                        <div class="sag-titel" {% if sag.beskrivelse %}title="{{ sag.beskrivelse }}"{% endif %}>{{ sag.titel }}</div>
                    </td>
                    <td onclick="window.location.href='/sag/{{ sag.id }}/v3'">
                        <span class="badge bg-light text-dark border">{{ sag.template_key or sag.type or 'ticket' }}</span>
                    </td>
                    <td onclick="window.location.href='/sag/{{ sag.id }}/v3'" style="color: var(--text-secondary); font-size: 0.85rem; text-transform: capitalize;">
                        {{ sag.priority if sag.priority else 'normal' }}
                    </td>
                    <td onclick="window.location.href='/sag/{{ sag.id }}/v3'">
                        {% set status_raw = sag.status if sag.status else 'åben' %}
                        {% set status_class = status_raw|lower|replace(' ', '-') %}
                        <span class="status-badge status-{{ status_class }}">{{ status_raw }}</span>
                    </td>
                    <td class="col-owner" onclick="window.location.href='/sag/{{ sag.id }}/v3'">
                        <div class="owner-cell">
                            {{ initials_bubble(sag.ansvarlig_navn) }}
                        </div>
                    </td>
                    <td class="col-group" onclick="window.location.href='/sag/{{ sag.id }}/v3'" style="color: var(--text-secondary); font-size: 0.85rem;">
                        <div class="owner-cell">
                            {{ initials_bubble(sag.assigned_group_name, true) }}
                        </div>
                    </td>
                    <td onclick="window.location.href='/sag/{{ sag.id }}/v3'" style="color: var(--text-secondary); font-size: 0.85rem; white-space: normal; max-width: 240px;">
                        {% if sag.next_todo_title %}
                        <div>{{ sag.next_todo_title }}</div>
                        {% if sag.next_todo_due_date %}
                        <div class="small text-muted">Forfald: {{ sag.next_todo_due_date.strftime('%d/%m-%Y') }}</div>
                        {% endif %}
                        {% else %}
                        -
                        {% endif %}
                    </td>
                    <td onclick="window.location.href='/sag/{{ sag.id }}/v3'" style="color: var(--text-secondary);">
                        {{ sag.created_at.strftime('%d/%m-%Y') if sag.created_at else '-' }}
                    </td>
                    <td onclick="window.location.href='/sag/{{ sag.id }}/v3'" style="color: var(--text-secondary);">
                        {{ sag.start_date.strftime('%d/%m-%Y') if sag.start_date else '-' }}
                    </td>
                    <td onclick="window.location.href='/sag/{{ sag.id }}/v3'" style="color: var(--text-secondary);">
                        {{ sag.deferred_until.strftime('%d/%m-%Y') if sag.deferred_until else '-' }}
                    </td>
                    <td onclick="window.location.href='/sag/{{ sag.id }}/v3'" style="color: var(--text-secondary);">
                        {{ sag.deadline.strftime('%d/%m-%Y') if sag.deadline else '-' }}
                    </td>
                </tr>
                {% if has_relations %}
                    {% set seen_targets = [] %}
                    {% for rel in relations_map[sag.id] %}
                    {% set related_sag = sager|selectattr('id', 'equalto', rel.target_id)|first %}
                    {% if related_sag and rel.target_id not in seen_targets %}
                    {% set _ = seen_targets.append(rel.target_id) %}
                    {% set all_rel_types = relations_map[sag.id]|selectattr('target_id', 'equalto', rel.target_id)|map(attribute='type')|list %}
                    <tr class="tree-child" data-parent="{{ sag.id }}" data-status="{{ related_sag.status }}" data-type="{{ related_sag.template_key or related_sag.type or 'ticket' }}" data-assignee-id="{{ related_sag.ansvarlig_bruger_id if related_sag.ansvarlig_bruger_id else '' }}" data-group-id="{{ related_sag.assigned_group_id if related_sag.assigned_group_id else '' }}" style="display: none;">
                        <td class="col-expand"><span class="child-branch">└</span></td>
                        <td>
                            <span class="sag-id" role="button" onclick="window.location.href='/sag/{{ related_sag.id }}/v3'">#{{ related_sag.id }}</span>
                            {% if (related_sag.unread_email_count or 0) > 0 %}
                            {% set child_unread_level = related_sag.unread_email_level or 'fresh' %}
                            <span class="sag-unread-badge sag-unread-{{ child_unread_level }}" title="{{ related_sag.unread_email_count }} ulæste e-mails">
                                {{ related_sag.unread_email_count if related_sag.unread_email_count <= 99 else '99+' }}
                            </span>
                            {% endif %}
                        </td>
                        <td class="col-company" onclick="window.location.href='/sag/{{ related_sag.id }}/v3'" style="color: var(--text-secondary); font-size: 0.85rem;">
                            {{ related_sag.customer_name if related_sag.customer_name else '-' }}
                        </td>
                        <td class="col-contact" onclick="window.location.href='/sag/{{ related_sag.id }}/v3'" style="color: var(--text-secondary); font-size: 0.85rem;">
                            {{ related_sag.kontakt_navn if related_sag.kontakt_navn and related_sag.kontakt_navn.strip() else '-' }}
                        </td>
                        <td class="col-desc" onclick="window.location.href='/sag/{{ related_sag.id }}/v3'">
                            {% for rt in all_rel_types %}
                            <span class="relation-badge">{{ rt }}</span>
                            {% endfor %}
                            <div class="sag-titel" style="display: inline;" {% if related_sag.beskrivelse %}title="{{ related_sag.beskrivelse }}"{% endif %}>{{ related_sag.titel }}</div>
                        </td>
                        <td onclick="window.location.href='/sag/{{ related_sag.id }}/v3'">
                            <span class="badge bg-light text-dark border">{{ related_sag.template_key or related_sag.type or 'ticket' }}</span>
                        </td>
                        <td onclick="window.location.href='/sag/{{ related_sag.id }}/v3'" style="color: var(--text-secondary); font-size: 0.85rem; text-transform: capitalize;">
                            {{ related_sag.priority if related_sag.priority else 'normal' }}
                        </td>
                        <td onclick="window.location.href='/sag/{{ related_sag.id }}/v3'">
                            {% set related_status_raw = related_sag.status if related_sag.status else 'åben' %}
                            {% set related_status_class = related_status_raw|lower|replace(' ', '-') %}
                            <span class="status-badge status-{{ related_status_class }}">{{ related_status_raw }}</span>
                        </td>
                        <td class="col-owner" onclick="window.location.href='/sag/{{ related_sag.id }}/v3'">
                            <div class="owner-cell">
                                {{ initials_bubble(related_sag.ansvarlig_navn) }}
                            </div>
                        </td>
                        <td class="col-group" onclick="window.location.href='/sag/{{ related_sag.id }}/v3'" style="color: var(--text-secondary); font-size: 0.85rem;">
                            <div class="owner-cell">
                                {{ initials_bubble(related_sag.assigned_group_name, true) }}
                            </div>
                        </td>
                        <td onclick="window.location.href='/sag/{{ related_sag.id }}/v3'" style="color: var(--text-secondary); font-size: 0.85rem; white-space: normal; max-width: 240px;">
                            {% if related_sag.next_todo_title %}
                            <div>{{ related_sag.next_todo_title }}</div>
                            {% if related_sag.next_todo_due_date %}
                            <div class="small text-muted">Forfald: {{ related_sag.next_todo_due_date.strftime('%d/%m-%Y') }}</div>
                            {% endif %}
                            {% else %}
                            -
                            {% endif %}
                        </td>
                        <td onclick="window.location.href='/sag/{{ related_sag.id }}/v3'" style="color: var(--text-secondary);">
                            {{ related_sag.created_at.strftime('%d/%m-%Y') if related_sag.created_at else '-' }}
                        </td>
                        <td onclick="window.location.href='/sag/{{ related_sag.id }}/v3'" style="color: var(--text-secondary);">
                            {{ related_sag.start_date.strftime('%d/%m-%Y') if related_sag.start_date else '-' }}
                        </td>
                        <td onclick="window.location.href='/sag/{{ related_sag.id }}/v3'" style="color: var(--text-secondary);">
                            {{ related_sag.deferred_until.strftime('%d/%m-%Y') if related_sag.deferred_until else '-' }}
                        </td>
                        <td onclick="window.location.href='/sag/{{ related_sag.id }}/v3'" style="color: var(--text-secondary);">
                            {{ related_sag.deadline.strftime('%d/%m-%Y') if related_sag.deadline else '-' }}
                        </td>
                    </tr>
                    {% endif %}
                    {% endfor %}
                {% endif %}
                {% endif %}
                {% endfor %}
            </tbody>
        </table>
        {% else %}
        <div class="empty-state">
            <i class="bi bi-inbox"></i>
            <p>Ingen sager fundet</p>
        </div>
        {% endif %}
    </div>
</div>

<script>
    const topAlertCustomerId = {{ current_customer_id if current_customer_id else 'null' }};

    function escapeTopAlertHtml(value) {
        return String(value ?? '')
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#39;');
    }

    async function loadSagTopAlertsForCustomer(customerId) {
        const container = document.getElementById('sagTopAlerts');
        if (!container || !customerId) {
            return;
        }

        container.classList.remove('d-none');
        container.innerHTML = '<div class="alert alert-info mb-0"><span class="spinner-border spinner-border-sm me-2"></span>Henter kunde-alerts...</div>';

        try {
            const response = await fetch(`/api/v1/alert-notes/check?entity_type=customer&entity_id=${customerId}`, {
                credentials: 'include'
            });

            if (!response.ok) {
                throw new Error(`HTTP ${response.status}`);
            }

            const data = await response.json();
            const alerts = (data?.alerts || []).filter((alert) => ['critical', 'warning'].includes(String(alert?.severity || '').toLowerCase()));

            if (!alerts.length) {
                container.classList.add('d-none');
                container.innerHTML = '';
                return;
            }

            const html = alerts.map((alert) => {
                const isCritical = String(alert.severity || '').toLowerCase() === 'critical';
                const klass = isCritical ? 'alert-danger' : 'alert-warning';
                const label = isCritical ? 'KRITISK' : 'ADVARSEL';
                const title = escapeTopAlertHtml(alert.title || 'Vigtig kundeinformation');
                const message = escapeTopAlertHtml(alert.message || '');
                return `
                    <div class="alert ${klass} mb-2" role="alert">
                        <strong>${label}:</strong> ${title}
                        ${message ? `<div class="small mt-1">${message}</div>` : ''}
                    </div>
                `;
            }).join('');

            container.innerHTML = html;
            container.classList.remove('d-none');
        } catch (error) {
            console.error('Failed to load customer alerts on sag list:', error);
            container.innerHTML = '<div class="alert alert-warning mb-0" role="alert"><strong>Advarsel:</strong> Kunde-alerts kunne ikke hentes.</div>';
            container.classList.remove('d-none');
        }
    }

    // Tree toggle functionality
    function toggleTreeNode(event, sagId) {
        event.stopPropagation();
        const toggle = event.currentTarget || event.target;
        const row = toggle.closest('tr');

        if (!row) {
            return;
        }

        if (row.classList.contains('expanded')) {
            row.classList.remove('expanded');
            toggle.textContent = '+';
        } else {
            row.classList.add('expanded');
            toggle.textContent = '-';
        }

        applyFilters();
    }
    
    // Search functionality
    const searchInput = document.getElementById('searchInput');
    const allRows = document.querySelectorAll('.tree-row');
    let currentSearch = '';
    let currentFilter = 'all';
    let currentTypes = new Set();
    let currentAssignees = new Set();
    let currentGroups = new Set();
    const closedStatuses = new Set({{ (closed_statuses or ['lukket', 'løst', 'afsluttet', 'closed', 'resolved', 'done'])|tojson }});

    const assigneeFilter = document.getElementById('assigneeFilter');
    const groupFilter = document.getElementById('groupFilter');
    const assigneeFilterList = document.getElementById('assigneeFilterList');
    const groupFilterList = document.getElementById('groupFilterList');
    const assigneeDropdownLabel = document.getElementById('assigneeDropdownLabel');
    const groupDropdownLabel = document.getElementById('groupDropdownLabel');
    const clearAssigneeFilterBtn = document.getElementById('clearAssigneeFilterBtn');
    const clearGroupFilterBtn = document.getElementById('clearGroupFilterBtn');

    function applyFilters() {
        const search = currentSearch;

        allRows.forEach(row => {
            const text = row.textContent.toLowerCase();
            const status = String(row.dataset.status || '').toLowerCase();
            const type = row.dataset.type || 'ticket';
            const assigneeRaw = String(row.dataset.assigneeId || '').trim();
            const groupRaw = String(row.dataset.groupId || '').trim();
            const assigneeId = assigneeRaw || '__UNASSIGNED__';
            const groupId = groupRaw;
            const matchesSearch = text.includes(search);
            const isClosed = closedStatuses.has(status);
            const matchesFilter = currentFilter === 'all'
                || (currentFilter === 'åben' && !isClosed)
                || (currentFilter === 'lukket' && isClosed)
                || status === currentFilter;
            const matchesType = currentTypes.size === 0 || currentTypes.has(type);
            const matchesAssignee = currentAssignees.size === 0 || currentAssignees.has(assigneeId);
            const matchesGroup = currentGroups.size === 0 || currentGroups.has(groupId);
            const visible = matchesSearch && matchesFilter && matchesType && matchesAssignee && matchesGroup;

            row.style.display = visible ? '' : 'none';

            const sagId = row.dataset.sagId;
            if (sagId) {
                const children = document.querySelectorAll(`tr[data-parent="${sagId}"]`);
                children.forEach(child => {
                    const childText = child.textContent.toLowerCase();
                    const childStatus = String(child.dataset.status || '').toLowerCase();
                    const childType = child.dataset.type || 'ticket';
                    const childAssigneeRaw = String(child.dataset.assigneeId || '').trim();
                    const childGroupRaw = String(child.dataset.groupId || '').trim();
                    const childAssigneeId = childAssigneeRaw || '__UNASSIGNED__';
                    const childGroupId = childGroupRaw;
                    const childMatchesSearch = childText.includes(search);
                    const childIsClosed = closedStatuses.has(childStatus);
                    const childMatchesFilter = currentFilter === 'all'
                        || (currentFilter === 'åben' && !childIsClosed)
                        || (currentFilter === 'lukket' && childIsClosed)
                        || childStatus === currentFilter;
                    const childMatchesType = currentTypes.size === 0 || currentTypes.has(childType);
                    const childMatchesAssignee = currentAssignees.size === 0 || currentAssignees.has(childAssigneeId);
                    const childMatchesGroup = currentGroups.size === 0 || currentGroups.has(childGroupId);
                    const childVisible = visible && row.classList.contains('expanded') && childMatchesSearch && childMatchesFilter && childMatchesType && childMatchesAssignee && childMatchesGroup;
                    child.style.display = childVisible ? '' : 'none';
                });
            }
        });
    }

    function renderMiniFilterOptions(selectEl, listEl, selectedSet, labelEl, defaultLabel) {
        if (!selectEl || !listEl) return;
        const options = Array.from(selectEl.options || []).filter((opt) => String(opt.value || '').trim() !== '');
        if (options.length === 0) {
            listEl.innerHTML = '<span class="type-filter-empty">Ingen muligheder</span>';
            if (labelEl) labelEl.textContent = defaultLabel;
            return;
        }

        listEl.innerHTML = options.map((opt) => {
            const value = String(opt.value || '').trim();
            const isChecked = selectedSet.has(value);
            const safeValue = value.replace(/"/g, '&quot;');
            const safeLabel = String(opt.textContent || value).replace(/"/g, '&quot;');
            const safeId = `${selectEl.id}-opt-${value.replace(/[^a-zA-Z0-9_-]+/g, '-')}`;
            return `
                <label class="mini-filter-item" for="${safeId}">
                    <input class="form-check-input" type="checkbox" id="${safeId}" data-value="${safeValue}" ${isChecked ? 'checked' : ''}>
                    <span class="mini-filter-label">${safeLabel}</span>
                </label>
            `;
        }).join('');

        if (labelEl) {
            labelEl.textContent = selectedSet.size === 0 ? defaultLabel : `${selectedSet.size} valgt`;
        }
    }

    function syncMiniSelect(selectEl, selectedSet) {
        if (!selectEl) return;
        Array.from(selectEl.options || []).forEach((opt) => {
            const value = String(opt.value || '').trim();
            opt.selected = value !== '' && selectedSet.has(value);
        });
    }

    if (assigneeFilterList && assigneeFilter) {
        assigneeFilterList.addEventListener('change', function(event) {
            const checkbox = event.target.closest('input[type="checkbox"][data-value]');
            if (!checkbox) return;
            const value = String(checkbox.dataset.value || '').trim();
            if (!value) return;
            if (checkbox.checked) currentAssignees.add(value);
            else currentAssignees.delete(value);
            syncMiniSelect(assigneeFilter, currentAssignees);
            renderMiniFilterOptions(assigneeFilter, assigneeFilterList, currentAssignees, assigneeDropdownLabel, 'Ansvarlig');
            applyFilters();
        });
    }

    if (groupFilterList && groupFilter) {
        groupFilterList.addEventListener('change', function(event) {
            const checkbox = event.target.closest('input[type="checkbox"][data-value]');
            if (!checkbox) return;
            const value = String(checkbox.dataset.value || '').trim();
            if (!value) return;
            if (checkbox.checked) currentGroups.add(value);
            else currentGroups.delete(value);
            syncMiniSelect(groupFilter, currentGroups);
            renderMiniFilterOptions(groupFilter, groupFilterList, currentGroups, groupDropdownLabel, 'Grupper');
            applyFilters();
        });
    }

    if (clearAssigneeFilterBtn) {
        clearAssigneeFilterBtn.addEventListener('click', function() {
            currentAssignees = new Set();
            syncMiniSelect(assigneeFilter, currentAssignees);
            renderMiniFilterOptions(assigneeFilter, assigneeFilterList, currentAssignees, assigneeDropdownLabel, 'Ansvarlig');
            applyFilters();
        });
    }

    if (clearGroupFilterBtn) {
        clearGroupFilterBtn.addEventListener('click', function() {
            currentGroups = new Set();
            syncMiniSelect(groupFilter, currentGroups);
            renderMiniFilterOptions(groupFilter, groupFilterList, currentGroups, groupDropdownLabel, 'Grupper');
            applyFilters();
        });
    }

    function initMiniFilterSelections() {
        if (assigneeFilter) {
            currentAssignees = new Set(
                Array.from(assigneeFilter.selectedOptions || [])
                    .map((opt) => String(opt.value || '').trim())
                    .filter((value) => value)
            );
            renderMiniFilterOptions(assigneeFilter, assigneeFilterList, currentAssignees, assigneeDropdownLabel, 'Ansvarlig');
        }

        if (groupFilter) {
            currentGroups = new Set(
                Array.from(groupFilter.selectedOptions || [])
                    .map((opt) => String(opt.value || '').trim())
                    .filter((value) => value)
            );
            renderMiniFilterOptions(groupFilter, groupFilterList, currentGroups, groupDropdownLabel, 'Grupper');
        }
    }

    if (searchInput) {
        searchInput.addEventListener('input', function(e) {
            currentSearch = e.target.value.toLowerCase();
            applyFilters();
        });
    }
    
    // Filter functionality
    const filterPills = document.querySelectorAll('.filter-pill');
    
    filterPills.forEach(pill => {
        pill.addEventListener('click', function() {
            // Update active state
            filterPills.forEach(p => p.classList.remove('active'));
            this.classList.add('active');
            
            currentFilter = this.dataset.filter || 'all';
            applyFilters();
        });
    });

    const typeFilter = document.getElementById('typeFilter');
    const typeFilterCheckboxList = document.getElementById('typeFilterCheckboxList');
    const typeFilterDropdownLabel = document.getElementById('typeFilterDropdownLabel');
    const typeFilterSelection = document.getElementById('typeFilterSelection');
    const clearTypeFilterBtn = document.getElementById('clearTypeFilterBtn');
    const saveTypeFilterDefaultBtn = document.getElementById('saveTypeFilterDefaultBtn');

    function getSelectedTypesFromUi() {
        return Array.from(currentTypes);
    }

    function renderTypeFilterOptions() {
        if (!typeFilterCheckboxList || !typeFilter) return;
        const options = Array.from(typeFilter.options || []);
        if (options.length === 0) {
            typeFilterCheckboxList.innerHTML = '<span class="type-filter-empty">Ingen typer fundet</span>';
            if (typeFilterSelection) typeFilterSelection.textContent = 'Ingen typer tilgaengelige';
            if (typeFilterDropdownLabel) typeFilterDropdownLabel.textContent = 'Ingen typer';
            return;
        }

        typeFilterCheckboxList.innerHTML = options.map((opt) => {
            const value = String(opt.value || '').trim();
            const key = value.toLowerCase();
            const isActive = currentTypes.has(key);
            const safeValue = value.replace(/"/g, '&quot;');
            const safeId = `type-filter-opt-${key.replace(/[^a-z0-9_-]+/g, '-')}`;
            return `
                <label class="type-filter-checkbox-item" for="${safeId}">
                    <input class="form-check-input" type="checkbox" id="${safeId}" data-type="${safeValue}" ${isActive ? 'checked' : ''}>
                    <span class="type-filter-checkbox-label">${value}</span>
                </label>
            `;
        }).join('');

        if (typeFilterSelection) {
            const selectedLabels = options
                .filter((opt) => currentTypes.has(String(opt.value || '').trim().toLowerCase()))
                .map((opt) => String(opt.value || '').trim())
                .filter(Boolean);
            if (selectedLabels.length === 0) {
                typeFilterSelection.textContent = 'Ingen typer valgt';
                if (typeFilterDropdownLabel) typeFilterDropdownLabel.textContent = 'Vælg typer';
            } else {
                typeFilterSelection.textContent = `Valgt: ${selectedLabels.join(', ')}`;
                if (typeFilterDropdownLabel) typeFilterDropdownLabel.textContent = `${selectedLabels.length} valgt`;
            }
        }
    }

    function applySelectedTypesToUi() {
        if (!typeFilter) return;
        Array.from(typeFilter.options || []).forEach((opt) => {
            opt.selected = currentTypes.has(String(opt.value || '').trim().toLowerCase());
        });
        renderTypeFilterOptions();
    }

    if (typeFilterCheckboxList) {
        typeFilterCheckboxList.addEventListener('change', function(event) {
            const checkbox = event.target.closest('input[type="checkbox"][data-type]');
            if (!checkbox) return;
            const typeValue = String(checkbox.dataset.type || '').trim().toLowerCase();
            if (!typeValue) return;
            if (checkbox.checked) {
                currentTypes.add(typeValue);
            } else {
                currentTypes.delete(typeValue);
            }
            applySelectedTypesToUi();
            applyFilters();
        });
    }

    if (clearTypeFilterBtn) {
        clearTypeFilterBtn.addEventListener('click', function() {
            currentTypes = new Set();
            applySelectedTypesToUi();
            applyFilters();
        });
    }

    async function loadTypeFilters() {
        if (!typeFilter) return;
        try {
            const rowTypes = new Set(Array.from(document.querySelectorAll('.tree-row[data-type], .tree-child[data-type]'))
                .map((row) => (row.dataset.type || '').trim())
                .filter(Boolean));

            const res = await fetch('/api/v1/settings/case_types');
            let configuredTypes = [];
            if (res.ok) {
                const setting = await res.json();
                const types = JSON.parse(setting.value || '[]');
                if (Array.isArray(types)) {
                    configuredTypes = types;
                }
            }

            configuredTypes.forEach((t) => rowTypes.add(String(t || '').trim()));
            const mergedTypes = Array.from(rowTypes).filter(Boolean).sort((a, b) => a.localeCompare(b, 'da'));
            if (mergedTypes.length === 0) {
                typeFilter.innerHTML = '';
                renderTypeFilterOptions();
                return;
            }

            typeFilter.innerHTML = mergedTypes.map(type => `<option value="${type}">${type}</option>`).join('');
            applySelectedTypesToUi();
        } catch (err) {
            console.error('Failed to load case types', err);
        }
    }

    async function loadTypeFilterPreferences() {
        try {
            const res = await fetch('/api/v1/sag/me/list-preferences', { credentials: 'include' });
            if (!res.ok) return;
            const data = await res.json();
            const fromServer = Array.isArray(data?.type_filters) ? data.type_filters : [];
            currentTypes = new Set(fromServer.map((v) => String(v || '').trim().toLowerCase()).filter(Boolean));
            applySelectedTypesToUi();
            applyFilters();
        } catch (err) {
            console.error('Failed to load type filter preferences', err);
        }
    }

    async function saveTypeFilterPreferences() {
        if (!saveTypeFilterDefaultBtn) return;
        const selected = getSelectedTypesFromUi();
        saveTypeFilterDefaultBtn.disabled = true;
        try {
            const res = await fetch('/api/v1/sag/me/list-preferences', {
                method: 'PATCH',
                credentials: 'include',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ type_filters: selected }),
            });
            if (!res.ok) throw new Error(`HTTP ${res.status}`);
            if (typeof showNotification === 'function') {
                showNotification('Typefilter gemt som standard', 'success');
            }
        } catch (err) {
            console.error('Failed to save type filter preferences', err);
            if (typeof showNotification === 'function') {
                showNotification('Kunne ikke gemme typefilter', 'error');
            }
        } finally {
            saveTypeFilterDefaultBtn.disabled = false;
        }
    }

    if (saveTypeFilterDefaultBtn) {
        saveTypeFilterDefaultBtn.addEventListener('click', saveTypeFilterPreferences);
    }

    (async () => {
        initMiniFilterSelections();
        await loadTypeFilters();
        await loadTypeFilterPreferences();
        applyFilters();
    })();

    if (topAlertCustomerId) {
        loadSagTopAlertsForCustomer(topAlertCustomerId);
    }
</script>
{% endblock %}
