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 appstate from '../../appstate.js';
import * as interfaces from '../../../dist_ts_interfaces/index.js';
import { viewHostCss } from '../shared/css.js';
import { DeesElement, css, cssManager, customElement, html, state, } from '@design.estate/dees-element';
let OpsViewGatewayClients = (() => {
    let _classDecorators = [customElement('ops-view-gatewayclients')];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = DeesElement;
    let _routeState_decorators;
    let _routeState_initializers = [];
    let _routeState_extraInitializers = [];
    var OpsViewGatewayClients = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _routeState_decorators = [state()];
            __esDecorate(this, null, _routeState_decorators, { kind: "accessor", name: "routeState", static: false, private: false, access: { has: obj => "routeState" in obj, get: obj => obj.routeState, set: (obj, value) => { obj.routeState = value; } }, metadata: _metadata }, _routeState_initializers, _routeState_extraInitializers);
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            OpsViewGatewayClients = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        #routeState_accessor_storage = __runInitializers(this, _routeState_initializers, {
            mergedRoutes: [],
            warnings: [],
            httpRedirects: [],
            apiTokens: [],
            gatewayClients: [],
            isLoading: false,
            error: null,
            lastUpdated: 0,
        });
        get routeState() { return this.#routeState_accessor_storage; }
        set routeState(value) { this.#routeState_accessor_storage = value; }
        constructor() {
            super();
            __runInitializers(this, _routeState_extraInitializers);
            const sub = appstate.routeManagementStatePart
                .select((s) => s)
                .subscribe((routeState) => {
                this.routeState = routeState;
            });
            this.rxSubscriptions.push(sub);
            const loginSub = appstate.loginStatePart
                .select((s) => s.isLoggedIn)
                .subscribe((isLoggedIn) => {
                if (isLoggedIn) {
                    appstate.routeManagementStatePart.dispatchAction(appstate.fetchGatewayClientsAction, null);
                }
            });
            this.rxSubscriptions.push(loginSub);
        }
        static styles = [
            cssManager.defaultStyles,
            viewHostCss,
            css `
      .pill {
        display: inline-flex;
        padding: 2px 6px;
        border-radius: 3px;
        font-size: 11px;
        background: ${cssManager.bdTheme('rgba(37, 99, 235, 0.1)', 'rgba(96, 165, 250, 0.14)')};
        color: ${cssManager.bdTheme('#1d4ed8', '#93c5fd')};
        margin-right: 4px;
        margin-bottom: 2px;
      }
    `,
        ];
        render() {
            return html `
      <dees-heading level="3">Gateway Clients</dees-heading>
      <dees-table
        .heading1=${'Gateway Clients'}
        .heading2=${'Create durable clients and token credentials for Onebox, Cloudly, or custom integrations'}
        .data=${this.routeState.gatewayClients}
        .dataName=${'gateway client'}
        .searchable=${true}
        .showColumnFilters=${true}
        .displayFunction=${(client) => ({
                name: client.name,
                id: client.id,
                type: client.type,
                hostnames: this.renderPills(client.hostnamePatterns),
                targets: this.renderTargets(client.allowedRouteTargets),
                tokens: client.tokenCount || 0,
                status: client.enabled ? 'Active' : 'Disabled',
            })}
        .dataActions=${[
                {
                    name: 'Create Client',
                    iconName: 'lucide:plus',
                    type: ['header'],
                    actionFunc: async () => await this.showCreateClientDialog(),
                },
                {
                    name: 'Create Token',
                    iconName: 'lucide:keyRound',
                    type: ['inRow', 'contextmenu'],
                    actionFunc: async (actionData) => await this.showCreateTokenDialog(actionData.item),
                },
                {
                    name: 'Enable',
                    iconName: 'lucide:play',
                    type: ['inRow', 'contextmenu'],
                    actionRelevancyCheckFunc: (actionData) => !actionData.item.enabled,
                    actionFunc: async (actionData) => {
                        await appstate.routeManagementStatePart.dispatchAction(appstate.updateGatewayClientAction, {
                            id: actionData.item.id,
                            enabled: true,
                        });
                    },
                },
                {
                    name: 'Disable',
                    iconName: 'lucide:pause',
                    type: ['inRow', 'contextmenu'],
                    actionRelevancyCheckFunc: (actionData) => actionData.item.enabled,
                    actionFunc: async (actionData) => {
                        await appstate.routeManagementStatePart.dispatchAction(appstate.updateGatewayClientAction, {
                            id: actionData.item.id,
                            enabled: false,
                        });
                    },
                },
                {
                    name: 'Delete',
                    iconName: 'lucide:trash2',
                    type: ['inRow', 'contextmenu'],
                    actionFunc: async (actionData) => {
                        await appstate.routeManagementStatePart.dispatchAction(appstate.deleteGatewayClientAction, actionData.item.id);
                    },
                },
            ]}
      ></dees-table>
    `;
        }
        renderPills(values) {
            if (!values.length)
                return html `<span>None</span>`;
            return html `${values.map((value) => html `<span class="pill">${value}</span>`)}`;
        }
        renderTargets(targets) {
            if (!targets.length)
                return html `<span>None</span>`;
            return html `${targets.map((target) => html `<span class="pill">${target.host}:${target.ports.join(',')}</span>`)}`;
        }
        async showCreateClientDialog() {
            const { DeesModal } = await import('@design.estate/dees-catalog');
            await DeesModal.createAndShow({
                heading: 'Create Gateway Client',
                content: html `
        <dees-form>
          <dees-input-text .key=${'name'} .label=${'Name'} .required=${true}></dees-input-text>
          <dees-input-text .key=${'type'} .label=${'Type'} .value=${'onebox'} .description=${'onebox, cloudly, or custom'}></dees-input-text>
          <dees-input-text .key=${'id'} .label=${'Client ID'} .description=${'Optional stable ID; generated when empty'}></dees-input-text>
          <dees-input-text .key=${'hostnamePatterns'} .label=${'Hostname Patterns'} .description=${'Comma separated, e.g. *.apps.example.com'}></dees-input-text>
          <dees-input-text .key=${'allowedRouteTarget'} .label=${'Allowed Route Target'} .description=${'Optional host:ports, e.g. onebox-smartproxy:80'}></dees-input-text>
          <dees-input-text .key=${'description'} .label=${'Description'}></dees-input-text>
        </dees-form>
      `,
                menuOptions: [
                    { name: 'Cancel', iconName: 'lucide:x', action: async (modalArg) => await modalArg.destroy() },
                    {
                        name: 'Create',
                        iconName: 'lucide:plus',
                        action: async (modalArg) => {
                            const form = modalArg.shadowRoot?.querySelector('.content')?.querySelector('dees-form');
                            if (!form)
                                return;
                            const formData = await form.collectFormData();
                            const name = String(formData.name || '').trim();
                            if (!name)
                                return;
                            await modalArg.destroy();
                            await appstate.createGatewayClient({
                                id: String(formData.id || '').trim() || undefined,
                                type: this.normalizeClientType(String(formData.type || 'onebox')),
                                name,
                                description: String(formData.description || '').trim() || undefined,
                                hostnamePatterns: this.parseList(String(formData.hostnamePatterns || '')),
                                allowedRouteTargets: this.parseAllowedRouteTargets(String(formData.allowedRouteTarget || '')),
                            });
                            await appstate.routeManagementStatePart.dispatchAction(appstate.fetchGatewayClientsAction, null);
                        },
                    },
                ],
            });
        }
        async showCreateTokenDialog(client) {
            const { DeesModal } = await import('@design.estate/dees-catalog');
            await DeesModal.createAndShow({
                heading: `Create Token for ${client.name}`,
                content: html `
        <div style="color: #888; margin-bottom: 12px; font-size: 13px;">
          The token will be shown once. Configure Onebox with the dcrouter URL and this token.
        </div>
        <dees-form>
          <dees-input-text .key=${'name'} .label=${'Token Name'} .value=${`${client.name} Token`}></dees-input-text>
          <dees-input-text .key=${'expiresInDays'} .label=${'Expires in'} .description=${'Number of days; leave blank for no expiration'}></dees-input-text>
        </dees-form>
      `,
                menuOptions: [
                    { name: 'Cancel', iconName: 'lucide:x', action: async (modalArg) => await modalArg.destroy() },
                    {
                        name: 'Create Token',
                        iconName: 'lucide:key',
                        action: async (modalArg) => {
                            const form = modalArg.shadowRoot?.querySelector('.content')?.querySelector('dees-form');
                            if (!form)
                                return;
                            const formData = await form.collectFormData();
                            const expiresInDays = formData.expiresInDays ? parseInt(formData.expiresInDays, 10) : null;
                            await modalArg.destroy();
                            const response = await appstate.createGatewayClientToken(client.id, String(formData.name || '').trim() || undefined, expiresInDays);
                            await appstate.routeManagementStatePart.dispatchAction(appstate.fetchGatewayClientsAction, null);
                            if (response.success && response.tokenValue) {
                                await DeesModal.createAndShow({
                                    heading: 'Gateway Client Token Created',
                                    content: html `
                  <p>Copy this token now. It will not be shown again.</p>
                  <div style="background: #111; padding: 12px; border-radius: 6px; margin-top: 8px;">
                    <code style="color: #0f8; word-break: break-all; font-size: 13px;">${response.tokenValue}</code>
                  </div>
                `,
                                    menuOptions: [
                                        { name: 'Done', iconName: 'lucide:check', action: async (m) => await m.destroy() },
                                    ],
                                });
                            }
                        },
                    },
                ],
            });
        }
        normalizeClientType(value) {
            const normalized = value.trim().toLowerCase();
            if (normalized === 'cloudly' || normalized === 'custom')
                return normalized;
            return 'onebox';
        }
        parseList(value) {
            return value.split(',').map((entry) => entry.trim()).filter(Boolean);
        }
        parseAllowedRouteTargets(value) {
            const target = value.trim();
            if (!target.includes(':'))
                return [];
            const [host, portsValue] = target.split(':');
            const ports = portsValue.split(',').map((port) => Number(port.trim())).filter((port) => Number.isInteger(port));
            return host.trim() && ports.length ? [{ host: host.trim(), ports }] : [];
        }
        static {
            __runInitializers(_classThis, _classExtraInitializers);
        }
    };
    return OpsViewGatewayClients = _classThis;
})();
export { OpsViewGatewayClients };
//# sourceMappingURL=data:application/json;base64, 