var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
    function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
    var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
    var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
    var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
    var _, done = false;
    for (var i = decorators.length - 1; i >= 0; i--) {
        var context = {};
        for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
        for (var p in contextIn.access) context.access[p] = contextIn.access[p];
        context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
        var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
        if (kind === "accessor") {
            if (result === void 0) continue;
            if (result === null || typeof result !== "object") throw new TypeError("Object expected");
            if (_ = accept(result.get)) descriptor.get = _;
            if (_ = accept(result.set)) descriptor.set = _;
            if (_ = accept(result.init)) initializers.unshift(_);
        }
        else if (_ = accept(result)) {
            if (kind === "field") initializers.unshift(_);
            else descriptor[key] = _;
        }
    }
    if (target) Object.defineProperty(target, contextIn.name, descriptor);
    done = true;
};
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
    var useValue = arguments.length > 2;
    for (var i = 0; i < initializers.length; i++) {
        value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
    }
    return useValue ? value : void 0;
};
import * as plugins from '../plugins.js';
import * as shared from './shared/index.js';
import * as appstate from '../appstate.js';
import { appRouter } from '../router.js';
import { DeesElement, customElement, html, state, css, cssManager, } from '@design.estate/dees-element';
const byteUnits = ['B', 'KB', 'MB', 'GB', 'TB'];
function getByteUnitIndex(bytes) {
    if (!bytes || bytes === 0)
        return 0;
    return Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), byteUnits.length - 1);
}
function formatBytes(bytes, forcedUnitIndex) {
    if ((!bytes || bytes === 0) && forcedUnitIndex === undefined)
        return '0 B';
    const unitIndex = forcedUnitIndex ?? getByteUnitIndex(bytes);
    const value = bytes / Math.pow(1024, unitIndex);
    return `${value.toFixed(1)} ${byteUnits[unitIndex]}`;
}
let ObViewDashboard = (() => {
    let _classDecorators = [customElement('ob-view-dashboard')];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = DeesElement;
    let _systemState_decorators;
    let _systemState_initializers = [];
    let _systemState_extraInitializers = [];
    let _servicesState_decorators;
    let _servicesState_initializers = [];
    let _servicesState_extraInitializers = [];
    let _networkState_decorators;
    let _networkState_initializers = [];
    let _networkState_extraInitializers = [];
    var ObViewDashboard = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _systemState_decorators = [state()];
            _servicesState_decorators = [state()];
            _networkState_decorators = [state()];
            __esDecorate(this, null, _systemState_decorators, { kind: "accessor", name: "systemState", static: false, private: false, access: { has: obj => "systemState" in obj, get: obj => obj.systemState, set: (obj, value) => { obj.systemState = value; } }, metadata: _metadata }, _systemState_initializers, _systemState_extraInitializers);
            __esDecorate(this, null, _servicesState_decorators, { kind: "accessor", name: "servicesState", static: false, private: false, access: { has: obj => "servicesState" in obj, get: obj => obj.servicesState, set: (obj, value) => { obj.servicesState = value; } }, metadata: _metadata }, _servicesState_initializers, _servicesState_extraInitializers);
            __esDecorate(this, null, _networkState_decorators, { kind: "accessor", name: "networkState", static: false, private: false, access: { has: obj => "networkState" in obj, get: obj => obj.networkState, set: (obj, value) => { obj.networkState = value; } }, metadata: _metadata }, _networkState_initializers, _networkState_extraInitializers);
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            ObViewDashboard = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        #systemState_accessor_storage = __runInitializers(this, _systemState_initializers, {
            status: null,
            resource: { phase: 'idle', error: null, lastSuccessAt: null },
        });
        get systemState() { return this.#systemState_accessor_storage; }
        set systemState(value) { this.#systemState_accessor_storage = value; }
        #servicesState_accessor_storage = (__runInitializers(this, _systemState_extraInitializers), __runInitializers(this, _servicesState_initializers, {
            services: [],
            currentService: null,
            currentHostedAppLifecycle: null,
            currentServiceLogs: [],
            currentServiceStats: null,
            platformServices: [],
            currentPlatformService: null,
            currentPlatformServiceStats: null,
            currentPlatformServiceLogs: [],
        }));
        get servicesState() { return this.#servicesState_accessor_storage; }
        set servicesState(value) { this.#servicesState_accessor_storage = value; }
        #networkState_accessor_storage = (__runInitializers(this, _servicesState_extraInitializers), __runInitializers(this, _networkState_initializers, {
            targets: [],
            stats: null,
            statsResource: { phase: 'idle', error: null, lastSuccessAt: null },
            trafficStats: null,
            dnsRecords: [],
            domains: [],
            gatewayDomains: [],
            gatewayDnsRecords: [],
            certificates: [],
        }));
        get networkState() { return this.#networkState_accessor_storage; }
        set networkState(value) { this.#networkState_accessor_storage = value; }
        constructor() {
            super();
            __runInitializers(this, _networkState_extraInitializers);
            const systemSub = appstate.systemStatePart
                .select((s) => s)
                .subscribe((newState) => {
                this.systemState = newState;
            });
            this.rxSubscriptions.push(systemSub);
            const servicesSub = appstate.servicesStatePart
                .select((s) => s)
                .subscribe((newState) => {
                this.servicesState = newState;
            });
            this.rxSubscriptions.push(servicesSub);
            const networkSub = appstate.networkStatePart
                .select((s) => s)
                .subscribe((newState) => {
                this.networkState = newState;
            });
            this.rxSubscriptions.push(networkSub);
        }
        static styles = [
            cssManager.defaultStyles,
            shared.viewHostCss,
            css `
      .dashboard {
        display: flex;
        flex-direction: column;
        gap: 24px;
      }

      .section {
        display: flex;
        flex-direction: column;
      }

      .section-title {
        font-size: 18px;
        font-weight: 600;
        color: ${cssManager.bdTheme('#18181b', '#fafafa')};
        margin: 0 0 12px;
      }

      .services-grid {
        display: grid;
        grid-template-columns: 1fr;
        gap: 16px;
        align-items: stretch;
      }

      .services-grid > * {
        height: 100%;
      }


      .status-panel {
        padding: 18px;
        border: 1px solid ${cssManager.bdTheme('#e4e4e7', '#3f3f46')};
        border-radius: 10px;
        color: ${cssManager.bdTheme('#52525b', '#a1a1aa')};
        background: ${cssManager.bdTheme('#fafafa', '#18181b')};
      }

      .status-panel button {
        margin-left: 12px;
        padding: 6px 10px;
        border: 0;
        border-radius: 6px;
        cursor: pointer;
      }

      .stale-warning {
        margin-bottom: 10px;
        padding: 8px 10px;
        border-radius: 8px;
        color: ${cssManager.bdTheme('#92400e', '#fbbf24')};
        background: ${cssManager.bdTheme('#fffbeb', '#422006')};
      }
      @media (min-width: 768px) {
        .services-grid {
          grid-template-columns: 1fr 1fr;
        }
      }
    `,
        ];
        async connectedCallback() {
            super.connectedCallback();
            await Promise.allSettled([
                appstate.fetchSystemStatus(),
                appstate.dispatchProtectedAction(appstate.fetchServicesAction, null),
                appstate.dispatchProtectedAction(appstate.fetchPlatformServicesAction, null),
                appstate.fetchNetworkStats(),
                appstate.dispatchProtectedAction(appstate.fetchTrafficStatsAction, null),
                appstate.dispatchProtectedAction(appstate.fetchCertificatesAction, null),
            ]);
        }
        render() {
            const status = this.systemState.status;
            const services = this.servicesState.services;
            const platformServices = this.servicesState.platformServices;
            const networkStats = this.networkState.stats;
            const trafficStats = this.networkState.trafficStats;
            const certificates = this.networkState.certificates;
            const statusCounts = trafficStats?.statusCounts || {};
            const runningServices = services.filter((s) => s.status === 'running').length;
            const stoppedServices = services.filter((s) => s.status === 'stopped').length;
            const memoryUnitIndex = getByteUnitIndex(status?.docker?.memoryTotal || status?.docker?.memoryUsage || 0);
            const validCerts = certificates.filter((c) => c.isValid).length;
            const expiringCerts = certificates.filter((c) => c.isValid && c.expiryDate && c.expiryDate - Date.now() < 30 * 24 * 60 * 60 * 1000).length;
            const expiredCerts = certificates.filter((c) => !c.isValid).length;
            const dashboardData = {
                cluster: status ? {
                    totalServices: services.length,
                    running: runningServices,
                    stopped: stoppedServices,
                    dockerStatus: status.docker.running ? 'running' : 'stopped',
                } : null,
                resourceUsage: status ? {
                    cpu: status.docker.cpuUsage,
                    memoryUsed: formatBytes(status.docker.memoryUsage, memoryUnitIndex),
                    memoryTotal: formatBytes(status.docker.memoryTotal, memoryUnitIndex),
                    networkIn: formatBytes(status.docker.networkIn),
                    networkOut: formatBytes(status.docker.networkOut),
                    topConsumers: [],
                } : null,
                platformServices: platformServices
                    .filter((ps) => ps.status === 'running' || ps.status === 'starting' || ps.status === 'stopping' || ps.status === 'failed' || ps.isCore)
                    .map((ps) => ({
                    name: ps.displayName,
                    status: ps.status === 'running'
                        ? 'Running'
                        : ps.status === 'starting'
                            ? 'Starting...'
                            : ps.status === 'stopping'
                                ? 'Stopping...'
                                : ps.status === 'failed'
                                    ? 'Failed'
                                    : ps.status === 'unknown'
                                        ? 'Unavailable'
                                        : 'Stopped',
                    running: ps.status === 'running',
                })),
                traffic: {
                    requests: trafficStats?.requestCount || 0,
                    errors: trafficStats?.errorCount || 0,
                    errorPercent: trafficStats?.errorRate || 0,
                    avgResponse: trafficStats?.avgResponseTime || 0,
                    reqPerMin: trafficStats?.requestsPerMinute || 0,
                    status2xx: statusCounts['2xx'] || 0,
                    status3xx: statusCounts['3xx'] || 0,
                    status4xx: statusCounts['4xx'] || 0,
                    status5xx: statusCounts['5xx'] || 0,
                },
                proxy: networkStats
                    && networkStats.proxy.running !== null
                    && (networkStats.proxy.state === 'running' || networkStats.proxy.state === 'stopped')
                    ? {
                        httpPort: String(networkStats.proxy.httpPort),
                        httpsPort: String(networkStats.proxy.httpsPort),
                        httpActive: networkStats.proxy.running,
                        httpsActive: networkStats.proxy.running,
                        routeCount: String(networkStats.proxy.routes),
                    } : null,
                certificates: {
                    valid: validCerts,
                    expiring: expiringCerts,
                    expired: expiredCerts,
                },
                dnsConfigured: status?.dns?.configured || false,
                acmeConfigured: status?.ssl?.configured || false,
                quickActions: [
                    { label: 'Deploy Service', icon: 'lucide:Plus', primary: true },
                    { label: 'Add Domain', icon: 'lucide:Globe' },
                    { label: 'View Logs', icon: 'lucide:FileText' },
                ],
            };
            return html `
      <ob-sectionheading>Dashboard</ob-sectionheading>
      <div class="dashboard">
        <section class="section">
          <h2 class="section-title">Cluster Overview</h2>
          ${dashboardData.cluster
                ? html `<sz-status-grid-cluster .stats=${dashboardData.cluster}></sz-status-grid-cluster>`
                : html `
                <div class="status-panel">
                  ${this.systemState.resource.phase === 'loading'
                    ? 'Loading system status…'
                    : 'System status is unavailable.'}
                  <button @click=${() => void appstate.fetchSystemStatus()}>Retry</button>
                </div>
              `}
        </section>

        <section class="section">
          <h2 class="section-title">Services & Resources</h2>
          <div class="services-grid">
            ${dashboardData.resourceUsage
                ? html `<sz-resource-usage-card .data=${dashboardData.resourceUsage}></sz-resource-usage-card>`
                : html `
                  <div class="status-panel">
                    Resource usage is unavailable.
                    <button @click=${() => void appstate.fetchSystemStatus()}>Retry</button>
                  </div>
                `}
            <sz-platform-services-card
              .services=${dashboardData.platformServices}
              @service-click=${(e) => this.handlePlatformServiceClick(e)}
            ></sz-platform-services-card>
          </div>
        </section>

        <section class="section">
          <h2 class="section-title">Network & Traffic</h2>
          ${this.networkState.statsResource.phase === 'stale'
                ? html `<div class="stale-warning">Showing the last known proxy status. Refresh failed.</div>`
                : ''}
          ${dashboardData.proxy
                ? html `
                <sz-status-grid-network
                  .traffic=${dashboardData.traffic}
                  .proxy=${dashboardData.proxy}
                  .certificates=${dashboardData.certificates}
                ></sz-status-grid-network>
              `
                : html `
                <div class="status-panel">
                  ${networkStats?.proxy.state === 'failed'
                    ? 'Reverse proxy status: Failed.'
                    : networkStats?.proxy.state === 'starting'
                        ? 'Reverse proxy is starting…'
                        : this.networkState.statsResource.phase === 'loading'
                            ? 'Loading reverse proxy status…'
                            : 'Reverse proxy status is unavailable.'}
                  <button @click=${() => void appstate.fetchNetworkStats()}>Retry</button>
                </div>
              `}
        </section>

        <section class="section">
          <h2 class="section-title">Infrastructure</h2>
          <sz-status-grid-infra
            ?dnsConfigured=${dashboardData.dnsConfigured}
            ?acmeConfigured=${dashboardData.acmeConfigured}
            .actions=${dashboardData.quickActions}
            @action-click=${(e) => this.handleQuickAction(e)}
          ></sz-status-grid-infra>
        </section>
      </div>
    `;
        }
        handleQuickAction(e) {
            const action = e.detail?.action || e.detail?.label;
            if (action === 'Deploy Service') {
                appRouter.navigateToView('services');
            }
            else if (action === 'Add Domain') {
                appRouter.navigateToView('network');
            }
        }
        handlePlatformServiceClick(e) {
            // Find the platform service type from the click event
            const name = e.detail?.name;
            const ps = this.servicesState.platformServices.find((p) => p.displayName === name);
            if (ps) {
                // Navigate to services tab — the ObViewServices component will pick up the type
                // Store the selected platform type so the services view can open it
                appstate.servicesStatePart.setState({
                    ...appstate.getRequiredState(appstate.servicesStatePart),
                    currentPlatformService: ps,
                });
                appRouter.navigateToView('services');
            }
        }
        static {
            __runInitializers(_classThis, _classExtraInitializers);
        }
    };
    return ObViewDashboard = _classThis;
})();
export { ObViewDashboard };
//# sourceMappingURL=data:application/json;base64, 