var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __decorateClass = (decorators, target, key, kind) => {
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
    if (decorator = decorators[i])
      result = (kind ? decorator(target, key, result) : decorator(result)) || result;
  if (kind && result) __defProp(target, key, result);
  return result;
};
/**
 * @license
 * Copyright 2025-2026 Open Home Foundation
 * SPDX-License-Identifier: Apache-2.0
 */
import { mdiFitToScreen, mdiMagnifyMinus, mdiMagnifyPlus, mdiPause, mdiPlay } from "@mdi/js";
import { css, html, LitElement } from "lit";
import { customElement, property, query, state } from "lit/decorators.js";
import "../components/ha-svg-icon";
import "./components/footer";
import "./components/header";
import "./network/device-panel";
import "./network/network-details";
import "./network/thread-graph";
import "./network/wifi-graph";
let MatterNetworkView = class extends LitElement {
  constructor() {
    super(...arguments);
    this.nodes = {};
    this.networkType = "thread";
    this.initialSelectedNodeId = null;
    this._selectedNodeId = null;
    this._physicsEnabled = true;
    this._threadAddressSearch = "";
    this._threadAddressSearchStatus = "idle";
    this._initialSelectionApplied = false;
  }
  willUpdate(changedProperties) {
    if (changedProperties.has("initialSelectedNodeId") && this.initialSelectedNodeId !== null) {
      this._selectedNodeId = this.initialSelectedNodeId;
      this._initialSelectionApplied = false;
    }
  }
  updated(changedProperties) {
    super.updated(changedProperties);
    if (!this._initialSelectionApplied && this.initialSelectedNodeId !== null) {
      this._initialSelectionApplied = true;
      this._selectNodeWhenReady(this.initialSelectedNodeId);
    }
  }
  disconnectedCallback() {
    super.disconnectedCallback();
    if (this._selectRetryTimer) {
      clearTimeout(this._selectRetryTimer);
    }
  }
  /**
   * Tries to select a node in the graph, retrying until the graph is ready.
   */
  _selectNodeWhenReady(nodeId, retries = 10) {
    const graph = this.networkType === "thread" ? this._threadGraph : this._wifiGraph;
    if (graph?.isReady()) {
      graph.selectNode(nodeId);
    } else if (retries > 0) {
      this._selectRetryTimer = setTimeout(() => this._selectNodeWhenReady(nodeId, retries - 1), 100);
    }
  }
  _handleNodeSelected(event) {
    this._selectedNodeId = event.detail.nodeId;
  }
  _handleDetailsClose() {
    this._selectedNodeId = null;
  }
  _handleSelectNode(event) {
    const nodeId = event.detail.nodeId;
    this._selectedNodeId = nodeId;
    if (this.networkType === "thread") {
      this._threadGraph?.selectNode(nodeId);
    } else {
      this._wifiGraph?.selectNode(nodeId);
    }
  }
  _handleFitToScreen() {
    if (this.networkType === "thread") {
      this._threadGraph?.fit();
    } else {
      this._wifiGraph?.fit();
    }
  }
  _handleZoomIn() {
    if (this.networkType === "thread") {
      this._threadGraph?.zoomIn();
    } else {
      this._wifiGraph?.zoomIn();
    }
  }
  _handleZoomOut() {
    if (this.networkType === "thread") {
      this._threadGraph?.zoomOut();
    } else {
      this._wifiGraph?.zoomOut();
    }
  }
  _handleTogglePhysics() {
    const newState = !this._physicsEnabled;
    this._physicsEnabled = newState;
    this._threadGraph?.setPhysicsEnabled(newState);
    this._wifiGraph?.setPhysicsEnabled(newState);
  }
  _handlePhysicsChanged(event) {
    this._physicsEnabled = event.detail.enabled;
    this._threadGraph?.setPhysicsEnabled(event.detail.enabled);
    this._wifiGraph?.setPhysicsEnabled(event.detail.enabled);
  }
  _handleThreadAddressSearchInput(event) {
    this._threadAddressSearch = event.target.value;
    this._threadAddressSearchStatus = "idle";
  }
  _handleThreadAddressSearchSubmit(event) {
    event.preventDefault();
    const searchValue = this._threadAddressSearch.trim();
    if (!searchValue) {
      this._threadAddressSearchStatus = "idle";
      return;
    }
    this._searchThreadAddressWhenReady(searchValue);
  }
  _searchThreadAddressWhenReady(searchValue, retries = 10) {
    const graph = this._threadGraph;
    if (!graph?.isReady()) {
      if (retries > 0) {
        this._selectRetryTimer = setTimeout(
          () => this._searchThreadAddressWhenReady(searchValue, retries - 1),
          100
        );
      } else {
        this._threadAddressSearchStatus = "not-found";
      }
      return;
    }
    const found = graph.selectByExtendedAddress(searchValue);
    this._threadAddressSearchStatus = found ? "found" : "not-found";
  }
  _renderThreadView() {
    return html`
            <div class="graph-section">
                <div class="graph-header">
                    <h2>Thread Network Mesh</h2>
                    <div class="graph-actions">
                        <form class="thread-search" @submit=${this._handleThreadAddressSearchSubmit}>
                            <input
                                type="text"
                                .value=${this._threadAddressSearch}
                                @input=${this._handleThreadAddressSearchInput}
                                placeholder="Search extended address"
                                title="Find device by Thread extended address (EUI-64)"
                            />
                            <button type="submit" class="search-button">Find</button>
                        </form>
                        <div class="graph-controls">
                            <button class="control-button" @click=${this._handleZoomIn} title="Zoom in">
                                <ha-svg-icon .path=${mdiMagnifyPlus}></ha-svg-icon>
                            </button>
                            <button class="control-button" @click=${this._handleZoomOut} title="Zoom out">
                                <ha-svg-icon .path=${mdiMagnifyMinus}></ha-svg-icon>
                            </button>
                            <button class="control-button" @click=${this._handleFitToScreen} title="Fit to screen">
                                <ha-svg-icon .path=${mdiFitToScreen}></ha-svg-icon>
                            </button>
                            <button
                                class="control-button ${this._physicsEnabled ? "" : "active"}"
                                @click=${this._handleTogglePhysics}
                                title="${this._physicsEnabled ? "Freeze layout" : "Unfreeze layout"}"
                            >
                                <ha-svg-icon .path=${this._physicsEnabled ? mdiPause : mdiPlay}></ha-svg-icon>
                            </button>
                        </div>
                    </div>
                </div>
                ${this._threadAddressSearchStatus === "idle" ? "" : html`<div class="thread-search-status ${this._threadAddressSearchStatus}">
                          ${this._threadAddressSearchStatus === "found" ? "Node highlighted." : "No matching extended address found."}
                      </div>`}
                <thread-graph
                    .nodes=${this.nodes}
                    @node-selected=${this._handleNodeSelected}
                    @physics-changed=${this._handlePhysicsChanged}
                ></thread-graph>
            </div>
        `;
  }
  _renderWifiView() {
    return html`
            <div class="graph-section">
                <div class="graph-header">
                    <h2>WiFi Network</h2>
                    <div class="graph-controls">
                        <button class="control-button" @click=${this._handleZoomIn} title="Zoom in">
                            <ha-svg-icon .path=${mdiMagnifyPlus}></ha-svg-icon>
                        </button>
                        <button class="control-button" @click=${this._handleZoomOut} title="Zoom out">
                            <ha-svg-icon .path=${mdiMagnifyMinus}></ha-svg-icon>
                        </button>
                        <button class="control-button" @click=${this._handleFitToScreen} title="Fit to screen">
                            <ha-svg-icon .path=${mdiFitToScreen}></ha-svg-icon>
                        </button>
                        <button
                            class="control-button ${this._physicsEnabled ? "" : "active"}"
                            @click=${this._handleTogglePhysics}
                            title="${this._physicsEnabled ? "Freeze layout" : "Unfreeze layout"}"
                        >
                            <ha-svg-icon .path=${this._physicsEnabled ? mdiPause : mdiPlay}></ha-svg-icon>
                        </button>
                    </div>
                </div>
                <wifi-graph
                    .nodes=${this.nodes}
                    @node-selected=${this._handleNodeSelected}
                    @physics-changed=${this._handlePhysicsChanged}
                ></wifi-graph>
            </div>
        `;
  }
  render() {
    const showSidebar = this._selectedNodeId !== null;
    const unknownDevices = this._threadGraph?.unknownDevicesMap ?? /* @__PURE__ */ new Map();
    const wifiAccessPoints = this._wifiGraph?.wifiAccessPointsMap ?? /* @__PURE__ */ new Map();
    return html`
            <dashboard-header
                title="Open Home Foundation Matter Server"
                .client=${this.client}
                .activeView=${this.activeView}
                .hasThreadDevices=${this.hasThreadDevices}
                .hasWifiDevices=${this.hasWifiDevices}
            ></dashboard-header>

            <div class="content">
                <div class="main-area">
                    ${this.networkType === "thread" ? this._renderThreadView() : this._renderWifiView()}
                </div>

                <aside class="details-sidebar ${showSidebar ? "visible" : ""}">
                    <network-details
                        .selectedNodeId=${this._selectedNodeId}
                        .nodes=${this.nodes}
                        .unknownDevices=${unknownDevices}
                        .wifiAccessPoints=${wifiAccessPoints}
                        @close=${this._handleDetailsClose}
                        @select-node=${this._handleSelectNode}
                    ></network-details>
                </aside>
            </div>

            <dashboard-footer></dashboard-footer>
        `;
  }
};
MatterNetworkView.styles = css`
        :host {
            display: flex;
            flex-direction: column;
            height: 100vh;
            height: 100dvh; /* dynamic viewport height - fallback above for older browsers */
            overflow: hidden;
            background-color: var(--md-sys-color-background, #fafafa);
        }

        .content {
            display: flex;
            flex: 1 1 0;
            padding: 8px 16px;
            gap: 8px;
            max-width: 1600px;
            margin: 0 auto;
            width: 100%;
            box-sizing: border-box;
            min-height: 0;
            overflow: hidden;
        }

        .main-area {
            flex: 1 1 0;
            display: flex;
            flex-direction: column;
            min-width: 0;
            min-height: 0;
            overflow: hidden;
        }

        .graph-section {
            flex: 1 1 0;
            min-height: 0;
            display: flex;
            flex-direction: column;
            overflow: hidden;
        }

        .graph-header {
            display: flex;
            align-items: center;
            justify-content: space-between;
            margin-bottom: 4px;
            flex-shrink: 0;
        }

        .graph-header h2 {
            margin: 0;
            font-size: 1.1rem;
            font-weight: 500;
            color: var(--md-sys-color-on-background, #333);
        }

        .graph-controls {
            display: flex;
            gap: 4px;
        }

        .graph-actions {
            display: flex;
            align-items: center;
            gap: 8px;
            min-width: 0;
        }

        .thread-search {
            display: flex;
            align-items: center;
            gap: 4px;
        }

        .thread-search input {
            width: 260px;
            max-width: 45vw;
            padding: 6px 8px;
            border: 1px solid var(--md-sys-color-outline-variant, #ccc);
            border-radius: 4px;
            background-color: var(--md-sys-color-surface, #fff);
            color: var(--md-sys-color-on-surface, #1c1b1f);
            font: inherit;
        }

        .thread-search input:focus {
            outline: 2px solid var(--md-sys-color-primary, #6750a4);
            outline-offset: 1px;
        }

        .search-button {
            padding: 6px 10px;
            border: 1px solid var(--md-sys-color-outline-variant, #ccc);
            border-radius: 4px;
            background-color: var(--md-sys-color-surface, #fff);
            color: var(--md-sys-color-on-surface, #1c1b1f);
            cursor: pointer;
            font: inherit;
        }

        .search-button:hover {
            background-color: var(--md-sys-color-surface-container-high, #e8e8e8);
        }

        .thread-search-status {
            margin: 0 0 6px;
            font-size: 0.85rem;
            color: var(--md-sys-color-on-surface-variant, #666);
        }

        .thread-search-status.found {
            color: #2e7d32;
        }

        .thread-search-status.not-found {
            color: #c62828;
        }

        .control-button {
            background: none;
            border: 1px solid var(--md-sys-color-outline-variant, #ccc);
            border-radius: 4px;
            padding: 6px;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            transition:
                background-color 0.2s,
                border-color 0.2s;
        }

        .control-button:hover {
            background-color: var(--md-sys-color-surface-container-high, #e8e8e8);
        }

        .control-button.active {
            background-color: var(--md-sys-color-primary-container, #e8def8);
            border-color: var(--md-sys-color-primary, #6750a4);
        }

        .control-button ha-svg-icon {
            --icon-primary-color: var(--md-sys-color-on-surface-variant, #666);
        }

        .control-button.active ha-svg-icon {
            --icon-primary-color: var(--md-sys-color-on-primary-container, #21005d);
        }

        .graph-section thread-graph,
        .graph-section wifi-graph {
            flex: 1 1 0;
            min-height: 0;
        }

        .wifi-section {
            display: flex;
            flex-direction: column;
            gap: 16px;
            overflow-y: auto;
        }

        .wifi-section h2 {
            margin: 0;
            font-size: 1.25rem;
            font-weight: 500;
            color: var(--md-sys-color-on-background, #333);
        }

        .wifi-section device-panel {
            flex-shrink: 0;
        }

        .details-sidebar {
            width: 320px;
            flex-shrink: 0;
            display: none;
            min-height: 0;
            overflow-y: auto;
        }

        .details-sidebar.visible {
            display: block;
        }

        @media (max-width: 1024px) {
            .content {
                flex-direction: column;
            }

            .details-sidebar {
                width: 100%;
                max-height: 300px;
            }

            .details-sidebar.visible {
                display: block;
            }
        }

        @media (max-width: 600px) {
            .content {
                padding: 8px;
            }

            .graph-header {
                align-items: flex-start;
                gap: 6px;
            }

            .graph-actions {
                flex-direction: column;
                align-items: stretch;
                width: 100%;
            }

            .thread-search {
                width: 100%;
            }

            .thread-search input {
                flex: 1 1 auto;
                width: auto;
                max-width: none;
            }

            .graph-controls {
                justify-content: flex-end;
            }
        }
    `;
__decorateClass([
  property({ type: Object })
], MatterNetworkView.prototype, "nodes", 2);
__decorateClass([
  property()
], MatterNetworkView.prototype, "activeView", 2);
__decorateClass([
  property()
], MatterNetworkView.prototype, "networkType", 2);
__decorateClass([
  property()
], MatterNetworkView.prototype, "initialSelectedNodeId", 2);
__decorateClass([
  property({ type: Boolean })
], MatterNetworkView.prototype, "hasThreadDevices", 2);
__decorateClass([
  property({ type: Boolean })
], MatterNetworkView.prototype, "hasWifiDevices", 2);
__decorateClass([
  state()
], MatterNetworkView.prototype, "_selectedNodeId", 2);
__decorateClass([
  state()
], MatterNetworkView.prototype, "_physicsEnabled", 2);
__decorateClass([
  state()
], MatterNetworkView.prototype, "_threadAddressSearch", 2);
__decorateClass([
  state()
], MatterNetworkView.prototype, "_threadAddressSearchStatus", 2);
__decorateClass([
  query("thread-graph")
], MatterNetworkView.prototype, "_threadGraph", 2);
__decorateClass([
  query("wifi-graph")
], MatterNetworkView.prototype, "_wifiGraph", 2);
MatterNetworkView = __decorateClass([
  customElement("matter-network-view")
], MatterNetworkView);
//# sourceMappingURL=matter-network-view.js.map
