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, customElement, html, state, css, cssManager, } from '@design.estate/dees-element';
import {} from '@design.estate/dees-catalog';
let OpsViewSecurityBlocked = (() => {
    let _classDecorators = [customElement('ops-view-security-blocked')];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = DeesElement;
    let _securityPolicyState_decorators;
    let _securityPolicyState_initializers = [];
    let _securityPolicyState_extraInitializers = [];
    var OpsViewSecurityBlocked = class extends _classSuper {
        static { _classThis = this; }
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _securityPolicyState_decorators = [state()];
            __esDecorate(this, null, _securityPolicyState_decorators, { kind: "accessor", name: "securityPolicyState", static: false, private: false, access: { has: obj => "securityPolicyState" in obj, get: obj => obj.securityPolicyState, set: (obj, value) => { obj.securityPolicyState = value; } }, metadata: _metadata }, _securityPolicyState_initializers, _securityPolicyState_extraInitializers);
            __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
            OpsViewSecurityBlocked = _classThis = _classDescriptor.value;
            if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        #securityPolicyState_accessor_storage = __runInitializers(this, _securityPolicyState_initializers, appstate.securityPolicyStatePart.getState());
        get securityPolicyState() { return this.#securityPolicyState_accessor_storage; }
        set securityPolicyState(value) { this.#securityPolicyState_accessor_storage = value; }
        constructor() {
            super();
            __runInitializers(this, _securityPolicyState_extraInitializers);
            const sub = appstate.securityPolicyStatePart
                .select((s) => s)
                .subscribe((s) => {
                this.securityPolicyState = s;
            });
            this.rxSubscriptions.push(sub);
        }
        async connectedCallback() {
            await super.connectedCallback();
            await appstate.securityPolicyStatePart.dispatchAction(appstate.fetchSecurityPolicyAction, null);
        }
        static styles = [
            cssManager.defaultStyles,
            viewHostCss,
            css `
      dees-statsgrid {
        margin-bottom: 32px;
      }

      .sectionStack {
        display: flex;
        flex-direction: column;
        gap: 32px;
      }

      .statusBadge {
        display: inline-flex;
        align-items: center;
        padding: 4px 8px;
        border-radius: 4px;
        font-size: 12px;
        font-weight: 500;
      }

      .statusBadge.enabled {
        background: ${cssManager.bdTheme('#e8f5e9', '#1a3a1a')};
        color: ${cssManager.bdTheme('#388e3c', '#66bb6a')};
      }

      .statusBadge.disabled {
        background: ${cssManager.bdTheme('#f5f5f5', '#2a2a2a')};
        color: ${cssManager.bdTheme('#757575', '#999')};
      }

      .typeBadge {
        display: inline-flex;
        align-items: center;
        padding: 4px 8px;
        border-radius: 999px;
        font-size: 12px;
        font-weight: 500;
        background: ${cssManager.bdTheme('#eef2ff', '#1e1b4b')};
        color: ${cssManager.bdTheme('#4338ca', '#a5b4fc')};
      }

      .errorMessage {
        padding: 12px 16px;
        border-radius: 8px;
        background: ${cssManager.bdTheme('#fef2f2', '#450a0a')};
        color: ${cssManager.bdTheme('#b91c1c', '#fca5a5')};
      }
    `,
        ];
        render() {
            const state = this.securityPolicyState;
            const activeRules = state.rules.filter((rule) => rule.enabled);
            const disabledRules = state.rules.length - activeRules.length;
            const compiledPolicy = state.compiledPolicy || { blockedIps: [], blockedCidrs: [] };
            const tiles = [
                {
                    id: 'activeRules',
                    title: 'Active Rules',
                    value: activeRules.length,
                    type: 'number',
                    icon: 'lucide:shield-check',
                    color: activeRules.length > 0 ? '#ef4444' : '#22c55e',
                    description: `${disabledRules} disabled`,
                },
                {
                    id: 'compiledIps',
                    title: 'Compiled IPs',
                    value: compiledPolicy.blockedIps.length,
                    type: 'number',
                    icon: 'lucide:server-off',
                    color: '#ef4444',
                    description: 'Direct IP blocks enforced by SmartProxy',
                },
                {
                    id: 'compiledCidrs',
                    title: 'Compiled CIDRs',
                    value: compiledPolicy.blockedCidrs.length,
                    type: 'number',
                    icon: 'lucide:network',
                    color: '#f97316',
                    description: 'Network ranges pushed to enforcement layers',
                },
                {
                    id: 'intelligenceRecords',
                    title: 'IP Intelligence',
                    value: state.ipIntelligence.length,
                    type: 'number',
                    icon: 'lucide:radar',
                    color: '#6366f1',
                    description: 'Observed public IPs with enrichment',
                },
            ];
            return html `
      <dees-heading level="3">Security Blocking</dees-heading>

      ${state.error ? html `<div class="errorMessage">${state.error}</div>` : html ``}

      <dees-statsgrid
        .tiles=${tiles}
        .minTileWidth=${200}
      ></dees-statsgrid>

      <div class="sectionStack">
        ${this.renderRulesTable()}
        ${this.renderCompiledPolicyTable()}
        ${this.renderIpIntelligenceTable()}
        ${this.renderAuditTable()}
      </div>
    `;
        }
        renderRulesTable() {
            return html `
      <dees-table
        .heading1=${'Managed Block Rules'}
        .heading2=${'Rules compiled into SmartProxy policy and remote ingress edge firewall snapshots'}
        .data=${this.securityPolicyState.rules}
        .rowKey=${'id'}
        .displayFunction=${(rule) => ({
                'Type': html `<span class="typeBadge">${rule.type}</span>`,
                'Value': rule.value,
                'Match': rule.type === 'organization' ? (rule.matchMode || 'contains') : '-',
                'Reason': rule.reason || '-',
                'Status': html `<span class="statusBadge ${rule.enabled ? 'enabled' : 'disabled'}">${rule.enabled ? 'Enabled' : 'Disabled'}</span>`,
                'Created': this.formatDateTime(rule.createdAt),
                'Updated': this.formatDateTime(rule.updatedAt),
            })}
        .dataActions=${this.getRuleActions()}
        searchable
        .showColumnFilters=${true}
        dataName="rule"
      ></dees-table>
    `;
        }
        renderCompiledPolicyTable() {
            const policy = this.securityPolicyState.compiledPolicy || { blockedIps: [], blockedCidrs: [] };
            const rows = [
                ...policy.blockedIps.map((value) => ({ type: 'ip', value })),
                ...policy.blockedCidrs.map((value) => ({ type: 'cidr', value })),
            ];
            return html `
      <dees-table
        .heading1=${'Compiled Enforcement Policy'}
        .heading2=${'Concrete IPs and CIDRs currently sent to SmartProxy and remote ingress'}
        .data=${rows}
        .rowKey=${'value'}
        .displayFunction=${(row) => ({
                'Enforcement Type': html `<span class="typeBadge">${row.type}</span>`,
                'Value': row.value,
            })}
        searchable
        .showColumnFilters=${true}
        dataName="compiled rule"
      ></dees-table>
    `;
        }
        renderIpIntelligenceTable() {
            return html `
      <dees-table
        .heading1=${'Observed IP Intelligence'}
        .heading2=${'Public IPs observed in network metrics and enriched for ASN / organization matching'}
        .data=${this.securityPolicyState.ipIntelligence}
        .rowKey=${'ipAddress'}
        .displayFunction=${(record) => ({
                'IP Address': record.ipAddress,
                'ASN': record.asn ? `AS${record.asn}` : '-',
                'ASN Org': record.asnOrg || '-',
                'Registrant Org': record.registrantOrg || '-',
                'Country': record.countryCode || record.country || '-',
                'Network Range': record.networkRange || '-',
                'Abuse Contact': record.abuseContact || '-',
                'Seen': record.seenCount,
                'Last Seen': this.formatDateTime(record.lastSeenAt),
            })}
        .dataActions=${this.getIpIntelligenceActions()}
        searchable
        .showColumnFilters=${true}
        dataName="ip intelligence record"
      ></dees-table>
    `;
        }
        renderAuditTable() {
            return html `
      <dees-table
        .heading1=${'Policy Audit'}
        .heading2=${'Recent security policy changes'}
        .data=${this.securityPolicyState.auditEvents}
        .rowKey=${'id'}
        .displayFunction=${(event) => ({
                'Time': this.formatDateTime(event.createdAt),
                'Action': event.action,
                'Actor': event.actor,
                'Details': this.formatAuditDetails(event.details),
            })}
        searchable
        .showColumnFilters=${true}
        dataName="audit event"
      ></dees-table>
    `;
        }
        getRuleActions() {
            return [
                {
                    name: 'Create Rule',
                    iconName: 'lucide:plus',
                    type: ['header'],
                    actionFunc: async () => this.showRuleDialog(),
                },
                {
                    name: 'Edit',
                    iconName: 'lucide:pencil',
                    type: ['inRow', 'contextmenu'],
                    actionFunc: async (actionData) => this.showRuleDialog(actionData.item),
                },
                {
                    name: 'Enable',
                    iconName: 'lucide:play',
                    type: ['contextmenu'],
                    actionRelevancyCheckFunc: (actionData) => !actionData.item.enabled,
                    actionFunc: async (actionData) => {
                        const rule = actionData.item;
                        await appstate.securityPolicyStatePart.dispatchAction(appstate.updateSecurityBlockRuleAction, {
                            id: rule.id,
                            enabled: true,
                        });
                    },
                },
                {
                    name: 'Disable',
                    iconName: 'lucide:pause',
                    type: ['contextmenu'],
                    actionRelevancyCheckFunc: (actionData) => actionData.item.enabled,
                    actionFunc: async (actionData) => {
                        const rule = actionData.item;
                        await appstate.securityPolicyStatePart.dispatchAction(appstate.updateSecurityBlockRuleAction, {
                            id: rule.id,
                            enabled: false,
                        });
                    },
                },
                {
                    name: 'Delete',
                    iconName: 'lucide:trash-2',
                    type: ['contextmenu'],
                    actionFunc: async (actionData) => {
                        const rule = actionData.item;
                        if (!window.confirm(`Delete block rule ${rule.type}:${rule.value}?`))
                            return;
                        await appstate.securityPolicyStatePart.dispatchAction(appstate.deleteSecurityBlockRuleAction, rule.id);
                    },
                },
            ];
        }
        getIpIntelligenceActions() {
            return [
                {
                    name: 'Refresh Intelligence',
                    iconName: 'lucide:refresh-cw',
                    type: ['inRow', 'contextmenu'],
                    actionFunc: async (actionData) => {
                        const record = actionData.item;
                        await appstate.securityPolicyStatePart.dispatchAction(appstate.refreshIpIntelligenceAction, record.ipAddress);
                    },
                },
                {
                    name: 'Block IP',
                    iconName: 'lucide:shield-ban',
                    type: ['contextmenu'],
                    actionFunc: async (actionData) => {
                        const record = actionData.item;
                        await this.showRuleDialog(undefined, {
                            type: 'ip',
                            value: record.ipAddress,
                            reason: 'Blocked from IP intelligence table',
                        });
                    },
                },
                {
                    name: 'Block Network Range',
                    iconName: 'lucide:network',
                    type: ['contextmenu'],
                    actionRelevancyCheckFunc: (actionData) => Boolean(actionData.item.networkRange),
                    actionFunc: async (actionData) => {
                        const record = actionData.item;
                        await this.showRuleDialog(undefined, {
                            type: 'cidr',
                            value: record.networkRange || '',
                            reason: 'Blocked network range from IP intelligence table',
                        });
                    },
                },
                {
                    name: 'Block ASN',
                    iconName: 'lucide:radio-tower',
                    type: ['contextmenu'],
                    actionRelevancyCheckFunc: (actionData) => Boolean(actionData.item.asn),
                    actionFunc: async (actionData) => {
                        const record = actionData.item;
                        await this.showRuleDialog(undefined, {
                            type: 'asn',
                            value: String(record.asn),
                            reason: 'Blocked ASN from IP intelligence table',
                        });
                    },
                },
                {
                    name: 'Block Organization',
                    iconName: 'lucide:building-2',
                    type: ['contextmenu'],
                    actionRelevancyCheckFunc: (actionData) => Boolean(actionData.item.asnOrg || actionData.item.registrantOrg),
                    actionFunc: async (actionData) => {
                        const record = actionData.item;
                        await this.showRuleDialog(undefined, {
                            type: 'organization',
                            value: record.asnOrg || record.registrantOrg || '',
                            reason: 'Blocked organization from IP intelligence table',
                        });
                    },
                },
            ];
        }
        async showRuleDialog(rule, defaults = {}) {
            const { DeesModal } = await import('@design.estate/dees-catalog');
            const typeOptions = [
                { key: 'ip', option: 'IP address' },
                { key: 'cidr', option: 'CIDR / network range' },
                { key: 'asn', option: 'ASN' },
                { key: 'organization', option: 'Organization' },
            ];
            const matchModeOptions = [
                { key: 'contains', option: 'Organization contains value' },
                { key: 'exact', option: 'Organization exactly matches value' },
            ];
            const selectedType = rule?.type || defaults.type || 'ip';
            const selectedMatchMode = rule?.matchMode || defaults.matchMode || 'contains';
            await DeesModal.createAndShow({
                heading: rule ? `Edit Block Rule: ${rule.type}:${rule.value}` : 'Create Block Rule',
                content: html `
        <dees-form>
          ${rule ? html `` : html `
            <dees-input-dropdown
              .key=${'type'}
              .label=${'Rule Type'}
              .options=${typeOptions}
              .selectedOption=${typeOptions.find((option) => option.key === selectedType)}
            ></dees-input-dropdown>
          `}
          <dees-input-text
            .key=${'value'}
            .label=${'Value'}
            .value=${rule?.value || defaults.value || ''}
            .required=${true}
          ></dees-input-text>
          <dees-input-dropdown
            .key=${'matchMode'}
            .label=${'Organization Match Mode'}
            .description=${'Only used for organization rules'}
            .options=${matchModeOptions}
            .selectedOption=${matchModeOptions.find((option) => option.key === selectedMatchMode)}
          ></dees-input-dropdown>
          <dees-input-text
            .key=${'reason'}
            .label=${'Reason'}
            .value=${rule?.reason || defaults.reason || ''}
          ></dees-input-text>
          <dees-input-checkbox
            .key=${'enabled'}
            .label=${'Enabled'}
            .value=${rule ? rule.enabled : defaults.enabled !== false}
          ></dees-input-checkbox>
        </dees-form>
      `,
                menuOptions: [
                    { name: 'Cancel', iconName: 'lucide:x', action: async (modalArg) => modalArg.destroy() },
                    {
                        name: rule ? 'Save' : 'Create',
                        iconName: rule ? 'lucide:check' : 'lucide:plus',
                        action: async (modalArg) => {
                            const form = modalArg.shadowRoot?.querySelector('.content')?.querySelector('dees-form');
                            if (!form)
                                return;
                            const data = await form.collectFormData();
                            const type = (rule?.type || this.getDropdownKey(data.type));
                            const value = String(data.value || '').trim();
                            if (!type || !value)
                                return;
                            const matchMode = type === 'organization'
                                ? this.getDropdownKey(data.matchMode)
                                : undefined;
                            const payload = {
                                value,
                                matchMode,
                                reason: String(data.reason || '').trim() || undefined,
                                enabled: data.enabled !== false,
                            };
                            if (rule) {
                                await appstate.securityPolicyStatePart.dispatchAction(appstate.updateSecurityBlockRuleAction, {
                                    id: rule.id,
                                    ...payload,
                                });
                            }
                            else {
                                await appstate.securityPolicyStatePart.dispatchAction(appstate.createSecurityBlockRuleAction, {
                                    type,
                                    ...payload,
                                });
                            }
                            await modalArg.destroy();
                        },
                    },
                ],
            });
        }
        getDropdownKey(value) {
            return typeof value === 'string' ? value : value?.key || '';
        }
        formatDateTime(timestamp) {
            return timestamp ? new Date(timestamp).toLocaleString() : '-';
        }
        formatAuditDetails(details) {
            const text = JSON.stringify(details);
            return text.length > 160 ? `${text.slice(0, 157)}...` : text;
        }
        static {
            __runInitializers(_classThis, _classExtraInitializers);
        }
    };
    return OpsViewSecurityBlocked = _classThis;
})();
export { OpsViewSecurityBlocked };
//# sourceMappingURL=data:application/json;base64, 