/*
Copyright 2023, 2024 New Vector Ltd.

SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/

import type { BrowserWindow } from "electron";

/**
 * Height of the styled title bar band, matching the design spec
 * (https://www.figma.com/design/MAUsalKv7bRRNKlAAigtNd/Community-contributions?node-id=76-12996).
 * The `trafficLightPosition` in `electron-main.ts` vertically centres the native window controls
 * within this band — keep the two in sync.
 */
export const TITLE_BAR_HEIGHT_PX = 32;

/**
 * Build the CSS injected into the renderer to draw the macOS title bar band.
 *
 * `electron-main.ts` uses `titleBarStyle: "hidden"`, which keeps the native window frame, rounded
 * corners and traffic lights but removes the native bar surface. This CSS paints that surface: a
 * full-width strip at the top of the window in the canvas background colour with a hairline
 * separator underneath, and pushes the app content below it. The strip is the window's drag
 * handle.
 *
 * The drag region is built from `-webkit-app-region` rects only: elements keep the default value
 * (`none`) and are ignored unless they explicitly set `drag`/`no-drag`. So the band stays draggable
 * underneath any overlay whose surface is transparent to the calc (a dialog's backdrop, a menu's
 * container), and an overlay panel that a user clicks (dialog panels, context menus, the lightbox
 * chrome) sets `no-drag` so its rect is subtracted and it stays interactive. An element must never
 * be both clickable and a drag handle.
 *
 * Extracted as a pure helper so the string contract can be unit-tested (see macos-titlebar.test.ts).
 */
export function buildTitleBarCss(): string {
    return `
            /* Reserve a band at the top of the window for the title bar */
            body {
                box-sizing: border-box;
                height: 100%;
                padding-top: ${TITLE_BAR_HEIGHT_PX}px !important;
            }

            /* The title bar itself: canvas background with a hairline separator below */
            body::before {
                content: "";
                position: fixed;
                top: 0;
                left: 0;
                right: 0;
                height: ${TITLE_BAR_HEIGHT_PX}px;
                box-sizing: border-box;
                /* Fallback colours for pages loaded without the app themes (e.g. the error view) */
                background: var(--cpd-color-bg-canvas-default, #ffffff);
                border-bottom: 1px solid var(--cpd-color-separator-primary, #e1e6ec);
                -webkit-app-region: drag;
                -webkit-user-select: none;
            }

            /* Exclude floating menus and tooltips, which render in body-level portals */
            [data-radix-popper-content-wrapper] {
                -webkit-app-region: no-drag;
            }

            /* The image lightbox covers the whole window, including the title bar band; keep its
               sender info clear of the traffic lights, and let its header double as a drag handle */
            .mx_ImageView_info_wrapper {
                margin-top: ${TITLE_BAR_HEIGHT_PX}px;
            }
            .mx_ImageView_panel {
                -webkit-app-region: drag;
            }
            /* Exclude header interactive elements from being drag handles */
            .mx_ImageView_panel > .mx_ImageView_info_wrapper,
            .mx_ImageView_panel > .mx_ImageView_title,
            .mx_ImageView_panel > .mx_ImageView_toolbar > * {
                -webkit-app-region: no-drag;
            }

            /* Exclude context menus and their backgrounds, which may open within the band */
            .mx_ContextualMenu, .mx_ContextualMenu_background {
                -webkit-app-region: no-drag;
            }
            /* Exclude iframes, such as recaptcha */
            iframe {
                -webkit-app-region: no-drag;
            }
        `;
}

export function setupMacosTitleBar(window: BrowserWindow): void {
    if (process.platform !== "darwin") return;

    let cssKey: string | undefined;

    async function applyStyling(): Promise<void> {
        cssKey = await window.webContents.insertCSS(buildTitleBarCss());
    }

    window.on("enter-full-screen", () => {
        if (cssKey !== undefined) {
            void window.webContents.removeInsertedCSS(cssKey);
        }
    });
    window.on("leave-full-screen", () => {
        void applyStyling();
    });
    window.webContents.on("did-finish-load", () => {
        if (!window.isFullScreen()) {
            void applyStyling();
        }
    });
}
