import logging
from datetime import datetime, timezone
from typing import Any, Dict, List, Optional

from app.core.database import execute_query, execute_query_single

logger = logging.getLogger(__name__)

CLOSED_CASE_STATUSES = ("lukket", "løst", "closed", "resolved")
URGENT_PRIORITIES = ("urgent", "high", "kritisk", "critical")


def _safe_count(row: Optional[dict], key: str = "count") -> int:
    if not row:
        return 0
    try:
        return int(row.get(key) or 0)
    except (TypeError, ValueError):
        return 0


def _format_elapsed(seconds: int) -> str:
    total = max(0, int(seconds or 0))
    hours = total // 3600
    minutes = (total % 3600) // 60
    secs = total % 60
    return f"{hours:02d}:{minutes:02d}:{secs:02d}"


def _priority_rank(priority: str) -> int:
    normalized = str(priority or "").strip().lower()
    if normalized in {"urgent", "critical", "kritisk"}:
        return 3
    if normalized in {"high", "høj"}:
        return 2
    if normalized in {"normal", "medium", "middel"}:
        return 1
    return 0


def _table_exists(table_name: str) -> bool:
    row = execute_query_single(
        """
        SELECT EXISTS(
            SELECT 1
            FROM information_schema.tables
            WHERE table_schema = 'public' AND table_name = %s
        ) AS exists
        """,
        (table_name,),
    )
    return bool((row or {}).get("exists"))


def _table_columns(table_name: str) -> List[str]:
    rows = execute_query(
        """
        SELECT column_name
        FROM information_schema.columns
        WHERE table_schema = 'public' AND table_name = %s
        """,
        (table_name,),
    ) or []
    return [str(r.get("column_name") or "").strip().lower() for r in rows if r.get("column_name")]


def _get_user_group_names(user_id: Optional[int]) -> List[str]:
    if user_id is None:
        return []
    rows = execute_query(
        """
        SELECT LOWER(g.name) AS name
        FROM user_groups ug
        JOIN groups g ON g.id = ug.group_id
        WHERE ug.user_id = %s
        """,
        (user_id,),
    ) or []
    return [str(r.get("name") or "").strip() for r in rows if r.get("name")]


def _can_view_boss_tab(user_id: Optional[int]) -> bool:
    if user_id is None:
        return False

    group_names = _get_user_group_names(user_id)
    if not group_names:
        # Fail-open for authenticated users if group mapping is missing.
        return True

    leadership_tokens = (
        "admin",
        "manager",
        "leder",
        "chef",
        "teknik",
        "technician",
        "support",
        "drift",
        "it",
    )
    return any(
        any(token in group for token in leadership_tokens)
        for group in group_names
    )


def is_bottom_bar_enabled(user_id: Optional[int]) -> bool:
    setting = execute_query_single("SELECT value FROM settings WHERE key = %s", ("bottom_bar_enabled",))
    setting_value = str((setting or {}).get("value") or "").strip().lower()
    if setting_value not in {"1", "true", "yes", "on"}:
        return False

    if user_id is None:
        return True

    pref = execute_query_single(
        """
        SELECT enabled
        FROM user_module_preferences
        WHERE user_id = %s AND module_name = %s
        LIMIT 1
        """,
        (user_id, "bottom_bar"),
    )
    if pref and pref.get("enabled") is not None:
        return bool(pref.get("enabled"))

    role = execute_query_single(
        """
        SELECT mrs.enabled
        FROM module_role_settings mrs
        JOIN user_groups ug ON ug.group_id = mrs.group_id
        WHERE ug.user_id = %s
          AND mrs.module_name = %s
        ORDER BY mrs.enabled DESC
        LIMIT 1
        """,
        (user_id, "bottom_bar"),
    )
    if role and role.get("enabled") is not None:
        return bool(role.get("enabled"))

    return True


def get_dashboard_status() -> Dict[str, int]:
    mails_unread = _safe_count(
        execute_query_single(
            """
            SELECT COUNT(*) AS count
            FROM email_messages
            WHERE deleted_at IS NULL
              AND COALESCE(is_read, FALSE) = FALSE
            """
        )
    )

    sager_open = _safe_count(
        execute_query_single(
            """
            SELECT COUNT(*) AS count
            FROM sag_sager
            WHERE deleted_at IS NULL
              AND LOWER(COALESCE(status, '')) NOT IN ('lukket', 'løst', 'closed', 'resolved')
            """
        )
    )

    sager_urgent = _safe_count(
        execute_query_single(
            """
            SELECT COUNT(*) AS count
            FROM sag_sager
            WHERE deleted_at IS NULL
              AND LOWER(COALESCE(status, '')) NOT IN ('lukket', 'løst', 'closed', 'resolved')
              AND LOWER(COALESCE(priority::text, 'normal')) IN ('urgent', 'high', 'kritisk', 'critical')
            """
        )
    )

    sager_unassigned = _safe_count(
        execute_query_single(
            """
            SELECT COUNT(*) AS count
            FROM sag_sager
            WHERE deleted_at IS NULL
              AND LOWER(COALESCE(status, '')) NOT IN ('lukket', 'løst', 'closed', 'resolved')
              AND ansvarlig_bruger_id IS NULL
            """
        )
    )

    return {
        "mails_unread": mails_unread,
        "sager_open": sager_open,
        "sager_urgent": sager_urgent,
        "sager_unassigned": sager_unassigned,
    }


def get_active_timer(user_id: Optional[int]) -> Dict[str, Any]:
    if user_id is None:
        return {
            "active": False,
            "sag_id": None,
            "sag_navn": None,
            "start_tid": None,
            "elapsed": 0,
            "elapsed_hhmmss": "00:00:00",
            "time_entry_id": None,
        }

    timer = execute_query_single(
        """
        SELECT
            t.id,
            t.sag_id,
            s.titel AS sag_navn,
            t.start_tid,
            GREATEST(EXTRACT(EPOCH FROM (NOW() - t.start_tid))::int, 0) AS elapsed
        FROM tmodule_times t
        LEFT JOIN sag_sager s ON s.id = t.sag_id
        WHERE t.medarbejder_id = %s
          AND t.aktiv_timer = TRUE
          AND t.slut_tid IS NULL
        ORDER BY t.start_tid DESC NULLS LAST, t.id DESC
        LIMIT 1
        """,
        (user_id,),
    )

    if not timer:
        return {
            "active": False,
            "sag_id": None,
            "sag_navn": None,
            "start_tid": None,
            "elapsed": 0,
            "elapsed_hhmmss": "00:00:00",
            "time_entry_id": None,
        }

    elapsed = int(timer.get("elapsed") or 0)
    return {
        "active": True,
        "sag_id": timer.get("sag_id"),
        "sag_navn": timer.get("sag_navn"),
        "start_tid": timer.get("start_tid"),
        "elapsed": elapsed,
        "elapsed_hhmmss": _format_elapsed(elapsed),
        "time_entry_id": timer.get("id"),
    }


def get_own_timer_snapshot(user_id: Optional[int], paused_limit: int = 10) -> Dict[str, Any]:
    active = get_active_timer(user_id)
    if user_id is None:
        return {
            "active": active,
            "paused": [],
            "counts": {"active": 0, "paused": 0, "total": 0},
        }

    paused_limit_safe = max(1, min(int(paused_limit or 10), 25))
    paused_rows = execute_query(
        """
        SELECT
            t.id,
            t.sag_id,
            s.titel AS sag_navn,
            t.start_tid,
            t.slut_tid,
            GREATEST(
                EXTRACT(EPOCH FROM (NOW() - COALESCE(t.start_tid, NOW())))::int,
                0
            ) AS elapsed_seconds,
            COALESCE(t.pause_total_seconds, 0)::int AS pause_total_seconds
        FROM tmodule_times t
        LEFT JOIN sag_sager s ON s.id = t.sag_id
        WHERE t.medarbejder_id = %s
          AND t.aktiv_timer = FALSE
          AND t.paused_at IS NOT NULL
          AND t.slut_tid IS NULL
        ORDER BY COALESCE(t.paused_at, t.updated_at, t.created_at) DESC, t.id DESC
        LIMIT %s
        """,
        (user_id, paused_limit_safe),
    ) or []

    paused_count_row = execute_query_single(
        """
        SELECT COUNT(*)::int AS count
        FROM tmodule_times t
        WHERE t.medarbejder_id = %s
          AND t.aktiv_timer = FALSE
                    AND t.paused_at IS NOT NULL
                    AND t.slut_tid IS NULL
        """,
        (user_id,),
    )
    paused_count = _safe_count(paused_count_row)
    active_count = 1 if active.get("active") else 0

    return {
        "active": active,
        "paused": [
            {
                "time_entry_id": row.get("id"),
                "sag_id": row.get("sag_id"),
                "sag_navn": row.get("sag_navn") or f"Sag #{row.get('sag_id')}",
                "start_tid": row.get("start_tid"),
                "slut_tid": row.get("slut_tid"),
                "faktisk_tid_min": 0,
                "elapsed_hhmmss": _format_elapsed(
                    max(0, int(row.get("elapsed_seconds") or 0) - int(row.get("pause_total_seconds") or 0))
                ),
            }
            for row in paused_rows
        ],
        "counts": {
            "active": active_count,
            "paused": paused_count,
            "total": active_count + paused_count,
        },
    }


def get_unassigned_open_cases(limit: int = 25) -> Dict[str, Any]:
    limit_safe = max(1, min(int(limit or 25), 100))
    rows = execute_query(
        """
        SELECT
            s.id,
            s.titel,
            s.priority,
            s.created_at,
            s.updated_at
        FROM sag_sager s
        WHERE s.deleted_at IS NULL
          AND LOWER(COALESCE(s.status, '')) NOT IN ('lukket', 'løst', 'closed', 'resolved')
          AND s.ansvarlig_bruger_id IS NULL
        ORDER BY COALESCE(s.updated_at, s.created_at) DESC, s.id DESC
        LIMIT %s
        """,
        (limit_safe,),
    ) or []

    count_row = execute_query_single(
        """
        SELECT COUNT(*)::int AS count
        FROM sag_sager s
        WHERE s.deleted_at IS NULL
          AND LOWER(COALESCE(s.status, '')) NOT IN ('lukket', 'løst', 'closed', 'resolved')
          AND s.ansvarlig_bruger_id IS NULL
        """
    )

    return {
        "items": [
            {
                "id": row.get("id"),
                "title": row.get("titel") or f"Sag #{row.get('id')}",
                "priority": row.get("priority") or "normal",
                "created_at": row.get("created_at"),
                "updated_at": row.get("updated_at"),
            }
            for row in rows
        ],
        "count": _safe_count(count_row),
        "filter_meta": {
            "route": "/api/v1/bottom-bar/boss/unassigned-cases",
            "query": {"limit": limit_safe, "only_open": True, "only_unassigned": True},
            "sql_guarantee": [
                "s.deleted_at IS NULL",
                "LOWER(COALESCE(s.status, '')) NOT IN ('lukket', 'løst', 'closed', 'resolved')",
                "s.ansvarlig_bruger_id IS NULL",
            ],
        },
    }


def _get_recent_cases(user_id: Optional[int], limit: int = 10) -> Dict[str, Any]:
    limit_safe = max(1, min(int(limit or 10), 20))

    source = "direct_query"
    rows: List[Dict[str, Any]] = []

    if _table_exists("sag_recent_cases"):
        columns = set(_table_columns("sag_recent_cases"))
        has_required = {"sag_id", "user_id"}.issubset(columns)
        if has_required:
            order_column = "viewed_at" if "viewed_at" in columns else "opened_at" if "opened_at" in columns else "updated_at" if "updated_at" in columns else "created_at"
            if order_column:
                source = "sag_recent_cases"
                rows = execute_query(
                    f"""
                    SELECT
                        s.id,
                        s.titel,
                        s.priority,
                        s.status,
                        rc.{order_column} AS recent_at
                    FROM sag_recent_cases rc
                    JOIN sag_sager s ON s.id = rc.sag_id
                    WHERE s.deleted_at IS NULL
                      AND LOWER(COALESCE(s.status, '')) NOT IN ('lukket', 'løst', 'closed', 'resolved')
                      AND rc.user_id = %s
                    ORDER BY rc.{order_column} DESC, s.id DESC
                    LIMIT %s
                    """,
                    (user_id, limit_safe),
                ) or []

    if not rows and user_id is not None:
        source = "direct_query_user_timers"
        rows = execute_query(
            """
            SELECT
                s.id,
                s.titel,
                s.priority,
                s.status,
                MAX(COALESCE(t.start_tid, t.updated_at, t.created_at)) AS recent_at
            FROM tmodule_times t
            JOIN sag_sager s ON s.id = t.sag_id
            WHERE t.medarbejder_id = %s
              AND s.deleted_at IS NULL
              AND LOWER(COALESCE(s.status, '')) NOT IN ('lukket', 'løst', 'closed', 'resolved')
            GROUP BY s.id, s.titel, s.priority, s.status
            ORDER BY recent_at DESC, s.id DESC
            LIMIT %s
            """,
            (user_id, limit_safe),
        ) or []

    if not rows:
        source = "direct_query_global"
        rows = execute_query(
            """
            SELECT
                s.id,
                s.titel,
                s.priority,
                s.status,
                COALESCE(s.updated_at, s.created_at) AS recent_at
            FROM sag_sager s
            WHERE s.deleted_at IS NULL
              AND LOWER(COALESCE(s.status, '')) NOT IN ('lukket', 'løst', 'closed', 'resolved')
            ORDER BY COALESCE(s.updated_at, s.created_at) DESC, s.id DESC
            LIMIT %s
            """,
            (limit_safe,),
        ) or []

    return {
        "source": source,
        "items": [
            {
                "id": row.get("id"),
                "title": row.get("titel") or f"Sag #{row.get('id')}",
                "priority": row.get("priority") or "normal",
                "status": row.get("status"),
                "recent_at": row.get("recent_at"),
            }
            for row in rows
        ],
        "count": len(rows),
    }


def get_notifications(user_id: Optional[int], limit: int = 20) -> Dict[str, Any]:
    if user_id is None:
        return {"items": [], "count": 0}

    limit_safe = max(1, min(int(limit or 20), 100))

    reminders = execute_query(
        """
        SELECT
            r.id,
            r.sag_id,
            r.title,
            r.message,
            r.priority,
            r.event_type,
            r.next_check_at,
            s.titel AS case_title,
            c.name AS customer_name
        FROM sag_reminders r
        JOIN sag_sager s ON r.sag_id = s.id
        JOIN customers c ON s.customer_id = c.id
        LEFT JOIN LATERAL (
            SELECT id, snoozed_until, status, triggered_at
            FROM sag_reminder_logs
            WHERE reminder_id = r.id AND user_id = %s
            ORDER BY triggered_at DESC
            LIMIT 1
        ) l ON true
        WHERE r.is_active = TRUE
          AND r.deleted_at IS NULL
          AND r.next_check_at <= CURRENT_TIMESTAMP
          AND %s = ANY(r.recipient_user_ids)
          AND (l.snoozed_until IS NULL OR l.snoozed_until < CURRENT_TIMESTAMP)
          AND (l.status IS NULL OR l.status != 'dismissed')
        ORDER BY
          CASE LOWER(COALESCE(r.priority::text, 'normal'))
            WHEN 'urgent' THEN 1
            WHEN 'high' THEN 2
            WHEN 'normal' THEN 3
            ELSE 4
          END,
          r.next_check_at ASC
        LIMIT %s
        """,
        (user_id, user_id, limit_safe),
    ) or []

    unread_mail_count = _safe_count(
        execute_query_single(
            """
            SELECT COUNT(*) AS count
            FROM email_messages em
            WHERE em.deleted_at IS NULL
              AND COALESCE(em.is_read, FALSE) = FALSE
            """
        )
    )

    items: List[Dict[str, Any]] = []

    if unread_mail_count > 0:
        items.append(
            {
                "id": f"mail-unread-{unread_mail_count}",
                "type": "mail",
                "severity": "medium" if unread_mail_count < 10 else "high",
                "title": f"{unread_mail_count} ulæste mails",
                "message": "Der er ulæste mails i indbakken",
                "action": "/emails",
                "created_at": datetime.now(timezone.utc).isoformat(),
            }
        )

    for row in reminders:
        priority = str(row.get("priority") or "normal").lower()
        severity = "low"
        if priority in {"high", "høj"}:
            severity = "medium"
        if priority in {"urgent", "critical", "kritisk"}:
            severity = "high"

        items.append(
            {
                "id": f"reminder-{row.get('id')}",
                "type": row.get("event_type") or "reminder",
                "severity": severity,
                "title": row.get("title") or "Påmindelse",
                "message": row.get("message") or row.get("case_title") or "",
                "sag_id": row.get("sag_id"),
                "case_title": row.get("case_title"),
                "customer_name": row.get("customer_name"),
                "action": f"/sag/{row.get('sag_id')}/v3" if row.get("sag_id") else "/sag",
                "created_at": row.get("next_check_at"),
            }
        )

    items.sort(
        key=lambda item: (
            {"high": 0, "medium": 1, "low": 2}.get(str(item.get("severity") or "low"), 3),
            str(item.get("created_at") or ""),
        )
    )

    return {"items": items[:limit_safe], "count": len(items)}


def _context_actions_for_path(context_path: str) -> Dict[str, Any]:
    normalized = str(context_path or "").strip().lower()

    payload: Dict[str, Any] = {
        "context_key": "global",
        "global": [
            {"id": "new_case", "label": "Ny sag", "action": "/sag"},
            {"id": "new_mail", "label": "Ny mail", "action": "/emails"},
            {"id": "start_timer", "label": "Start timer", "action": "/timetracking"},
            {"id": "log_time", "label": "Log tid", "action": "/timetracking"},
            {"id": "add_note", "label": "Tilføj note", "action": "/sag"},
        ],
        "context": [],
    }

    if normalized.startswith("/sag"):
        payload["context_key"] = "sag"
        payload["context"] = [
            {"id": "case_time", "label": "Tid", "action": "/timetracking"},
            {"id": "case_mail", "label": "Mail", "action": "/emails"},
            {"id": "case_relation", "label": "Relation", "action": "/customers"},
            {"id": "case_tag", "label": "Tag", "action": "/tags"},
        ]
    elif normalized.startswith("/hardware"):
        payload["context_key"] = "hardware"
        payload["context"] = [
            {"id": "hardware_new", "label": "Ny enhed", "action": "/hardware"},
            {"id": "hardware_history", "label": "Historik", "action": "/hardware"},
            {"id": "hardware_link_case", "label": "Tilknyt sag", "action": "/sag"},
        ]

    return payload


def get_user_notes_summary(user_id: Optional[int], limit: int = 10) -> Dict[str, Any]:
    if user_id is None:
        return {"count": 0, "list": []}

    limit_safe = max(1, min(int(limit or 10), 50))
    rows = execute_query(
        """
        SELECT
            id,
            title,
            content,
            is_pinned,
            is_archived,
            created_at,
            updated_at
        FROM user_notes
        WHERE user_id = %s
          AND deleted_at IS NULL
          AND is_archived = FALSE
        ORDER BY is_pinned DESC, updated_at DESC, id DESC
        LIMIT %s
        """,
        (user_id, limit_safe),
    ) or []

    total_row = execute_query_single(
        """
        SELECT COUNT(*) AS count
        FROM user_notes
        WHERE user_id = %s
          AND deleted_at IS NULL
          AND is_archived = FALSE
        """,
        (user_id,),
    )

    return {
        "count": _safe_count(total_row),
        "list": [
            {
                "id": row.get("id"),
                "title": row.get("title") or "",
                "content": row.get("content") or "",
                "is_pinned": bool(row.get("is_pinned")),
                "is_archived": bool(row.get("is_archived")),
                "created_at": row.get("created_at"),
                "updated_at": row.get("updated_at"),
            }
            for row in rows
        ],
    }


def build_bottom_bar_state(
    user_id: Optional[int],
    context_path: str = "",
    force_boss_access: bool = False,
) -> Dict[str, Any]:
    enabled = is_bottom_bar_enabled(user_id)
    if not enabled:
        return {"enabled": False, "sections": {}}

    status = get_dashboard_status()
    timer = get_active_timer(user_id)
    own_timers = get_own_timer_snapshot(user_id, paused_limit=10)
    notifications = get_notifications(user_id, limit=10)
    unassigned_open_cases = get_unassigned_open_cases(limit=8)
    recent_cases = _get_recent_cases(user_id, limit=10)
    notes_summary = get_user_notes_summary(user_id, limit=10)

    urgent_cases = execute_query(
        """
        SELECT id, titel
        FROM sag_sager
        WHERE deleted_at IS NULL
          AND LOWER(COALESCE(status, '')) NOT IN ('lukket', 'løst', 'closed', 'resolved')
          AND LOWER(COALESCE(priority::text, 'normal')) IN ('urgent', 'high', 'kritisk', 'critical')
        ORDER BY updated_at DESC NULLS LAST, id DESC
        LIMIT 5
        """
    ) or []

    open_cases = execute_query(
        """
        SELECT id, titel
        FROM sag_sager
        WHERE deleted_at IS NULL
          AND LOWER(COALESCE(status, '')) NOT IN ('lukket', 'løst', 'closed', 'resolved')
        ORDER BY updated_at DESC NULLS LAST, id DESC
        LIMIT 5
        """
    ) or []

    timer_list: List[Dict[str, Any]] = []
    if timer.get("active"):
        timer_list.append(
            {
                "id": timer.get("time_entry_id"),
                "sag_id": timer.get("sag_id"),
                "desc": timer.get("sag_navn") or f"Sag #{timer.get('sag_id')}",
                "elapsed": timer.get("elapsed"),
                "elapsed_hhmmss": timer.get("elapsed_hhmmss"),
            }
        )

    messages = [
        {
            "from": "System",
            "text": f"{notifications.get('count', 0)} aktive notifikationer",
        }
    ]

    tasks = []
    for n in (notifications.get("items") or [])[:5]:
        tasks.append(
            {
                "title": n.get("title") or "Notifikation",
                "deadline": n.get("severity") or "info",
                "action": n.get("action") or "/",
            }
        )

    context_actions = _context_actions_for_path(context_path)
    can_view_boss = bool(force_boss_access) or _can_view_boss_tab(user_id)

    team_workload: List[Dict[str, Any]] = []
    technicians_today: List[Dict[str, Any]] = []
    escalation_cases: List[Dict[str, Any]] = []
    unassigned_cases: List[Dict[str, Any]] = []

    if can_view_boss:
        team_workload = execute_query(
            """
            SELECT
                u.user_id,
                COALESCE(NULLIF(u.full_name, ''), u.username, ('Bruger #' || u.user_id::text)) AS owner_name,
                COUNT(s.id)::int AS open_cases,
                COUNT(CASE WHEN LOWER(COALESCE(s.priority::text, 'normal')) IN ('urgent', 'high', 'kritisk', 'critical') THEN 1 END)::int AS urgent_cases
            FROM users u
            LEFT JOIN sag_sager s
              ON s.ansvarlig_bruger_id = u.user_id
             AND s.deleted_at IS NULL
             AND LOWER(COALESCE(s.status, '')) NOT IN ('lukket', 'løst', 'closed', 'resolved')
            GROUP BY u.user_id, u.full_name, u.username
            HAVING COUNT(s.id) > 0
            ORDER BY urgent_cases DESC, open_cases DESC, owner_name ASC
            LIMIT 8
            """
        ) or []

        technicians_today = execute_query(
            """
            SELECT
                u.user_id,
                COALESCE(NULLIF(u.full_name, ''), u.username, ('Bruger #' || u.user_id::text)) AS owner_name,
                COUNT(s.id)::int AS open_cases,
                COUNT(CASE WHEN s.deadline::date = CURRENT_DATE THEN 1 END)::int AS due_today_cases,
                COALESCE(
                    (
                        SELECT json_agg(
                            json_build_object(
                                'id', t.id,
                                'title', t.titel,
                                'priority', COALESCE(t.priority::text, 'normal'),
                                'deadline', t.deadline
                            )
                            ORDER BY
                                CASE WHEN t.deadline::date = CURRENT_DATE THEN 0 ELSE 1 END,
                                COALESCE(t.deadline, t.updated_at, t.created_at) ASC,
                                t.id ASC
                        )
                        FROM (
                            SELECT s2.id, s2.titel, s2.priority, s2.deadline, s2.updated_at, s2.created_at
                            FROM sag_sager s2
                            WHERE s2.ansvarlig_bruger_id = u.user_id
                              AND s2.deleted_at IS NULL
                              AND LOWER(COALESCE(s2.status, '')) NOT IN ('lukket', 'løst', 'closed', 'resolved')
                              AND (
                                s2.deadline::date = CURRENT_DATE
                                OR s2.created_at::date = CURRENT_DATE
                              )
                            ORDER BY
                                CASE WHEN s2.deadline::date = CURRENT_DATE THEN 0 ELSE 1 END,
                                COALESCE(s2.deadline, s2.updated_at, s2.created_at) ASC,
                                s2.id ASC
                            LIMIT 6
                        ) t
                    ),
                    '[]'::json
                ) AS today_tasks
            FROM users u
            LEFT JOIN sag_sager s
              ON s.ansvarlig_bruger_id = u.user_id
             AND s.deleted_at IS NULL
             AND LOWER(COALESCE(s.status, '')) NOT IN ('lukket', 'løst', 'closed', 'resolved')
            WHERE EXISTS (
                SELECT 1
                FROM user_groups ug
                JOIN groups g ON g.id = ug.group_id
                WHERE ug.user_id = u.user_id
                  AND LOWER(g.name) LIKE ANY(ARRAY['%teknik%', '%technician%', '%support%'])
            )
            GROUP BY u.user_id, u.full_name, u.username
            ORDER BY due_today_cases DESC, open_cases DESC, owner_name ASC
            LIMIT 10
            """
        ) or []

        escalation_cases = execute_query(
            """
            SELECT
                s.id,
                s.titel,
                s.priority,
                s.updated_at,
                EXTRACT(EPOCH FROM (NOW() - COALESCE(s.updated_at, s.created_at)))::int AS age_seconds,
                COALESCE(NULLIF(u.full_name, ''), u.username, 'Ikke tildelt') AS owner_name
            FROM sag_sager s
            LEFT JOIN users u ON u.user_id = s.ansvarlig_bruger_id
            WHERE s.deleted_at IS NULL
              AND LOWER(COALESCE(s.status, '')) NOT IN ('lukket', 'løst', 'closed', 'resolved')
              AND LOWER(COALESCE(s.priority::text, 'normal')) IN ('urgent', 'high', 'kritisk', 'critical')
              AND NOW() - COALESCE(s.updated_at, s.created_at) > INTERVAL '24 hours'
            ORDER BY COALESCE(s.updated_at, s.created_at) ASC
            LIMIT 8
            """
        ) or []

        unassigned_cases = [
            {
                "id": row.get("id"),
                "titel": row.get("title"),
                "priority": row.get("priority"),
            }
            for row in (unassigned_open_cases.get("items") or [])
        ]

    sections = {
        "mail": {
            "unread": status.get("mails_unread", 0),
            "customer_reply_needed": status.get("mails_unread", 0),
        },
        "cases": {
            "open": status.get("sager_open", 0),
            "list": [{"id": row.get("id"), "title": row.get("titel") or f"Sag #{row.get('id')}"} for row in open_cases],
        },
        "urgent": {
            "count": status.get("sager_urgent", 0),
            "list": [{"id": row.get("id"), "title": row.get("titel") or f"Sag #{row.get('id')}"} for row in urgent_cases],
        },
        "unassigned": {
            "count": status.get("sager_unassigned", 0),
            "list": unassigned_open_cases.get("items") or [],
            "filter_meta": unassigned_open_cases.get("filter_meta") or {},
        },
        "timer": {
            "active_count": 1 if timer.get("active") else 0,
            "list": timer_list,
            "active": timer,
            "own": own_timers,
            "switch_case_hooks": {
                "fetch_own_active_paused_timers": {
                    "route": "/api/v1/bottom-bar/timers/own",
                    "method": "GET",
                    "query": {"paused_limit": 10},
                },
                "switch_case_start_timer": {
                    "route": "/api/v1/timetracking/time/start",
                    "method": "POST",
                    "payload": {
                        "sag_id": "required:int",
                        "medarbejder_id": "optional:int",
                        "beskrivelse": "optional:string",
                    },
                },
            },
        },
        "kuma": {
            "down": 0,
            "list": [],
        },
        "eset": {
            "incidents": 0,
            "list": [],
        },
        "messages": {
            "count": len(messages),
            "list": messages,
        },
        "tasks": {
            "count": len(tasks),
            "list": tasks,
        },
        "recent_cases": recent_cases,
        "notes": notes_summary,
        "boss": {
            "can_view": can_view_boss,
            "stats": {
                "unassigned": status.get("sager_unassigned", 0),
                "active_employees": _safe_count(
                    execute_query_single(
                        "SELECT COUNT(*) AS count FROM tmodule_times WHERE aktiv_timer = TRUE AND slut_tid IS NULL"
                    )
                ),
                "open_cases": status.get("sager_open", 0),
                "urgent_cases": status.get("sager_urgent", 0),
                "stale_urgent_cases": len(escalation_cases),
            }
            ,
            "team_workload": [
                {
                    "user_id": row.get("user_id"),
                    "owner_name": row.get("owner_name"),
                    "open_cases": int(row.get("open_cases") or 0),
                    "urgent_cases": int(row.get("urgent_cases") or 0),
                }
                for row in team_workload
            ],
            "technicians_today": [
                {
                    "user_id": row.get("user_id"),
                    "owner_name": row.get("owner_name"),
                    "open_cases": int(row.get("open_cases") or 0),
                    "due_today_cases": int(row.get("due_today_cases") or 0),
                    "today_tasks": row.get("today_tasks") or [],
                }
                for row in technicians_today
            ],
            "escalations": [
                {
                    "id": row.get("id"),
                    "title": row.get("titel") or f"Sag #{row.get('id')}",
                    "priority": row.get("priority") or "normal",
                    "owner_name": row.get("owner_name") or "Ikke tildelt",
                    "age_seconds": int(row.get("age_seconds") or 0),
                }
                for row in escalation_cases
            ],
            "unassigned_cases": [
                {
                    "id": row.get("id"),
                    "title": row.get("titel") or f"Sag #{row.get('id')}",
                    "priority": row.get("priority") or "normal",
                }
                for row in unassigned_cases
            ],
        },
        "context_actions": context_actions,
    }

    return {
        "enabled": True,
        "sections": sections,
        "status": status,
        "active_timer": timer,
        "own_timers": own_timers,
        "recent_cases": recent_cases,
        "notifications": notifications,
    }
