/* COPYRIGHT Esri - https://js.arcgis.com/5.0/LICENSE.txt */
import { c as Z } from "../../chunks/runtime.js";
import { css as ee, html as l } from "lit";
import { nothing as V, safeClassMap as te, LitElement as ie } from "@arcgis/lumina";
import { ref as oe, createRef as ae } from "lit/directives/ref.js";
import se from "@arcgis/core/identity/IdentityManager.js";
import { u as ne } from "../../chunks/useT9n.js";
import { b as N } from "../../chunks/arcade-defaults.js";
import _ from "@arcgis/core/request.js";
import { e as ce, a as re } from "../../chunks/utilities.js";
import { repeat as Q } from "lit/directives/repeat.js";
import "@arcgis/toolkit/function";
import { generateGuid as le } from "@arcgis/toolkit/string";
import { unsafeHTML as A } from "lit/directives/unsafe-html.js";
import de from "@arcgis/core/layers/FeatureLayer.js";
import pe from "@arcgis/core/config.js";
import ue from "@arcgis/core/Graphic.js";
import { log as x } from "@arcgis/toolkit/log";
import { getDeclaredVoxelMembers as he, getDeclaredPixelMembers as me } from "@arcgis/core/applications/Components/arcadeEditorUtils.js";
import { s as fe } from "../../chunks/fields.js";
import { g as Y, h as be } from "../../chunks/language-defaults-base.js";
import ge from "@arcgis/core/core/Accessor.js";
import { property as f, subclass as ve } from "@arcgis/core/core/accessorSupport/decorators.js";
const ye = ee`:host(:not([closed])){container-type:size;--calcite-block-border-color: var(--calcite-color-transparent);box-sizing:border-box;.submission-actions-wrapper{display:flex;flex-direction:column;width:100%;gap:.75rem}.submission-actions{display:flex;flex-direction:row;gap:.5rem;justify-content:space-between}@container (max-width: 380px){.hidden-below-380{display:none}}@container (min-width: 380px){.hidden-above-380{display:none}}.gaps{display:flex;gap:.25rem}.align-inline-end{margin-inline-start:auto}.context-popover p{padding:0 .5rem;font-size:var(--calcite-font-size-sm)}.feedback-content{padding:var(--calcite-spacing-sm);display:flex;flex-direction:column;max-height:75cqb;overflow-y:auto;>*{margin-block-end:.5rem}>*:last-child,.terms-label{margin-block-end:0}calcite-text-area{--calcite-text-area-min-height: 4rem}calcite-notice{margin-block-start:0}}.feedback-sheet{--calcite-sheet-height: auto;--calcite-sheet-max-height: 100%;--calcite-sheet-min-height: auto}.feedback-footer{display:flex;justify-content:flex-end;gap:.5rem;width:100%}calcite-chip[slot=header-actions-end]{align-self:center;margin-inline-end:.5rem}calcite-flow-item calcite-shell{background:transparent}calcite-block{width:100%;max-width:100%;align-self:flex-end;background-color:transparent;margin-block:0}calcite-sheet{--calcite-sheet-scrim-background: rgba(200, 200, 200, .5)}calcite-list-item calcite-button{margin-inline-end:.25rem}calcite-flow-item calcite-shell calcite-notice{margin-block:1rem}calcite-block[open]:last-of-type{border-block-end:0}.text-area-wrapper{display:flex;border-radius:var(--calcite-corner-radius-round);margin:.75rem;overflow:hidden;--calcite-color-border-input: transparent;position:sticky;box-shadow:var(--calcite-shadow-sm);flex:none;flex-direction:column}calcite-text-area{height:auto;overflow:hidden;--calcite-font-weight-normal: 500;font-weight:500;line-height:1.2}calcite-flow{height:100%}calcite-popover calcite-list{--calcite-list-background-color: transparent;--calcite-input-border-color: transparent}calcite-popover calcite-list calcite-filter{--calcite-spacing-sm: 0}.contained-popover-or-tooltip{--calcite-popover-max-size-x: 100%;--calcite-tooltip-max-size-x: 100%}.info-heading{font-size:var(--calcite-font-size-0);color:var(--calcite-color-text-1);margin:0}.info-heading-row{display:flex;align-items:center;gap:var(--calcite-spacing-sm);flex-wrap:wrap}.unstyled-h3{margin:unset;font-size:var(--calcite-font-size-md)}.unstyled-shell{position:unset;inset:unset;display:unset;block-size:unset;inline-size:unset}.suggestion-button{font-weight:var(--calcite-font-weight-medium)}.suggestions{display:flex;flex-direction:row;gap:var(--calcite-spacing-xs);flex-wrap:wrap}.info-block{max-width:450px}#result-block{calcite-card-group{--calcite-card-group-gap: 1.25rem}calcite-card{--calcite-card-corner-radius: var(--calcite-corner-radius-round);--calcite-card-border-color: transparent;width:100%}.positioned-code-content{display:flex;flex-direction:row;gap:.5rem;padding:.5rem}calcite-card [slot=heading] calcite-chip{margin-block-start:.25rem}.code-response-wrapper{position:relative;background:var(--calcite-color-foreground-2);border-radius:var(--calcite-corner-radius-round);margin-top:-1.5rem}.prior-prompt{display:flex;flex-direction:row;padding:0;overflow-y:hidden;overflow-x:auto;margin:.25rem 0 .75rem;align-items:center;max-width:100%;span{overflow-x:auto;overflow-y:hidden}}.copy-feedback{display:none}.copy-prompt-button{align-self:flex-start;margin-inline-start:auto}.response-secondary-action-button[data-copied]+.copy-feedback,.copy-prompt-button[data-copied]+.copy-feedback{display:block;span{padding:.75rem 1rem;font-size:var(--calcite-font-size--2);line-height:1.375;color:var(--calcite-color-text--2);font-weight:var(--calcite-font-weight-medium)}}.copy-prompt-button[data-copied]~.copy-tooltip,.response-secondary-action-button[data-copied]~.copy-tooltip{display:none}code{white-space:pre;font-size:12px;margin:0;overflow-x:auto;font-family:Fira Mono,Consolas,Menlo,monospace;display:block;max-height:12rem;position:relative;padding:.5rem}.response-secondary-action-button{margin-left:.5rem}.add-to-editor-button{--calcite-internal-button-border-color: unset}}.collapsible-code{padding:.5rem}.collapsible-code summary{cursor:pointer;font-weight:500;color:var(--calcite-color-brand);outline:none;padding:.25rem 0}.collapsible-code[open] summary{color:var(--calcite-color-text-2)}.response-error-container{padding:.5rem;background:color-mix(in srgb,var(--calcite-color-status-warning) 10%,transparent);border-radius:var(--calcite-corner-radius-round);margin:1rem 0;font-size:var(--calcite-font-size--2);--calcite-input-message-icon-color: var(--calcite-color-status-warning)}.response-error-chip{--calcite-internal-chip-background-color: var(--calcite-color-status-warning);--calcite-chip-icon-color: var(--calcite-color-foreground-1);--calcite-chip-border-color: var(--calcite-color-transparent)}.feedback-actions{gap:unset}.contained{max-width:100%;max-height:100%;max-width:100cqi;max-height:75cqb;overflow-y:auto}.submission-notice{--calcite-notice-border-color: transparent;margin-block:0;width:100%;--calcite-font-size-relative-base: var(--calcite-font-size--2)}.border-block-end{border-block-end:1px solid var(--calcite-color-border-3)}.round-top{border-radius:var(--calcite-corner-radius-round) var(--calcite-corner-radius-round) 0 0}}:host([closed]){display:none}`;
class C extends Error {
  constructor({
    message: e,
    code: i,
    subCode: o,
    details: s,
    source: n
  }) {
    super(e), this.name = "ArcadeAssistantError", this.code = i, this.subCode = o, this.details = s, this.source = n;
  }
}
function U(t) {
  if (!t)
    return;
  const e = t.indexOf('{"error":');
  if (e !== -1)
    try {
      const i = t.slice(e), o = JSON.parse(i);
      if (o && typeof o == "object" && o.error)
        return o.error;
    } catch {
      return;
    }
}
async function we(t) {
  const { baseUrl: e, skillId: i, message: o, authToken: s, previousConversationId: n, context: r } = t, p = i ? `${e}/skills/${i}/chat` : `${e}/chat`, c = [], a = {
    message: o,
    context: r
  };
  n && (a.conversation_id = n);
  let h;
  try {
    h = await _(p, {
      method: "post",
      headers: {
        "Content-Type": "application/json",
        token: s
      },
      body: JSON.stringify(a),
      responseType: "json"
    });
  } catch (b) {
    const g = b, $ = g.details?.rawResponse || g.message || String(b), k = U($);
    throw k ? new C(k) : b;
  }
  const d = h.data;
  c.push(d);
  const y = d.conversationId, q = d.inquiryId;
  let w = d.sequenceNumber;
  async function T() {
    let b = 0;
    const g = 100;
    for (; b < g; ) {
      await new Promise((S) => setTimeout(S, 1e3));
      const $ = $e(y, w, q);
      let k;
      try {
        k = await _(p, {
          method: "post",
          headers: {
            "Content-Type": "application/json",
            token: s
          },
          body: JSON.stringify($),
          responseType: "json"
        });
      } catch (S) {
        const F = S, X = F.details?.rawResponse || F.message || String(S), D = U(X);
        throw D ? new C(D) : S;
      }
      const v = k.data;
      if (v.context?.kind === "ArcgisErrorAsContext" && v.context.error)
        throw new C({
          message: v.context.error.message || "ArcGIS Assistant error",
          code: v.context.error.code,
          subCode: v.context.error.subCode,
          details: v.context.error.details,
          source: "polling-response"
        });
      if (c.push(v), w = v.sequenceNumber, b++, !v.hasMore)
        break;
    }
    if (b === g)
      throw new C({
        message: "Request timed out",
        code: "TIMEOUT",
        source: "polling"
      });
  }
  const I = 120 * 1e3;
  return await Promise.race([
    T(),
    new Promise(
      (b, g) => setTimeout(
        () => g(
          new C({
            message: "Request timed out",
            code: "TIMEOUT",
            source: "hard-timeout"
          })
        ),
        I
      )
    )
  ]), c;
}
function $e(t, e, i) {
  return {
    conversationId: t,
    inquiryId: i,
    ackSequenceNumber: e
  };
}
function xe(t) {
  return t.message.match(/Error in prompt shield/u) ? "I'm having trouble with this request. Try again by rephrasing the question." : t.code === "TIMEOUT" ? "Request timed out. Try again by re-asking the same question or rephrasing it." : t.message;
}
const ke = ({ notices: t }) => t.length ? l`<div class="border-block-end">${Q(t, (e) => e.id ?? e.title, (e) => l`<calcite-notice class="submission-notice" .icon=${e.icon} .kind=${e.kind} scale=s open .closable=${e.closable} @calciteNoticeClose=${() => e.onClose?.()}><div slot=title>${e.title}</div>${e.message && l`<div slot=message>${e.message}</div>` || ""}${e.actionLinkMessage && e.onAction && l`<calcite-link slot=link @click=${() => e.onAction?.()}>${e.actionLinkMessage}</calcite-link>` || ""}</calcite-notice>`)}</div>` : null, Se = (t) => {
  const e = t.value.length, i = 72, o = 180, s = t.offsetWidth, r = Math.max(1, Math.floor(s / 8)), p = Math.ceil(e / r), c = i + (p - 2) * 24;
  t.style.setProperty("--calcite-text-area-min-height", `${Math.min(c, o)}px`);
}, Ce = ({ promptValidationMessage: t, errorMessage: e, contextTooBig: i, contextReducedNoticeDismissed: o, setContextReducedNoticeDismissed: s, setErrorMessage: n, messages: r }) => {
  const p = [];
  if (t && p.push({
    id: "prompt-validation",
    kind: "danger",
    icon: "exclamation-mark-triangle",
    title: t,
    closable: !0
  }), e && p.push({
    id: "assistant-error",
    kind: "danger",
    icon: "exclamation-mark-triangle",
    title: e,
    closable: !0,
    onClose: () => n(void 0)
  }), i && !o) {
    const c = r.contextreduced ?? "Context reduced", a = r.contextreducedmessage ?? "The editor profile is too large for the assistant. It has been reduced in the assistant in order to ensure a successful request.";
    p.push({
      id: "context-reduced",
      kind: "warning",
      icon: "exclamation-mark-triangle",
      title: c,
      message: a,
      closable: !0,
      onClose: () => s(!0)
    });
  }
  return p;
};
function Ae({ messages: t }) {
  return l`<calcite-chip slot=header-actions-end scale=s appearance=outline-fill .label=${t.beta ?? "Beta"}>${t.beta ?? "Beta"}</calcite-chip>`;
}
function Te({ popoverContent: t, messages: e }) {
  return l`<calcite-action icon=information slot=header-actions-end id=legal-disclaimer text></calcite-action><calcite-popover reference-element=legal-disclaimer .label=${e.legaldisclaimer ?? "Legal disclaimer"} placement=bottom auto-close focus-trap-disabled><div class="contained">${t}</div></calcite-popover>`;
}
function Ie({ errorMessage: t, slot: e }) {
  return l`<div class="error-display"><calcite-input-message id=error-message status=invalid icon=exclamation-mark-triangle scale=m slot=${e ?? V}>${t}</calcite-input-message></div>`;
}
function Ee({ active: t, setActive: e, messages: i }) {
  return l`<calcite-alert slot=alerts .open=${t} placement=bottom kind=success icon=check-circle-f auto-close @calciteAlertClose=${() => e(!1)} .label=${i.expressionapplied ?? "Expression applied"}><div slot=message>${i.expressionapplied ?? "Expression applied to editor."}</div></calcite-alert>`;
}
function Re({ context: t, messages: e }) {
  return t ? l`<div class="gaps">${t.profileId && l`<calcite-popover auto-close placement=top .label=${(e.profilecontextlabel ?? "Profile context: {profileId}").replace("{profileId}", t.profileId)} reference-element=profile-context-button class="context-popover contained-popover-or-tooltip"><p>${(e.profilecontextlabel ?? "Profile context: {profileId}").replace("{profileId}", t.profileId)}</p></calcite-popover><calcite-button round kind=neutral icon-start=map-information id=profile-context-button scale=s></calcite-button>` || ""}</div>` : null;
}
function Me({ isDisabled: t, isReadOnly: e, setQuestion: i, setIsViewingResult: o, textAreaRef: s, question: n, errorMessage: r, setErrorMessage: p, promptValidationMessage: c, setPromptValidationMessage: a, submitQuestion: h, messages: d, mode: y, assistantRef: q, context: w, contextReducedNoticeDismissed: T, setContextReducedNoticeDismissed: I }) {
  const b = w?.contextTooLarge ?? !1, g = Ce({
    promptValidationMessage: c,
    errorMessage: r,
    contextTooBig: b,
    contextReducedNoticeDismissed: T,
    setContextReducedNoticeDismissed: I,
    setErrorMessage: p,
    messages: d
  });
  return l`<div class="text-area-wrapper">${ke({ notices: g })}<calcite-text-area scale=s resize=vertical .readOnly=${t || e} class=${te(g.length ? "submission-text-area" : "submission-text-area round-top")} .placeholder=${d.askaquestion ?? `Specify the calculation or logic you need in an Arcade expression. (e.g., 'Return "Yes" if value > 10')`} .value=${n} @calciteTextAreaInput=${($) => {
    Se($.target), i($.target.value);
  }} ${oe(s)}><div class="submission-actions-wrapper" slot=footer-start><div class="submission-actions">${w && Re({ context: w, messages: d }) || ""}<div class="align-inline-end gaps"><calcite-button round kind=neutral .hidden=${y !== "refine"} icon-start=arrow-left icon-flip-rtl=both appearance=solid scale=s .disabled=${t} @click=${async () => {
    o(!1), i("");
  }} .label=${d.startover ?? "Start Over"} class="hidden-above-380" id=small-start-over-button></calcite-button><calcite-tooltip reference-element=small-start-over-button placement=top-start class="hidden-above-380">${d.startover ?? "Start Over"}</calcite-tooltip><calcite-button round kind=neutral .hidden=${y !== "refine"} icon-start=arrow-left icon-flip-rtl=both appearance=solid .disabled=${t} @click=${async () => {
    o(!1), i("");
  }} class="hidden-below-380" scale=s>${d.startover ?? "Start Over"}</calcite-button><calcite-button round scale=s icon-end=effects appearance=solid .loading=${t} .disabled=${t} @click=${async () => {
    if (p(""), !n) {
      a(d.enteraprompt ?? "Please enter a prompt");
      return;
    }
    a(void 0), await h();
  }} class="hidden-below-380">${y === "prompt" ? d.ask ?? "Generate" : d.refine ?? "Refine"}</calcite-button><calcite-button round scale=s icon-end=effects appearance=solid .loading=${t} .disabled=${t} @click=${async () => {
    if (p(""), !n) {
      a(d.enteraprompt ?? "Please enter a prompt");
      return;
    }
    a(void 0), await h();
  }} class="hidden-above-380" .label=${y === "prompt" ? d.ask ?? "Generate" : d.refine ?? "Refine"}></calcite-button></div></div></div></calcite-text-area></div>`;
}
const Pe = "https://www.esri.com/en-us/privacy/privacy-statements/privacy-supplement", Ve = "https://www.esri.com/en-us/privacy/privacy-statements";
function qe({ setOpen: t, messages: e, feedback: i, learnMoreUrl: o, setFeedback: s, onSubmit: n }) {
  return i.active ? l`<calcite-sheet class="feedback-sheet" .label=${e.feedback ?? "Feedback"} slot=sheets display-mode=float position=block-end .open=${i.active} @calciteSheetClose=${() => t(!1)}><calcite-panel .heading=${e.submitfeedback ?? "Submit feedback to Esri"} scale=s><div class="feedback-content"><calcite-text-area scale=s resize=vertical .value=${i.text} @calciteTextAreaInput=${(r) => s({ ...i, text: r.target.value })} .disabled=${i.submitting} .placeholder=${e.donotincludepersonalinfo ?? "Do not include personal or sensitive information"} rows=3></calcite-text-area><calcite-label layout=inline scale=s class="terms-label"><calcite-checkbox scale=l .checked=${i.termsAccepted} @calciteCheckboxChange=${(r) => {
    s({ ...i, termsAccepted: r.target.checked });
  }} .disabled=${i.submitting}></calcite-checkbox><span>${A((e.agreement ?? "I agree to the {EsriPrivacyStatement} (and {Supplement}).").replace("{EsriPrivacyStatement}", `<calcite-link href=${Ve} target="_blank">${e.esriprivacystatement ?? "Esri Privacy Statement"}</calcite-link>`).replace("{Supplement}", `<calcite-link href=${Pe} target="_blank">${e.supplement ?? "Supplement"}</calcite-link>`))}</span></calcite-label><calcite-notice scale=s open closable><span slot=message>${A((e.feedbackhelps ?? "Your feedback will be used to improve Esri products and services. {LearnMore} about how this data is used.").replace("{LearnMore}", `<calcite-link href=${o} target="_blank">${e.learnmore ?? "Learn more"}</calcite-link>`))}</span></calcite-notice></div><div slot=footer class="feedback-footer"><calcite-button kind=neutral appearance=outline @click=${() => t(!1)} .disabled=${i.submitting}>${e.cancel ?? "Cancel"}</calcite-button><calcite-button @click=${n} .disabled=${!i.termsAccepted || i.submitting} .loading=${i.submitting} data-testid=submit-feedback-button>${e.submit ?? "Submit"}</calcite-button></div></calcite-panel></calcite-sheet>` : null;
}
function O({ assistantsEnabled: t, messages: e, slot: i, helpTopicUrl: o }) {
  return l`<calcite-block .label=${e.assistantinformation ?? "Assistant information"} slot=${i ?? V} expanded class="info-block" scale=s><div class="info-heading-row"><h1 class="info-heading">${e.introducing ?? "Introducing Arcade Assistant (beta)"}</h1><calcite-chip .label=${e.new ?? "New"} kind=brand scale=s>${e.new ?? "New"}</calcite-chip></div>${t ? l`<p>${e.capabilities ?? "The assistant uses artificial intelligence to generate Arcade expressions."}</p><p>${e.keepinmind ?? "Keep in mind the following:"}<ul><li>${e.beconsise ?? "Be concise, but also clear in your request"}</li><li>${e.avoidambiguity ?? "Avoid ambiguity and vagueness"}</li><li>${e.moredetails ?? "you do not need to use exact field names in your instructions, but more detail is generally better"}</li></ul>${A((e.seedocumentation ?? "Please see the {documentation} for more information, including limitations and additional resources.").replace("{documentation}", `<calcite-link href=${o} target="_blank">${e.documentation ?? "documentation"}</calcite-link>`))}</p>` : l`<p>${e.useofassistant ?? "The assistant uses artificial intelligence to generate Arcade expressions. To enable Arcade Assistant (beta), the following must be true:"}</p><ul><li>${e.enabledinorg ?? "AI assistants are enabled in the organization settings"}</li><li>${e.enabledbetaapps ?? "Beta apps and capabilities are not blocked"}</li><li>${e.enabledroleprivilege ?? "Your role privilege allows you to use AI assistants"}</li></ul>`}</calcite-block>`;
}
function Fe({ messages: t, onProceed: e, onExit: i, helpTopicUrl: o }) {
  return l`<calcite-dialog close-disabled placement=top .heading=${t.welcome ?? "Welcome to the new assistant experience"} slot=dialogs open width-scale=m id=welcome-dialog><h3 class="unstyled-h3">${t.beforeyougetstarted ?? "Before you get started be aware:"}</h3><ul><li>${t.maybeincorrect ?? "AI generated code may occasionally be incorrect or biased. Review carefully."}</li><li>${A((t.pleasereadhelp ?? "Read the Arcade Assistant (beta) {helpTopic} to get started and learn details on security, privacy and limitations.").replace("{helpTopic}", `<calcite-link href=${o} target="_blank">${t.helptopic ?? "help topic"}</calcite-link>`))}</li></ul><calcite-button id=welcome-proceed slot=footer-end @click=${e}>${t.proceed ?? "Proceed"}</calcite-button><calcite-button id=welcome-decline slot=footer-start @click=${i} kind=neutral>${t.exit ?? "Exit"}</calcite-button></calcite-dialog>`;
}
function De({ messages: t, suggestions: e, onSuggestionClick: i }) {
  return l`<calcite-block .heading=${t.promptsuggestions} expanded collapsible id=suggestion-block scale=s><div class="suggestions">${e.map((o) => l`<calcite-button round scale=s appearance=outline-fill kind=neutral .label=${t.promptsuggestion} class="suggestion-button" @click=${() => i?.(o)}>${o}</calcite-button>`)}</div></calcite-block>`;
}
const z = 200;
function L({ hidden: t = !1, expanded: e = !1, messages: i, cards: o, heading: s, collapsible: n = !1, showEffectsIcon: r = !1, onCopyCode: p, standalone: c }) {
  return l`<calcite-block .hidden=${t} id=result-block .heading=${s ?? i.besteffort ?? "Here is the assistant's best effort"} .expanded=${e} .collapsible=${n}>${r && l`<calcite-chip .label=${i.assistantresponses ?? "Assistant responses"} slot=content-start icon=effects scale=m class="suggestion-chips"></calcite-chip>` || ""}<calcite-card-group .label=${i.assistantresponses ?? "Assistant responses"}>${Q(o, (a) => a.conversationId, (a) => l`<calcite-card><div slot=heading><div class="prior-prompt"><span>${a.priorPrompt.length > z ? `${a.priorPrompt.slice(0, z)}...` : a.priorPrompt}</span><calcite-action icon=duplicate scale=s slot=actions-end class="copy-prompt-button" text .id=${`copy-prompt-${a.conversationId}-${c ? "standalone" : "list"}`} @click=${(h) => {
    const d = h.currentTarget;
    navigator.clipboard.writeText(a.priorPrompt).then(() => {
      d.setAttribute("data-copied", "true"), setTimeout(() => d.removeAttribute("data-copied"), 1500);
    });
  }}></calcite-action><calcite-popover .referenceElement=${`copy-prompt-${a.conversationId}-${c ? "standalone" : "list"}`} placement=top-start class="copy-feedback" .label=${i.copiedsuccessfully ?? "copied successfully"} open trigger-disabled><span>${i.copiedsuccessfully ?? "copied successfully"}</span></calcite-popover><calcite-tooltip .referenceElement=${`copy-prompt-${a.conversationId}-${c ? "standalone" : "list"}`} placement=top-start class="copy-tooltip">${i.copyprompttoclipboard ?? "Copy prompt to clipboard"}</calcite-tooltip></div>${a.message && c && l`<div class="response-error-container">${Ie({ errorMessage: a.message })}</div>` || ""}</div><div><div class="code-response-wrapper"><div class="positioned-code-content"><calcite-chip-group .label=${i.responsecontext ?? "Response Context"} scale=s>${a.message && !c && l`<calcite-tooltip .referenceElement=${`response-chip-${a.conversationId}-error`} placement=top-start>${a.message}</calcite-tooltip><calcite-chip .id=${`response-chip-${a.conversationId}-error`} .label=${i.error ?? "Error"} scale=s appearance=outline icon=exclamation-mark-triangle-f class="response-error-chip"></calcite-chip>` || ""}${Ne({ card: a, messages: i })}</calcite-chip-group></div><details class="collapsible-code" open><summary>Code response</summary><arcgis-code-viewer language=arcade round>${a.code}</arcgis-code-viewer></details></div></div><div slot=footer-start class="feedback-actions"><calcite-button class="add-to-editor-button hidden-above-380" @click=${() => a.onAddToEditor("add")} scale=s icon-start=plus round .label=${i.addtoeditor ?? "Add to editor"} .id=${`add-to-editor-button-${a.conversationId}-${c ? "standalone" : "list"}`}></calcite-button><calcite-tooltip class="hidden-above-380" .referenceElement=${`add-to-editor-button-${a.conversationId}-${c ? "standalone" : "list"}`} placement=top-start>${i.addtoeditor ?? "Add to editor"}</calcite-tooltip><calcite-button class="add-to-editor-button hidden-below-380" @click=${() => a.onAddToEditor("add")} scale=s icon-start=plus round>${i.addtoeditor ?? "Add to editor"}</calcite-button><calcite-button round icon-start=file-code kind=neutral scale=s @click=${() => a.onAddToEditor("replace")} class="response-secondary-action-button" .id=${`replace-${a.conversationId}-${c ? "standalone" : "list"}`}></calcite-button><calcite-tooltip .referenceElement=${`replace-${a.conversationId}-${c ? "standalone" : "list"}`} placement=top-start><span>${i.replaceineditor ?? "Replace all code in editor"}</span></calcite-tooltip><calcite-button round icon-start=copy-to-clipboard kind=neutral scale=s @click=${(h) => {
    const d = h.currentTarget;
    p(a.code).then(() => {
      d.setAttribute("data-copied", "true"), setTimeout(() => d.removeAttribute("data-copied"), 1500);
    });
  }} class="response-secondary-action-button" .id=${`copy-response-${a.conversationId}-${c ? "standalone" : "list"}`}></calcite-button><calcite-popover .referenceElement=${`copy-response-${a.conversationId}-${c ? "standalone" : "list"}`} placement=top-start class="copy-feedback" .label=${i.copiedsuccessfully ?? "copied successfully"} open trigger-disabled><span>${i.copiedsuccessfully ?? "copied successfully"}</span></calcite-popover><calcite-tooltip .referenceElement=${`copy-response-${a.conversationId}-${c ? "standalone" : "list"}`} placement=top-start class="copy-tooltip">${i.copytoclipboard ?? "Copy code to clipboard"}</calcite-tooltip></div><div slot=footer-end class="feedback-actions"><calcite-action .text=${i.thumbsup ?? "Thumbs up"} scale=s icon=thumbs-up @click=${a.onThumbsUp} .id=${`thumbs-up-${a.conversationId}-${c ? "standalone" : "list"}`}></calcite-action><calcite-tooltip .referenceElement=${`thumbs-up-${a.conversationId}-${c ? "standalone" : "list"}`} placement=top-start><span>${i.helpful ?? "Helpful"}</span></calcite-tooltip><calcite-action .text=${i.thumbsdown ?? "Thumbs down"} scale=s icon=thumbs-down @click=${a.onThumbsDown} .id=${`thumbs-down-${a.conversationId}-${c ? "standalone" : "list"}`}></calcite-action><calcite-tooltip .referenceElement=${`thumbs-down-${a.conversationId}-${c ? "standalone" : "list"}`} placement=top-start><span>${i.unhelpful ?? "Unhelpful"}</span></calcite-tooltip></div></calcite-card>`)}</calcite-card-group></calcite-block>`;
}
const Ne = ({ card: t, messages: e }) => {
  const i = le(), o = `response-chip-profile-${t.conversationId}-${i}`, s = (e.profilecontextlabel ?? "Profile context: {profileId}").replace("{profileId}", t.profileId);
  return l`<calcite-tooltip .referenceElement=${o} placement=top-start class="contained-popover-or-tooltip">${s}</calcite-tooltip><calcite-chip .label=${t.profileId} scale=s appearance=outline icon=map-information id=${o ?? V}>${t.profileId}</calcite-chip>`;
}, B = (t) => t.type === "featureSet", E = (t) => {
  if (!be(t))
    return [];
  const e = [];
  return t.relationships?.forEach((i) => {
    e.push(i.toJSON());
  }), e;
}, R = (t) => t.length > 0 ? { relationships: t } : {}, _e = (t) => fe(t).map((e) => ({
  alias: e.alias,
  name: e.name,
  type: e.type,
  ...e.domain ? { domain: e.domain } : {}
})), M = (t) => t ? { fields: _e(t) } : { fields: [] };
async function j(t) {
  const e = await t.loadSource(), i = Y(e) && e.isTable, o = E(e);
  return {
    name: t.name,
    type: "featureSet",
    isTable: i,
    ...M(e?.fields),
    ...R(o)
  };
}
async function K(t) {
  switch (t.type) {
    case "feature": {
      const e = await t.loadSource(), i = E(e);
      return {
        name: t.name,
        type: t.type,
        ...M(e?.fields),
        ...R(i)
      };
    }
    case "featureSet": {
      const e = await t.loadSource(), i = Y(e) && e.isTable;
      return {
        name: t.name,
        type: "featureSet",
        ...i ? { isTable: i } : {},
        ...M(e?.fields),
        ...R(E(e))
      };
    }
    case "featureSetCollection": {
      const e = await t.loadSource(), i = e?.layers.filter(B) ?? [], o = e?.tables.filter(B) ?? [], s = await Promise.all(i.map(j)), n = await Promise.all(o.map(j));
      return {
        name: t.name,
        type: "featureSetCollection",
        layers: s,
        tables: n
      };
    }
    case "dictionary": {
      const e = await Promise.all(t.dictionaryVariables.map(K));
      return {
        name: t.name,
        type: "dictionary",
        attributes: e
      };
    }
    case "pixel": {
      const e = await t.loadSource();
      if (!e)
        return {
          name: t.name,
          type: "pixel"
        };
      const i = await me(e);
      return {
        name: t.name,
        type: "pixel",
        members: i.map(H)
      };
    }
    case "voxel": {
      const e = await t.loadSource();
      if (!e)
        return {
          name: t.name,
          type: "voxel"
        };
      const i = await he(e);
      return {
        name: t.name,
        type: "voxel",
        members: i.map(H)
      };
    }
    case "array":
      return {
        name: t.name,
        type: "array",
        elementType: t.elementType.type
      };
    case "number":
    case "text":
    case "boolean":
    case "date":
    case "knowledgeGraph":
    case "dateOnly":
    case "geometry":
    case "time":
      return {
        name: t.name,
        type: t.type
      };
  }
}
function H(t) {
  return t.type === "array" ? {
    name: t.name,
    type: "array",
    elementType: t.elementType.type
  } : {
    name: t.name,
    type: t.type
    // casting bc member types shouldn't be feature, featureset, etc.
  };
}
async function Ue(t) {
  return {
    variables: await Promise.all(t.variables.map(K))
  };
}
const Oe = 1e5;
function ze(t) {
  const e = new TextEncoder().encode(t).length;
  return Math.ceil(e / 3.5);
}
function P(t) {
  return ze(JSON.stringify(t));
}
function Le(t) {
  const e = (o) => ({
    name: o.name,
    type: o.type,
    ...o.isTable ? { isTable: o.isTable } : {},
    ...o.relationships ? { relationships: o.relationships } : {}
  }), i = (o) => {
    switch (o.type) {
      case "feature":
      case "featureSet":
      case "knowledgeGraph":
        return {
          name: o.name,
          type: o.type,
          ..."isTable" in o && o.isTable ? { isTable: o.isTable } : {},
          ..."relationships" in o ? { relationships: o.relationships } : {}
        };
      case "featureSetCollection":
        return {
          name: o.name,
          type: "featureSetCollection",
          layers: o.layers.map(e),
          tables: o.tables.map(e)
        };
      case "dictionary":
        return {
          name: o.name,
          type: "dictionary",
          attributes: o.attributes.map(i)
        };
      case "pixel":
      case "voxel":
        return {
          name: o.name,
          type: o.type
        };
      case "array":
        return {
          name: o.name,
          type: "array",
          ...o.elementType ? { elementType: o.elementType } : {}
        };
      default:
        return o;
    }
  };
  return {
    variables: t.variables.map(i)
  };
}
function Be(t) {
  const e = t.variables, i = e.length, o = e.find((n) => n.name === "$feature") ?? e.find((n) => n.type === "feature") ?? e[0], s = o ? [o] : [];
  return {
    context: { variables: s },
    wasReduced: i !== s.length,
    reducedToVariableName: o?.name
  };
}
function je(t) {
  return P(t) > Oe;
}
var He = Object.defineProperty, Ge = Object.getOwnPropertyDescriptor, m = (t, e, i, o) => {
  for (var s = o > 1 ? void 0 : o ? Ge(e, i) : e, n = t.length - 1, r; n >= 0; n--)
    (r = t[n]) && (s = (o ? r(e, i, s) : r(s)) || s);
  return o && s && He(e, i, s), s;
};
let u = class extends ge {
  constructor(t) {
    super(t), this.viewMode = "prompt", this.confirmationActive = !1, this.contextReducedNoticeDismissed = !1, this.splashActive = !0, this.isSubmitting = !1, this.question = "", this.history = [], this.feedback = { active: !1 };
  }
};
m([
  f()
], u.prototype, "viewMode", 2);
m([
  f()
], u.prototype, "confirmationActive", 2);
m([
  f()
], u.prototype, "contextReducedNoticeDismissed", 2);
m([
  f()
], u.prototype, "splashActive", 2);
m([
  f()
], u.prototype, "isSubmitting", 2);
m([
  f()
], u.prototype, "errorMessage", 2);
m([
  f()
], u.prototype, "promptValidationMessage", 2);
m([
  f()
], u.prototype, "question", 2);
m([
  f()
], u.prototype, "history", 2);
m([
  f()
], u.prototype, "feedback", 2);
m([
  f()
], u.prototype, "context", 2);
u = m([
  ve("ArcadeAssistantViewState")
], u);
const Je = "arcade_generation", We = "ArcadeCodeRequest", G = "visualization", Qe = "ArcadeAssistant", Ye = [
  "your_comments",
  "user_evaluation",
  "question",
  "answer",
  "useragent",
  "_source",
  "version",
  "context",
  "extras"
];
let J = [], W = !0;
class Ke extends ie {
  constructor() {
    super(...arguments), this.textAreaRef = ae(), this.messages = ne(), this._feedbackService = void 0, this.viewState = new u(), this.handleFeedbackButton = (e, i) => {
      this.updateViewState({
        feedback: { active: !0, value: e, item: i, termsAccepted: !1, text: "", submitting: !1 }
      });
    }, this.handleFeedbackSheetClose = () => {
      this.updateViewState({ feedback: { active: !1 } });
    }, this.handleFeedbackSubmit = async () => {
      if (!this.viewState.feedback.active)
        return;
      this.updateViewState({ feedback: { ...this.viewState.feedback, submitting: !0 } });
      const e = await this.ensureFeedbackService();
      if (!e) {
        this.handleFeedbackSheetClose();
        return;
      }
      const i = this.viewState.feedback.item.contextSnapshot, o = pe.applicationName;
      !o && !this.appVersion && x("warn", this, "esriConfig.applicationName is not set. Consider setting it to help identify the application version in feedback.");
      const { value: s, text: n, termsAccepted: r, item: { question: p, formattedScript: c, conversationId: a } } = this.viewState.feedback, h = {
        user_evaluation: s,
        your_comments: n || void 0,
        question: p ?? "",
        /**
         * The answer may contain invalid or partial HTML, which causes the feature service's HTML sanitizer to strip or reject it.
         * To preserve the content reliably, we encode it using encodeURIComponent, which escapes all non-ASCII and special characters.
         * This ensures the content passes through the sanitizer safely and can be decoded later. This is a temporary workaround until
         * the sanitizer can be disabled on the service.
         */
        answer: encodeURIComponent(c ?? ""),
        useragent: navigator.userAgent,
        _source: Qe,
        version: this.appVersion || o || "NOT_SET",
        context: i ? JSON.stringify(i) : "",
        extras: i?.profileId ?? "",
        conversation_id: a ?? "",
        privacy_statement: r ? "I_agree" : ""
      };
      try {
        await e.applyEdits({ addFeatures: [new ue({ attributes: h })] });
      } catch (d) {
        x("error", this, "Error submitting feedback.", { detail: { error: d } });
      }
      this.handleFeedbackSheetClose();
    }, this.handleClose = (e) => {
      this.closed = !0, this.closePanel?.(e);
    }, this.setQuestionState = (e) => {
      this.updateViewState({ question: e, promptValidationMessage: void 0 });
    }, this.setFeedbackState = (e) => {
      this.updateViewState({ feedback: e });
    }, this.onSuggestionClick = (e) => {
      this.textAreaRef.value && (this.textAreaRef.value.value = e, this.textAreaRef.value.setFocus(), this.setQuestionState(e));
    }, this.helpBase = "", this.assistantsEnabled = !1, this.closed = !1;
  }
  static {
    this.properties = { closePanel: 0, insertText: 0, helpBase: 1, assistantsEnabled: 5, portalUrl: 1, serviceUrl: 1, closed: 7, editorRef: 0, feedbackServiceUrl: 1, appVersion: 1 };
  }
  static {
    this.styles = ye;
  }
  get disclaimerComment() {
    return `// ${this.messages.disclaimercomment}
// ${this.messages.disclaimerpt2 ?? "AI-generated content may be inaccurate. Review before using."}`;
  }
  get assistantOverviewDocUrl() {
    return `${this.helpBase ?? "https://doc.arcgis.com/en/arcgis-online/"}create-maps/understand-arcade-assistant.htm`;
  }
  get usingTheAssitantDocUrl() {
    return `${this.helpBase ?? "https://doc.arcgis.com/en/arcgis-online/"}create-maps/use-arcade-assistant.htm`;
  }
  async destroy() {
  }
  connectedCallback() {
    super.connectedCallback(), this.updateViewState({ history: J, splashActive: W });
  }
  load() {
    const e = async () => {
      const i = this.getModel();
      if (!i) {
        this.updateViewState({ context: void 0 });
        return;
      }
      const o = await this.getProfileAndMetadata(i.uri);
      this.updateViewState({
        context: o,
        contextReducedNoticeDismissed: o.contextTooLarge ? !1 : this.viewState.contextReducedNoticeDismissed
      });
    };
    e().catch((i) => {
      x("error", this, "Error setting initial context.", { detail: { error: i } });
    }), this.manager.onLifecycle(() => {
      const i = N.onModelContextDidChange(async () => {
        e().catch((s) => {
          x("error", this, "Error setting context.", { detail: { error: s } });
        });
      });
      return { remove: () => {
        i.dispose();
      } };
    });
  }
  disconnectedCallback() {
    super.disconnectedCallback(), J = this.viewState.history, W = this.viewState.splashActive, this.copySuccessTimer && (clearTimeout(this.copySuccessTimer), this.copySuccessTimer = void 0);
  }
  createFeedbackContextSnapshot(e) {
    const i = Le(e.metadata);
    return {
      ...e,
      metadata: i,
      estimatedTokens: P(i)
    };
  }
  updateViewState(e) {
    this.viewState.set(e);
  }
  getHistoryCards() {
    return this.viewState.history.reduce((e, i) => (!i.script || (e.push({
      priorPrompt: i.question,
      code: i.formattedScript || i.error || "",
      profileId: i.profile ?? G,
      onAddToEditor: (o) => {
        ce(this.editorRef.editorInstance, i.formattedScript ?? "", o, this.disclaimerComment);
      },
      onThumbsUp: () => this.handleFeedbackButton("good", i),
      onThumbsDown: () => this.handleFeedbackButton("bad", i),
      conversationId: i.conversationId ?? "",
      message: i.message
    }), this.viewState.viewMode === "result"), e), []);
  }
  async ensureFeedbackService() {
    if (this._feedbackService)
      return this._feedbackService;
    if (!this.feedbackServiceUrl)
      return;
    const e = new de({ url: this.feedbackServiceUrl });
    await e.load();
    const i = Ye.filter((o) => !e.fields.some((s) => s.name === o));
    if (i.length > 0) {
      x("error", this, `Missing the following fields in feedback service: ${i.join(", ")}. Feedback will not be logged.`);
      return;
    }
    return this._feedbackService = e, e;
  }
  getModel() {
    return this.editorRef.editorInstance?.getModel();
  }
  async submitQuestion() {
    if (this.viewState.question) {
      this.updateViewState({ isSubmitting: !0, errorMessage: void 0 });
      try {
        const e = await this.getToken(), i = this.getModel();
        if (!i)
          return;
        const o = this.viewState.context ?? await this.getProfileAndMetadata(i.uri), n = (await we({
          baseUrl: this.serviceUrl,
          skillId: Je,
          message: this.viewState.question,
          authToken: e,
          context: {
            kind: We,
            context: {
              profile_id: o.profileId,
              metadata: [o.metadata]
            }
          }
        })).find((r) => r.context?.kind === "ArcadeCodeResponse");
        if (!n)
          return;
        if (n.context?.kind === "ArcadeCodeResponse") {
          const r = this.createFeedbackContextSnapshot(o);
          this.updateViewState({
            history: [
              {
                script: n?.context?.arcadeCode?.code,
                formattedScript: re(n?.context?.arcadeCode?.code ?? ""),
                error: void 0,
                question: this.viewState.question,
                profile: o.profileId,
                conversationId: n.conversationId,
                contextSnapshot: r,
                ...n.message ? { message: n.message } : {}
              },
              ...this.viewState.history
            ],
            viewMode: "result",
            errorMessage: void 0
          });
        }
      } catch (e) {
        e instanceof Error && e.name === "ArcadeAssistantError" ? this.updateViewState({
          errorMessage: xe(e) || this.messages.erroroccurred || "An error occurred."
        }) : this.updateViewState({ errorMessage: this.messages.erroroccurred || "An error occurred." }), x("error", this, "Error submitting question", { detail: { error: e } });
      } finally {
        this.updateViewState({ isSubmitting: !1 });
      }
    }
  }
  async getToken() {
    const { token: e } = await se.getCredential(this.portalUrl);
    return e;
  }
  async getProfileAndMetadata(e) {
    let i = G;
    const o = N.getEditorProfileForModel(e);
    o?.loaded || await o?.loadSource();
    const s = this.editorRef.profile;
    s && "id" in s && (i = s.id);
    const n = o ? await Ue(o) : { variables: [] }, r = je(n), p = r ? Be(n) : void 0, a = p ? p.context : n, h = P(a);
    return {
      profileId: i,
      metadata: a,
      contextTooLarge: r,
      reducedToVariableName: p?.reducedToVariableName,
      estimatedTokens: h
    };
  }
  onCopyCode(e) {
    const i = e ? `${this.disclaimerComment}
${e}` : "";
    return navigator.clipboard.writeText(i);
  }
  render() {
    if (this.closed)
      return null;
    const e = this.viewState.viewMode === "result", i = this.getHistoryCards();
    return this.assistantsEnabled ? l`<calcite-flow><calcite-flow-item closable heading-level=2 .heading=${this.messages.arcadeassistant ?? "Arcade assistant"} @calciteFlowItemClose=${this.handleClose}>${this.viewState.splashActive && l`<calcite-scrim></calcite-scrim>` || ""}${Ae({ messages: this.messages })}${Te({ messages: this.messages, popoverContent: O({ assistantsEnabled: this.assistantsEnabled, messages: this.messages, helpTopicUrl: this.usingTheAssitantDocUrl }) })}<calcite-shell class="unstyled-shell">${this.viewState.splashActive && Fe({ messages: this.messages, onProceed: () => {
      this.updateViewState({ splashActive: !1 });
    }, helpTopicUrl: this.assistantOverviewDocUrl, onExit: (o) => this.closePanel?.(o) }) || ""}${Ee({ active: this.viewState.confirmationActive, setActive: (o) => this.updateViewState({ confirmationActive: o }), messages: this.messages })}${Me({ isDisabled: this.viewState.isSubmitting, isReadOnly: !1, setQuestion: this.setQuestionState, setIsViewingResult: (o) => this.updateViewState({ viewMode: o ? "result" : "prompt" }), mode: e ? "refine" : "prompt", textAreaRef: this.textAreaRef, question: this.viewState.question, errorMessage: this.viewState.errorMessage, setErrorMessage: (o) => this.updateViewState({ errorMessage: o }), promptValidationMessage: this.viewState.promptValidationMessage, setPromptValidationMessage: (o) => this.updateViewState({ promptValidationMessage: o }), submitQuestion: this.submitQuestion.bind(this), assistantRef: this.el, messages: this.messages, context: this.viewState.context, contextReducedNoticeDismissed: this.viewState.contextReducedNoticeDismissed, setContextReducedNoticeDismissed: (o) => this.updateViewState({ contextReducedNoticeDismissed: o }) })}<calcite-block-group .label=${this.messages.interactiveblocks ?? "interactive blocks"}>${!e && !this.viewState.isSubmitting && De({ messages: this.messages, suggestions: [this.messages.prompsuggestion1 ?? "", this.messages.prompsuggestion2 ?? ""], onSuggestionClick: this.onSuggestionClick }) || ""}<calcite-block .hidden=${!this.viewState.isSubmitting} .heading=${this.messages.generatingresponse ?? "Generating response..."}></calcite-block>${L({
      expanded: e,
      messages: this.messages,
      collapsible: !0,
      showEffectsIcon: !0,
      /** Only show the latest history card */
      cards: i.length ? [i[0]] : [],
      heading: this.messages.besteffort ?? "Here's the assistant's best effort",
      hidden: this.viewState.isSubmitting || !e,
      onCopyCode: this.onCopyCode.bind(this),
      standalone: !0
    })}${L({
      expanded: !e,
      messages: this.messages,
      collapsible: !0,
      /**
       * When the user is viewing the latest result, we display the first history card
       * (historyCards[0]) separately at the top in "standalone" mode.
       * To avoid showing the same card twice, we remove (slice out) the first card
       * from the list of recent prompts below.
       */
      cards: e ? i.slice(1) : i,
      heading: this.messages.recentprompts ?? "Recent prompts",
      hidden: this.viewState.isSubmitting || this.viewState.history.length === 0,
      onCopyCode: this.onCopyCode.bind(this)
    })}</calcite-block-group>${this.viewState.feedback.active ? qe({ setOpen: this.handleFeedbackSheetClose, messages: this.messages, onSubmit: this.handleFeedbackSubmit, feedback: this.viewState.feedback, setFeedback: this.setFeedbackState, learnMoreUrl: this.assistantOverviewDocUrl }) : null}</calcite-shell></calcite-flow-item></calcite-flow>` : l`<calcite-flow><calcite-flow-item .selected=${!e} closable heading-level=2 .heading=${this.messages.arcadeassistant ?? "Arcade assistant"} @calciteFlowItemClose=${this.handleClose}>${O({ slot: "content-top", messages: this.messages, assistantsEnabled: this.assistantsEnabled, helpTopicUrl: this.usingTheAssitantDocUrl })}</calcite-flow-item></calcite-flow>`;
  }
}
Z("arcgis-arcade-coding-assistant", Ke);
export {
  Ke as ArcgisArcadeCodingAssistant
};
