import{e as ae,aa as xe,r as i,j as e,cu as se,B as h,f as R,$ as x,dA as ne,c8 as he,bE as fe}from"./index-C4inJ1rU.js";import{P as je,a as ye,B as ge,C}from"./PageLayout-CdGXajgM.js";import{g as we,a as _e,u as ve}from"./maintenance-BzsxIVOE.js";import{r as be}from"./system-Yjyk7rn7.js";import{R as M,C as I}from"./Grid-rJkrpDAP.js";import{R as Ne}from"./rotate-cw-Cu8X-5qo.js";import{S as Se}from"./save-B_ndF54A.js";import{P as Ce}from"./plus-BvSKm1y6.js";import{T as Te}from"./trash-2-1fU70LRT.js";/**
 * @license lucide-react v0.559.0 - ISC
 *
 * This source code is licensed under the ISC license.
 * See the LICENSE file in the root directory of this source tree.
 */const Ee=[["line",{x1:"15",x2:"15",y1:"12",y2:"18",key:"1p7wdc"}],["line",{x1:"12",x2:"18",y1:"15",y2:"15",key:"1nscbv"}],["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]],Be=ae("copy-plus",Ee);/**
 * @license lucide-react v0.559.0 - ISC
 *
 * This source code is licensed under the ISC license.
 * See the LICENSE file in the root directory of this source tree.
 */const Re=[["rect",{width:"20",height:"8",x:"2",y:"2",rx:"2",ry:"2",key:"ngkwjq"}],["rect",{width:"20",height:"8",x:"2",y:"14",rx:"2",ry:"2",key:"iecqi9"}],["line",{x1:"6",x2:"6.01",y1:"6",y2:"6",key:"16zg32"}],["line",{x1:"6",x2:"6.01",y1:"18",y2:"18",key:"nzw8ys"}]],te=ae("server",Re),Me=["REQ","RESPONSE","TXT_MSG","ACK","ADVERT","GRP_TXT","GRP_DATA","ANON_REQ","PATH","TRACE","RAW_CUSTOM"];function Ie(t){const r=t==null?void 0:t.config;return(r==null?void 0:r.mqtt_brokers)??{}}let Pe=1;function P(t={}){var c,p;const r=t.disallowedInput??t.disallowed_packet_types??[];return{_id:Pe++,name:String(t.name??""),enabled:t.enabled??!0,host:String(t.host??""),port:Number(t.port??(t.transport==="tcp"?1883:443)),format:t.format??"letsmesh",transport:t.transport??"websockets",use_jwt_auth:t.use_jwt_auth??!1,audience:t.audience??"",username:t.username??"",password:t.password??"",base_topic:t.base_topic??"",retain_status:t.retain_status??!1,disallowedInput:[...r],disallowed_packet_types:[...r],tls:{enabled:((c=t.tls)==null?void 0:c.enabled)??t.transport!=="tcp",insecure:((p=t.tls)==null?void 0:p.insecure)??!1}}}function Ae(t){var c,p,_,v;const r={name:t.name.trim(),enabled:t.enabled,host:t.host.trim(),port:Number(t.port),format:t.format,transport:t.transport,use_jwt_auth:!!t.use_jwt_auth,disallowed_packet_types:t.disallowedInput,base_topic:((c=t.base_topic)==null?void 0:c.trim())||void 0,retain_status:!!t.retain_status,tls:{enabled:!!((p=t.tls)!=null&&p.enabled),insecure:!!((_=t.tls)!=null&&_.insecure)}};return t.use_jwt_auth?{...r,audience:((v=t.audience)==null?void 0:v.trim())||t.host.trim()}:{...r,username:t.username||"",password:t.password||""}}function qe(t){return t?t.connected?e.jsxs(x,{color:"green",children:[e.jsx(he,{className:"w-3 h-3"})," connected"]}):t.reconnecting?e.jsxs(x,{color:"amber",children:[e.jsx(ne,{className:"w-3 h-3"})," reconnecting"]}):e.jsxs(x,{color:"red",children:[e.jsx(fe,{className:"w-3 h-3"})," disconnected"]}):e.jsx(x,{color:"zinc",children:"unknown"})}function o({label:t,children:r}){return e.jsxs("label",{className:"block min-w-0",children:[e.jsx("span",{className:"type-data-xs text-fg-muted",children:t}),r]})}function u(t,r,c={}){return e.jsx("input",{...c,className:"mt-1 w-full min-w-0 surface-input radius-inner px-3 py-2 text-fg-primary",value:t,onChange:p=>r(p.target.value)})}function Ge(){var k;const t=xe(),r=i.useMemo(()=>Ie(t),[t]),[c,p]=i.useState(null),[_,v]=i.useState([]),[A,q]=i.useState(""),[O,Q]=i.useState(""),[l,y]=i.useState(!1),[T,z]=i.useState(!1),[E,$]=i.useState(!1),[b,F]=i.useState(!1),[L,N]=i.useState(""),[g,f]=i.useState(""),[H,U]=i.useState(""),[W,D]=i.useState(300),[G,V]=i.useState(""),[X,K]=i.useState(""),[S,j]=i.useState([]),B=()=>{U(r.iata_code??""),D(r.status_interval??300),V(r.owner??""),K(r.email??""),j((r.brokers??[]).map(P))};i.useEffect(()=>{l||B()},[r,l]);const w=async()=>{try{const s=await _e();if(s.success===!1)throw new Error(s.error||"MQTT status unavailable");p(s.data??null),q("")}catch(s){q(s instanceof Error?s.message:"MQTT status unavailable")}};i.useEffect(()=>{w();const s=window.setInterval(w,5e3);return()=>window.clearInterval(s)},[]),i.useEffect(()=>{we().then(s=>{if(s.success===!1)throw new Error(s.error||"Broker presets unavailable");v(s.data??[]),Q("")}).catch(s=>Q(s instanceof Error?s.message:"Broker presets unavailable"))},[]);const J=i.useMemo(()=>{const s=new Map;for(const n of(c==null?void 0:c.brokers)??[])s.set(`${n.name}|${n.host}`,n),s.set(n.host,n);return s},[c]),re=()=>{B(),y(!0),N(""),f("")},le=()=>{B(),y(!1),f("")},m=(s,n)=>{j(a=>a.map(d=>d._id===s?{...d,...n}:d))},Y=(s,n)=>{j(a=>a.map(d=>d._id===s?{...d,tls:{...d.tls,...n}}:d))},ie=(s,n)=>{j(a=>a.map(d=>{if(d._id!==s)return d;const ee=d.disallowedInput.includes(n)?d.disallowedInput.filter(pe=>pe!==n):[...d.disallowedInput,n];return{...d,disallowedInput:ee,disallowed_packet_types:ee}}))},ce=s=>{j(n=>[...n,P(s)]),y(!0)},de=s=>{j(n=>[...n,...s.brokers.map(P)]),y(!0)},oe=s=>{j(n=>n.filter(a=>a._id!==s))},me=async()=>{const s=S.find(n=>!n.name.trim()||!n.host.trim()||Number(n.port)<1||Number(n.port)>65535||n.use_jwt_auth&&!(n.audience||n.host).trim());if(s){f(`Broker ${s.name||s.host||s._id} is incomplete.`);return}z(!0),f(""),N("");try{const n=await ve({iata_code:H.trim(),status_interval:Math.max(60,Number(W)||300),owner:G.trim(),email:X.trim(),brokers:S.map(Ae)});if(n.success===!1)throw new Error(n.error||"Save failed");y(!1),$(!0),N("Observer/MQTT settings saved. Restart openhop-repeater for broker changes to take effect."),await w()}catch(n){f(n instanceof Error?n.message:"Save failed")}finally{z(!1)}},ue=async()=>{if(!b){F(!0),f("");try{await be(),N("Restart requested. The UI will reconnect after the service comes back."),$(!1),window.setTimeout(w,4e3)}catch(s){f(s instanceof Error?s.message:"Restart request failed")}finally{F(!1)}}},Z=(c==null?void 0:c.handler_active)??!1;return e.jsxs(je,{children:[e.jsx(ye,{title:"Observer",icon:e.jsx(se,{}),subtitle:e.jsx("p",{className:"type-body-sm text-fg-muted",children:"Manage the default Repeater observer publisher: IATA identity, broker presets, MQTT broker connections, and live handler status."})}),e.jsxs(ge,{ready:!0,children:[(E||L||g)&&e.jsx(M,{template:"auto",children:e.jsx(C,{neomorphic:!0,className:g?"border-sys-red/40 text-sys-red":"border-sys-amber/40 text-fg-secondary",children:e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs("div",{children:[e.jsx("p",{className:"type-body-sm font-medium",children:g?"Observer update failed":E?"Restart required":"Observer"}),e.jsx("p",{className:"type-body-sm text-fg-muted mt-1",children:g||L||"Saved observer broker changes need a service restart before new observers start."})]}),E&&!g&&e.jsxs(h,{color:"warning",outline:!0,onClick:ue,disabled:b,children:[e.jsx(Ne,{"data-slot":"icon",className:b?"animate-spin":void 0}),b?"Restarting…":"Restart Now"]})]})})}),e.jsxs(M,{template:"auto",children:[e.jsx(I,{span:12,md:4,children:e.jsxs(C,{children:[e.jsx(R,{icon:e.jsx(te,{className:"icon-sm"}),title:"Live MQTT Status"}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("span",{className:"type-data-xs text-fg-muted",children:"Handler"}),e.jsx(x,{color:Z?"green":"zinc",children:Z?"active":"inactive"})]}),e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("span",{className:"type-data-xs text-fg-muted",children:"Runtime brokers"}),e.jsx(x,{color:"cyan",children:((k=c==null?void 0:c.brokers)==null?void 0:k.length)??0})]}),A&&e.jsx("p",{className:"type-body-sm text-sys-amber",children:A}),e.jsxs(h,{plain:!0,onClick:w,className:"w-full justify-center",children:[e.jsx(ne,{"data-slot":"icon"})," Refresh status"]})]})]})}),e.jsx(I,{span:12,md:8,children:e.jsxs(C,{children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx(R,{icon:e.jsx(se,{className:"icon-sm"}),title:"Observer Setup"}),e.jsx("p",{className:"type-body-sm text-fg-muted",children:"These fields publish observer identity/status metadata to configured MC2MQTT brokers."})]}),e.jsx("div",{className:"flex gap-2",children:l?e.jsxs(e.Fragment,{children:[e.jsx(h,{plain:!0,onClick:le,disabled:T,children:"Cancel"}),e.jsxs(h,{color:"success",onClick:me,disabled:T,children:[e.jsx(Se,{"data-slot":"icon"})," ",T?"Saving…":"Save"]})]}):e.jsx(h,{color:"primary",onClick:re,children:"Edit Settings"})})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 mt-4",children:[e.jsx(o,{label:"IATA code",children:l?u(H,s=>U(s.toUpperCase()),{maxLength:10,placeholder:"SFO"}):e.jsx("p",{className:"type-data-sm text-fg-primary mt-1",children:r.iata_code||"—"})}),e.jsx(o,{label:"Status interval",children:l?u(W,s=>D(Number(s)),{type:"number",min:60,max:3600}):e.jsxs("p",{className:"type-data-sm text-fg-primary mt-1",children:[r.status_interval??300,"s"]})}),e.jsx(o,{label:"Owner companion pubkey",children:l?u(G,V,{placeholder:"Optional"}):e.jsx("p",{className:"type-data-sm text-fg-primary mt-1 break-all",children:r.owner||"—"})}),e.jsx(o,{label:"Email",children:l?u(X,K,{type:"email",placeholder:"Optional"}):e.jsx("p",{className:"type-data-sm text-fg-primary mt-1 break-all",children:r.email||"—"})})]})]})})]}),e.jsx(M,{template:"auto",children:e.jsx(I,{span:12,children:e.jsxs(C,{children:[e.jsxs("div",{className:"flex flex-col lg:flex-row lg:items-start lg:justify-between gap-4 mb-4",children:[e.jsxs("div",{children:[e.jsx(R,{icon:e.jsx(te,{className:"icon-sm"}),title:"MQTT Broker Management"}),e.jsx("p",{className:"type-body-sm text-fg-muted",children:"Configure the repeater-side observer publisher. This is separate from Console's browser-only Sources/MQTT subscriber page."})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[_.map(s=>e.jsxs(h,{plain:!0,onClick:()=>de(s),disabled:!l,title:s.website||void 0,children:[e.jsx(Be,{"data-slot":"icon"})," ",s.name]},s.id)),e.jsxs(h,{color:"primary",onClick:()=>ce(),disabled:!l,children:[e.jsx(Ce,{"data-slot":"icon"})," Add Broker"]})]})]}),O&&e.jsxs("p",{className:"type-body-sm text-sys-amber mb-3",children:["Broker presets unavailable: ",O]}),e.jsxs("div",{className:"space-y-4",children:[S.length===0&&e.jsx("div",{className:"rounded-xl border border-dashed border-edge-subtle p-5 text-center type-body-sm text-fg-muted",children:"No MQTT brokers configured. Click Edit Settings, then add a broker or choose a preset."}),S.map(s=>{const n=J.get(`${s.name}|${s.host}`)??J.get(s.host);return e.jsxs("div",{className:"rounded-xl border border-edge-subtle bg-surface/40 p-4 space-y-4",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[qe(n==null?void 0:n.status),e.jsx(x,{color:s.enabled?"green":"zinc",children:s.enabled?"enabled":"disabled"}),e.jsx(x,{color:"cyan",children:s.format}),e.jsx(x,{color:"zinc",children:s.transport})]}),l&&e.jsxs(h,{plain:!0,onClick:()=>oe(s._id),className:"text-sys-red hover:text-sys-red/80",children:[e.jsx(Te,{"data-slot":"icon"})," Remove"]})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-4 gap-3",children:[e.jsx(o,{label:"Name",children:l?u(s.name,a=>m(s._id,{name:a})):e.jsx("p",{className:"type-data-sm text-fg-primary mt-1",children:s.name||"—"})}),e.jsx(o,{label:"Host",children:l?u(s.host,a=>m(s._id,{host:a,audience:s.audience||a})):e.jsx("p",{className:"type-data-sm text-fg-primary mt-1",children:s.host||"—"})}),e.jsx(o,{label:"Port",children:l?u(s.port,a=>m(s._id,{port:Number(a)}),{type:"number",min:1,max:65535}):e.jsx("p",{className:"type-data-sm text-fg-primary mt-1",children:s.port})}),e.jsx(o,{label:"Format",children:l?e.jsxs("select",{className:"mt-1 w-full surface-input radius-inner px-3 py-2 text-fg-primary",value:s.format,onChange:a=>m(s._id,{format:a.target.value}),children:[e.jsx("option",{value:"meshcoretomqtt",children:"Meshcoretomqtt"}),e.jsx("option",{value:"letsmesh",children:"Letsmesh"}),e.jsx("option",{value:"waev",children:"Waev"}),e.jsx("option",{value:"mqtt",children:"pyMC/custom MQTT"})]}):e.jsx("p",{className:"type-data-sm text-fg-primary mt-1",children:s.format})}),e.jsx(o,{label:"Transport",children:l?e.jsxs("select",{className:"mt-1 w-full surface-input radius-inner px-3 py-2 text-fg-primary",value:s.transport,onChange:a=>m(s._id,{transport:a.target.value}),children:[e.jsx("option",{value:"websockets",children:"WebSockets"}),e.jsx("option",{value:"tcp",children:"TCP"})]}):e.jsx("p",{className:"type-data-sm text-fg-primary mt-1",children:s.transport})}),s.format==="mqtt"&&e.jsx(o,{label:"Base topic",children:l?u(s.base_topic??"",a=>m(s._id,{base_topic:a}),{placeholder:"meshcore/repeater"}):e.jsx("p",{className:"type-data-sm text-fg-primary mt-1",children:s.base_topic||"—"})}),e.jsx(o,{label:s.use_jwt_auth?"Audience":"Username",children:l?u(s.use_jwt_auth?s.audience??"":s.username??"",a=>m(s._id,s.use_jwt_auth?{audience:a}:{username:a}),{placeholder:s.use_jwt_auth?s.host:"optional"}):e.jsx("p",{className:"type-data-sm text-fg-primary mt-1",children:s.use_jwt_auth?s.audience||s.host:s.username||"—"})}),!s.use_jwt_auth&&l&&e.jsx(o,{label:"Password",children:u(s.password??"",a=>m(s._id,{password:a}),{type:"password",placeholder:"blank = anonymous"})})]}),l&&e.jsxs("div",{className:"flex flex-wrap gap-4 pt-1",children:[e.jsxs("label",{className:"inline-flex items-center gap-2 type-body-sm text-fg-secondary",children:[e.jsx("input",{type:"checkbox",checked:s.enabled,onChange:a=>m(s._id,{enabled:a.target.checked})})," Enabled"]}),e.jsxs("label",{className:"inline-flex items-center gap-2 type-body-sm text-fg-secondary",children:[e.jsx("input",{type:"checkbox",checked:!!s.use_jwt_auth,onChange:a=>m(s._id,{use_jwt_auth:a.target.checked})})," JWT auth"]}),e.jsxs("label",{className:"inline-flex items-center gap-2 type-body-sm text-fg-secondary",children:[e.jsx("input",{type:"checkbox",checked:!!s.retain_status,onChange:a=>m(s._id,{retain_status:a.target.checked})})," Retain status"]}),e.jsxs("label",{className:"inline-flex items-center gap-2 type-body-sm text-fg-secondary",children:[e.jsx("input",{type:"checkbox",checked:!!s.tls.enabled,onChange:a=>Y(s._id,{enabled:a.target.checked})})," TLS"]}),e.jsxs("label",{className:"inline-flex items-center gap-2 type-body-sm text-fg-secondary",children:[e.jsx("input",{type:"checkbox",checked:!!s.tls.insecure,onChange:a=>Y(s._id,{insecure:a.target.checked})})," Insecure TLS"]})]}),l&&e.jsxs("div",{children:[e.jsx("p",{className:"type-data-xs text-fg-muted mb-2",children:"Disallowed packet types"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:Me.map(a=>e.jsx("button",{type:"button",onClick:()=>ie(s._id,a),className:`radius-badge px-2 py-1 type-data-xs border ${s.disallowedInput.includes(a)?"border-sys-amber text-sys-amber bg-sys-amber/10":"border-edge-subtle text-fg-muted"}`,children:a},a))})]})]},s._id)})]})]})})})]})]})}export{Ge as default};
