/* COPYRIGHT Esri - https://js.arcgis.com/1.2/LICENSE.txt */
import { c as customElement } from "../../chunks/runtime.js";
import { a as getAllFeatureLayers, g as getLayerOrTable } from "../../chunks/mapViewUtils.js";
import { u as useT9n } from "../../chunks/useT9n.js";
import { css, html, nothing } from "lit";
import { createRef, ref } from "lit-html/directives/ref.js";
import { LitElement, createEvent, noShadowRoot, safeClassMap } from "@arcgis/lumina";
import { p as projectToSpatialReference } from "../../chunks/queryUtils.js";
import Editor from "@arcgis/core/widgets/Editor";
import ExpressionInfo from "@arcgis/core/form/ExpressionInfo";
import FeatureLayer from "@arcgis/core/layers/FeatureLayer";
import FieldElement from "@arcgis/core/form/elements/FieldElement";
import FormTemplate from "@arcgis/core/form/FormTemplate";
import MapView from "@arcgis/core/views/MapView";
import Home from "@arcgis/core/widgets/Home";
import Search from "@arcgis/core/widgets/Search";
import Graphic from "@arcgis/core/Graphic";
import * as reactiveUtils from "@arcgis/core/core/reactiveUtils";
import esriRequest from "@arcgis/core/request";
import * as exifr from "exifr";
import Point from "@arcgis/core/geometry/Point";
import SpatialReference from "@arcgis/core/geometry/SpatialReference";
const styles = css`@layer{
/** @license
 * Copyright 2025 Esri
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

:host {
  display: block;
}

/* Override to hide Editor settings panel collapsible */
.hide-editor-toolbar .esri-editor__panel-toolbar {
  display: none !important;
}

/* Override to reduce the padding of panel content*/
.esri-editor__panel-content {
  padding-block: 0px !important;
}

/* Override to hide header */
.esri-editor .esri-item-list__group__header {
  display: none !important;
}

/* Override to hide the create feature heading title */
.esri-editor__panel-content__section .esri-widget__heading {
  display: none !important;
}

/* Override to reduce padding for the template filter*/
.esri-editor .esri-item-list__filter-container--sticky {
  padding-block: 0px !important;
  padding-inline: 10px !important;
}

.search-widget {
  width: 92% !important;
  margin: 5px 14px 20px 14px;
}

.display-none {
  display: none !important;
}

.hide-map {
  height: 1%;
  visibility: hidden;
}

.show-map {
  padding: 10px !important;
  position: absolute !important;
  bottom: 0;
  height: auto !important;
  width: calc(100% - 22px);
}

.notice-msg {
  padding: 10px;
  width: calc(100% - 20px);
}

.edit-location-btn {
  margin: 5px;
  display: flex;
}

/* override the padding of the feature form */
.esri-editor__panel-content {
  padding-block: 10px !important;
}

.image-preview-container {
  padding: 10px;
}

.esri-editor {
  height: auto !important;
}

.content-container {
  padding: 1.5rem;
}

.instruction-text {
  margin-bottom: 1.5rem;
  font-size: 1rem;
}

/* Mimics the blue selection border in the image */
.selected-card {
  border: 2px solid var(--calcite-ui-brand);
}

.upload-img-footer-container {
  width: 100%;
  gap: 5px;
  display: grid;
}

.info-container {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 10px;
}

.info-container calcite-icon {
  --calcite-icon-color: var(--calcite-color-brand);
}

.info-container span {
  font-size: 12px;
  color: var(--calcite-ui-text-3)
}

.padding-10 {
  padding: 10px;
}

/* Main UI Container */
.report-selection-container {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 10px;
  --calcite-card-border-color: var(--calcite-color-border-1);
}

.cursor-pointer {
  cursor: pointer;
}

.card-body-content {
  display: flex;
  flex-direction: row;
  align-items: center;
  padding: 10px 5px;
  gap: 15px;
}

.text-stack {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.option-title {
  font-weight: var(--calcite-font-weight-bold);
  color: var(--calcite-ui-text-1);
  font-size: var(--calcite-font-size--1);
}

.option-description {
  color: var(--calcite-ui-text-3);
  font-size: var(--calcite-font-size--1);
}

/* Centered Button Wrapper */
.action-footer {
  display: flex;
  justify-content: center;
  margin-top: 16px;
}
/* Main Centered Container */
.analysis-wrapper {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  /* Space between the label row and the button */
  text-align: center;
  margin: auto;
}

/* Animation for the 'effects' icon */
.analyzing-icon {
  --calcite-icon-color: var(--calcite-color-brand);
  animation: sparkle 2s infinite ease-in-out;
}

@keyframes sparkle {

  0%,
  100% {
    transform: scale(1);
  }

  50% {
    transform: scale(1.5);
  }
}

/* overide css for editor widget in case of mobile */
@media only screen and (max-width: 600px) {
  .esri-editor__panel-content {
    padding-block: 0 !important;
    min-height: 0 !important;
  }
}
}`;
class CreateFeature extends LitElement {
  constructor() {
    super(...arguments);
    this.customizeSubmit = false;
    this.enableSearch = false;
    this.enableSnapping = false;
    this.floorLevel = "";
    this.isMobile = false;
    this.selectedLayerId = "";
    this.showGuidingMsg = true;
    this.submitNewReportsMessage = "";
    this.updateMapPosition = false;
    this.reportingArea = false;
    this.reportingAreaLayer = "";
    this.reportingAreaMessage = "";
    this.showSketchWidgets = false;
    this.allowMultipleCreation = false;
    this.popupEnabled = false;
    this.showLayerVisibilityMsg = false;
    this.enablePhotoLocation = false;
    this.aiImageExtraction = [];
    this._currentPage = "templatePicker";
    this._editorLoading = false;
    this._inValidGeomtryDrawn = false;
    this._selectedImageBase64 = "";
    this._imageAnalysisFailed = false;
    this._translations = useT9n({ name: "create-feature", blocking: true });
    this._addingAttachment = false;
    this._uploadedImage = null;
    this._calciteNotice = createRef();
    this._isSubmitBtnClicked = false;
    this._mapViewContainer = createRef();
    this._searchDiv = createRef();
    this._inputImageForAI = createRef();
    this._guidingMessageRefNode = createRef();
    this._abortController = new AbortController();
    this.success = createEvent();
    this.fail = createEvent();
    this.drawComplete = createEvent();
    this.editingLocation = createEvent();
    this.editingAttachment = createEvent();
    this.progressStatus = createEvent();
    this.modeChanged = createEvent();
  }
  static {
    this.properties = { customizeSubmit: [5, {}, { type: Boolean }], enableSearch: [5, {}, { type: Boolean }], enableSnapping: [5, {}, { type: Boolean }], floorLevel: 1, formElements: 1, isMobile: [5, {}, { type: Boolean }], mapView: [0, {}, { attribute: false }], searchConfiguration: [0, {}, { attribute: false }], selectedLayerId: 1, showGuidingMsg: [5, {}, { type: Boolean }], submitNewReportsMessage: 1, updateMapPosition: [5, {}, { type: Boolean }], reportingArea: [5, {}, { type: Boolean }], reportingAreaLayer: 1, reportingAreaMessage: 1, showSketchWidgets: [5, {}, { type: Boolean }], allowMultipleCreation: [5, {}, { type: Boolean }], popupEnabled: [5, {}, { type: Boolean }], showLayerVisibilityMsg: [5, {}, { type: Boolean }], enablePhotoLocation: [5, {}, { type: Boolean }], aiImageExtraction: [0, {}, { attribute: false }], _currentPage: [16, {}, { state: true }], _editorLoading: [16, {}, { state: true }], _inValidGeomtryDrawn: [16, {}, { state: true }], _selectedImageBase64: [16, {}, { state: true }], _imageAnalysisFailed: [16, {}, { state: true }], _translations: [16, {}, { state: true }] };
  }
  static {
    this.styles = styles;
  }
  static {
    this.shadowRootOptions = noShadowRoot;
  }
  willUpdate(changes) {
    if (changes.has("mapView") && this.hasUpdated) {
      void this.mapViewWatchHandler();
    }
    if (changes.has("isMobile") && this.hasUpdated) {
      void this.isMobileHandler();
    }
    if (changes.has("_editorLoading") && (this.hasUpdated || this._editorLoading !== false)) {
      void this._editorLoadingWatchHandler(this._editorLoading);
    }
  }
  async mapViewWatchHandler() {
    this.mapView && await this.mapView.when(async () => {
      if (this._imageAnalysisInfo && !this._imageAnalysisInfo.canUseAI) {
        await this.init();
      }
    });
  }
  async isMobileHandler() {
    this.modeChanged.emit();
  }
  async _editorLoadingWatchHandler(v) {
    if (v) {
      this._container?.classList.add("display-none");
      if (this._selectedLayer?.isTable) {
        if (this._selectedLayer.templates && this._editor) {
          const template = this._selectedLayer.templates[0];
          const creationInfo = {
            layer: this._selectedLayer,
            template
          };
          await this._editor.startCreateFeaturesWorkflowAtFeatureCreation(creationInfo);
          await this.hideEditorsElements();
        }
      } else {
        await this.startCreate();
      }
      this._container?.classList.remove("display-none");
      this._editorLoading = false;
    }
  }
  async submit() {
    if (this._editor?.viewModel?.featureFormViewModel) {
      this._isSubmitBtnClicked = true;
      this._editor.viewModel.featureFormViewModel.submit();
    }
  }
  async refresh(floorLevel) {
    if (this._editor) {
      if (floorLevel) {
        await this._setFloorLevel(floorLevel);
      } else {
        if (this.reportingArea && this.reportingAreaLayer && this._currentPage !== "drawing") {
          await this.queryIntersectingFeatures();
        } else if (this._currentPage !== "drawing") {
          this._inValidGeomtryDrawn = false;
          this.drawComplete.emit(this._inValidGeomtryDrawn);
        }
      }
    }
  }
  async showForm() {
    this.progressStatus.emit(100);
    this._container?.classList.remove("display-none");
    this._mapViewContainer.value?.classList?.replace("show-map", "hide-map");
    this._currentPage = "featureForm";
  }
  async load() {
    this._imageAnalysisInfo = await this._getImageAnalysisInfo();
    this._currentPage = this._imageAnalysisInfo.canUseAI ? "chooseReportType" : "templatePicker";
  }
  async loaded() {
    if (this._imageAnalysisInfo && !this._imageAnalysisInfo.canUseAI) {
      await this.init();
    }
  }
  async updated() {
    if (this.isMobile && this.updateMapPosition) {
      const customHeight = this._currentPage === "drawing" ? 80 : 30;
      const searchDiv = this.enableSearch ? this._searchDiv.value?.offsetHeight : 0;
      await this._calciteNotice.value?.componentOnReady();
      const calciteNotice = this._calciteNotice.value?.offsetHeight || 0;
      const top = calciteNotice + searchDiv + customHeight;
      if (this._mapViewContainer.value) {
        this._mapViewContainer.value.style.top = `${top}px`;
      }
    }
    if (this.reportingAreaMessage && this._guidingMessageRefNode.value?.children[0]) {
      this._guidingMessageRefNode.value.children[0].style.margin = "0px";
    }
  }
  disconnectedCallback() {
    super.disconnectedCallback();
    if (this._editor) {
      if (this._editor.viewModel.sketchViewModel) {
        this._editor.viewModel.sketchViewModel?.destroy();
      }
      this._editor.destroy();
      if (this.enableSnapping && this.mapView?.ui.view) {
        (this.mapView?.ui.view).grid = null;
      }
    }
  }
  render() {
    console.log("step through here for the AI issue");
    const showSearchWidget = this._currentPage === "drawing" || this._currentPage === "editing" ? "" : "display-none";
    const loaderClass = this._editorLoading ? "" : "display-none";
    const featureFormClass = this._editorLoading ? "display-none" : "";
    const mobileMapClass = this.isMobile && this.updateMapPosition ? "show-map" : "display-none";
    const noticeKind = this._inValidGeomtryDrawn ? "danger" : "success";
    const icon = this._inValidGeomtryDrawn ? "exclamation-mark-triangle" : "lightbulb";
    const showLayerVisibilityGuidingMsgAtTemplatePickerPage = this.showLayerVisibilityMsg && this._currentPage === "templatePicker";
    const showGuidingMsg = this.showGuidingMsg || showLayerVisibilityGuidingMsgAtTemplatePickerPage;
    let guidingMsg = this._translations.chooseCategoryMsg;
    const showPanel = this._imageAnalysisInfo?.canUseAI && ["chooseReportType", "analyzingImage", "imageUpload"].includes(this._currentPage);
    if (this._inValidGeomtryDrawn) {
      guidingMsg = this.reportingAreaMessage || this._translations.reportOutsideAreaMessage;
    } else if (this._currentPage === "drawing" || this._currentPage === "editing") {
      guidingMsg = this._translations.provideLocationMsg;
    } else if (this._currentPage === "featureForm") {
      guidingMsg = this._imageAnalysisInfo?.results?.filter((res) => res.success).length ? this._translations.formReviewMsg : this._translations.provideDetailsMsg;
    } else if (showLayerVisibilityGuidingMsgAtTemplatePickerPage) {
      guidingMsg = this._translations.enableFeatureTemplatesMessage;
    }
    return html`${this._imageAnalysisFailed && html`<calcite-alert auto-close icon=x-octagon kind=danger label @calciteAlertClose=${() => {
      this._imageAnalysisFailed = false;
    }} open placement=top><div slot=title>${this._translations.error}</div><div slot=message>${this._translations.imageExtractionError}</div></calcite-alert>` || ""}${showPanel && html`<calcite-panel>${this._currentPage === "chooseReportType" && this._getReportTypePage() || ""}${this._currentPage === "imageUpload" && this._aiImageExtractionPage() || ""}${this._currentPage === "analyzingImage" && this._getAnalyzingImagePage() || ""}</calcite-panel>` || ""}${!showPanel && html`${showGuidingMsg && html`<calcite-notice class="notice-msg" .icon=${icon} .kind=${noticeKind} open ${ref(this._calciteNotice)}><div slot=message .innerHTML=${guidingMsg ?? ""} ${ref(this._guidingMessageRefNode)}></div></calcite-notice>` || ""}${this._selectedImageBase64 && this._currentPage === "featureForm" && html`<div class="image-preview-container"><calcite-label>${this._translations.photo}</calcite-label><img class="width-full" src=${this._selectedImageBase64 ?? nothing}></div>` || ""}<calcite-loader class=${safeClassMap(loaderClass)} label scale=s></calcite-loader>${this._currentPage === "featureForm" && this.isMobile && html`<calcite-button appearance=transparent class="edit-location-btn" icon-start=pin @click=${this.editLocation}>${this._translations.editLocationLabel}</calcite-button>` || ""}<div class=${safeClassMap(featureFormClass)} id=feature-form></div>${this.enableSearch && html`<div class=${`search-widget ${showSearchWidget} ${featureFormClass}`} id=search-widget-ref ${ref(this._searchDiv)}></div>` || ""}` || ""}<div class=${safeClassMap(mobileMapClass)} ${ref(this._mapViewContainer)}></div>`;
  }
  async init() {
    if (this.mapView && this.selectedLayerId) {
      this._updatedMapView = this.mapView;
      await (this.isMobile && this.updateMapPosition ? this.createMobileMapView() : this._loadWidgets());
    }
  }
  async createMobileMapView() {
    if (this._mapViewContainer.value && this.mapView) {
      this._mapViewContainer.value.classList.add("hide-map");
      await new MapView({
        map: this.mapView.map,
        container: this._mapViewContainer.value,
        zoom: this.mapView.zoom,
        center: this.mapView.center,
        popupEnabled: this.popupEnabled
      }).when((view) => {
        this._updatedMapView = view;
        const home = new Home({
          view: this._updatedMapView
        });
        if (home) {
          this._updatedMapView.ui.add(home, "top-left");
        }
        void this._loadWidgets();
      }, (e) => {
        console.log(e);
      });
    }
  }
  async _loadWidgets() {
    await this.createEditorWidget();
    if (this.enableSearch) {
      await this.createSearchWidget();
    }
  }
  _getReportTypePage() {
    return html`<div class="report-selection-container"><calcite-label>${this._translations.createReportHeading}</calcite-label><calcite-card class="cursor-pointer" @click=${() => {
      this.progressStatus.emit(35);
      this._currentPage = "imageUpload";
    }}><div slot=description class="card-body-content"><calcite-icon icon=effects scale=m style="color: var(--calcite-ui-text-2)"></calcite-icon><div class="text-stack"><span class="option-title">${this._translations.aiImgExtractionLabel}</span><span class="option-description">${this._translations.aiAssistantDescription}</span></div></div></calcite-card><calcite-card class="cursor-pointer" @click=${() => {
      this._currentPage = "templatePicker";
      void this.init();
    }}><div slot=description class="card-body-content"><calcite-icon icon=pencil scale=m></calcite-icon><div class="text-stack"><span class="option-title">${this._translations.fillOutManually}</span><span class="option-description">${this._translations.startBlank}</span></div></div></calcite-card></div>`;
  }
  _aiImageExtractionPage() {
    const imageUploaded = this._selectedImageBase64 !== "";
    const infoText = imageUploaded ? this._translations.replaceImage : this._translations.imageUploadLimitHint;
    return html`<calcite-notice class="notice-msg" icon=effects kind=brand open><div slot=message>${this._translations.aiAssistantProcessingHint}</div></calcite-notice><div class="padding-10"><calcite-label><div>${this._translations.photo}<span style="color: var(--calcite-color-status-danger)">*</span></div><calcite-input type=file accept=image/* @calciteInputInput=${this._onImageUpload} ${ref(this._inputImageForAI)}></calcite-input></calcite-label><div class="info-container"><calcite-icon icon=information scale=s></calcite-icon><span>${infoText}</span></div>${imageUploaded && html`<img class="width-full" src=${this._selectedImageBase64 ?? nothing}>` || ""}</div><div slot=footer class="upload-img-footer-container"><calcite-button width=full .disabled=${!imageUploaded} id=next-btn @click=${this._analyzeImage}>${this._translations.next}</calcite-button><calcite-button width=full appearance=outline kind=brand @click=${() => this.modeChanged.emit()}>${this._translations.cancel}</calcite-button></div>`;
  }
  _getAnalyzingImagePage() {
    return html`<div class="analysis-wrapper"><calcite-label layout=inline><calcite-icon class="analyzing-icon" icon=effects scale=s></calcite-icon><span>${this._translations.analyzingImage}</span></calcite-label><calcite-button class="skip-btn" appearance=transparent @click=${() => {
      this._abortController.abort();
      this._currentPage = "templatePicker";
    }}>${this._translations.skip}</calcite-button></div>`;
  }
  _onImageUpload(evt) {
    const imgInput = evt.target;
    if (imgInput) {
      const file = imgInput.files[0];
      this._uploadedImage = file;
      const reader = new FileReader();
      reader.onload = (e) => {
        this._selectedImageBase64 = e.target?.result;
      };
      reader.readAsDataURL(file);
    }
  }
  async _analyzeImage() {
    this._abortController = new AbortController();
    const signal = this._abortController.signal;
    const imageAnalysisInfo = await this._getImageAnalysisInfo();
    if (!imageAnalysisInfo.canUseAI || !imageAnalysisInfo.url || !this._inputImageForAI.value?.files?.length) {
      this._imageAnalysisFailed = true;
      console.error(this._translations.error);
      this._resetImageAnalysisInfo();
      await this.init();
      return;
    }
    try {
      this._currentPage = "analyzingImage";
      this.progressStatus.emit(45);
      const selectedImage = this._inputImageForAI.value.files[0];
      const base64Image = await new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onloadend = () => resolve(reader.result);
        reader.onerror = reject;
        if (this._inputImageForAI.value) {
          reader.readAsDataURL(selectedImage);
        }
      });
      if (this.enablePhotoLocation) {
        const imageLocation = await exifr.gps(selectedImage);
        if (imageLocation?.longitude && imageLocation.latitude && this.mapView?.spatialReference) {
          const point = new Point({
            longitude: imageLocation.longitude,
            latitude: imageLocation.latitude,
            spatialReference: new SpatialReference({ wkid: 4326 })
          });
          const projectedPoint = await projectToSpatialReference(point, this.mapView.spatialReference);
          if (this._imageAnalysisInfo) {
            this._imageAnalysisInfo.imageLocation = projectedPoint;
          }
        }
      }
      const dataForImageExtraction = [];
      this.aiImageExtraction.forEach((config) => {
        if (config?.field && config.prompt && config.id === this.selectedLayerId) {
          dataForImageExtraction.push({ key: config.field, context: config.prompt });
        }
      });
      if (dataForImageExtraction.length) {
        const reqBody = {
          input: base64Image,
          data: dataForImageExtraction
        };
        const response = await esriRequest(imageAnalysisInfo.url, {
          method: "post",
          headers: {
            "Content-Type": "application/json",
            "x-esri-authorization": `Bearer ${imageAnalysisInfo.token}`
          },
          body: JSON.stringify(reqBody),
          responseType: "json",
          signal
        });
        if (this._imageAnalysisInfo) {
          this._imageAnalysisInfo.results = response.data.results;
        }
      }
      await this.init();
    } catch (error) {
      if (error.name === "AbortError") {
        console.error("Aborted", error);
      } else {
        this._imageAnalysisFailed = true;
        console.error("Analyzing failed", error);
      }
      this._resetImageAnalysisInfo();
      void this.init();
    }
  }
  _resetImageAnalysisInfo() {
    const emptyInfo = {
      url: "",
      token: "",
      canUseAI: false,
      imageLocation: void 0,
      results: []
    };
    this._imageAnalysisInfo = emptyInfo;
  }
  async _getImageAnalysisInfo() {
    const imageAnalysisInfo = {
      url: "",
      token: "",
      canUseAI: false
    };
    const enableAI = this.aiImageExtraction.some((config) => config?.field && config.prompt && config.id === this.selectedLayerId);
    if (enableAI) {
      const portalSelf = (this.mapView?.map).portalItem.portal;
      if (portalSelf) {
        const portalSettings = await portalSelf.fetchSettings();
        const aiUtilityServices = portalSelf?.helperServices.aiUtilityServices;
        if (aiUtilityServices?.url && aiUtilityServices?.api?.image_analyze) {
          imageAnalysisInfo.url = aiUtilityServices.url + aiUtilityServices.api.image_analyze;
        }
        if (portalSelf.credential) {
          imageAnalysisInfo.token = portalSelf.credential.token;
        }
        if (portalSettings?.aiAssistantsEnabled && !portalSettings.blockBetaApps && portalSelf?.user?.privileges?.includes("portal:user:useAIAssistants")) {
          imageAnalysisInfo.canUseAI = true;
        }
      }
    }
    return imageAnalysisInfo;
  }
  async createEditorWidget() {
    if (this._editor) {
      this._editor.destroy();
    }
    const layerInfos = [];
    this._container = document.createElement("div");
    this._container?.classList.add("display-none");
    if (!this.enableSnapping) {
      this._container.classList.add("hide-editor-toolbar");
    }
    const allMapLayers = this._updatedMapView && await getAllFeatureLayers(this._updatedMapView);
    const selectedLayer = this.mapView && await getLayerOrTable(this.mapView, this.selectedLayerId);
    if (selectedLayer) {
      this._selectedLayer = selectedLayer;
      if (!this._selectedLayer?.isTable && allMapLayers) {
        allMapLayers.forEach((layer) => {
          layerInfos.push({
            layer,
            enabled: layer?.type === "feature" && layer?.id === this.selectedLayerId,
            addEnabled: true,
            // default is true, set to false to disable the ability to add a new feature
            updateEnabled: false,
            // if true, enable ability to edit an existing feature
            deleteEnabled: false
            // default is true, set to false to disable the ability to delete features
          });
        });
      }
    }
    this._editor = new Editor({
      view: this._updatedMapView,
      layerInfos,
      visibleElements: {
        settingsMenu: this.enableSnapping,
        snappingControls: this.enableSnapping,
        createFeaturesSection: true,
        editFeaturesSection: false,
        flow: true,
        sketch: this.showSketchWidgets && this._selectedLayer?.geometryType !== "point"
      },
      container: this._container
    });
    if (this._mapViewContainer.value) {
      this.el.insertBefore(this._container, this._mapViewContainer.value);
    } else {
      this.el.appendChild(this._container);
    }
    if (this._selectedLayer?.isTable) {
      this._editorLoading = true;
    }
    if (this._editor) {
      const attachmentHandle = reactiveUtils.watch(() => this._editor?.viewModel.state, (state) => {
        if (state === "adding-attachment" || state === "editing-attachment") {
          this._addingAttachment = true;
          this.editingAttachment.emit(true);
        } else {
          if (this._addingAttachment) {
            this.editingAttachment.emit(false);
            this._addingAttachment = false;
          }
        }
      });
      attachmentHandle && this._editor.viewModel.addHandles(attachmentHandle);
      const handle = reactiveUtils?.watch(() => this._editor?.viewModel.featureTemplatesViewModel.state, (state) => {
        if (state === "ready" && this._editor?.viewModel?.activeWorkflow?.type !== "create-features") {
          this.progressStatus.emit(50);
          this._editorLoading = true;
        }
      });
      handle && this._editor.viewModel.addHandles(handle);
      const formHandle = reactiveUtils?.watch(() => this._editor?.viewModel.featureFormViewModel?.state, (state) => {
        if (state === "ready" && this._editor?.viewModel.featureFormViewModel && this._currentPage !== "editing") {
          this._mapViewContainer.value?.classList?.replace("show-map", "hide-map");
          this._editor.viewModel.featureFormViewModel.addHandles(this._editor.viewModel.featureFormViewModel.on("submit", this.submitted.bind(this)));
          setTimeout(() => {
            void this._setFloorLevel(this.floorLevel);
            if (this._imageAnalysisInfo?.results) {
              this._setAttributeValuesFromImageAnalysis();
            }
          }, 200);
          if (!this.allowMultipleCreation && this._editor.activeWorkflow) {
            this._editor.activeWorkflow.data.creationInfo.maxFeatures = 1;
          }
          this._currentPage = "featureForm";
          this.progressStatus.emit(100);
          this.drawComplete.emit(false);
        }
      });
      formHandle && this._editor.viewModel.addHandles(formHandle);
      const createFeatureHandle = reactiveUtils.watch(() => this._editor?.viewModel.state, (state) => {
        if (state === "creating-features" && this._editor?.viewModel.featureFormViewModel) {
          if (this._editor.viewModel.featureFormViewModel.state === "disabled") {
            this._mapViewContainer.value?.classList.replace("hide-map", "show-map");
            if (this._selectedLayer && !this._selectedLayer.isTable) {
              this._currentPage = "drawing";
              if (this._editor.viewModel.sketchViewModel?.createGraphic && this._imageAnalysisInfo?.imageLocation) {
                void this._updatedMapView?.goTo({ center: this._imageAnalysisInfo.imageLocation });
                if (this._selectedLayer.geometryType === "point") {
                  void this._initializeSketchPoint(this._imageAnalysisInfo.imageLocation.clone());
                }
              }
            }
          }
        }
      });
      createFeatureHandle && this._editor.viewModel.addHandles(createFeatureHandle);
      this._editor.on("sketch-create", async (e) => {
        if (e.detail.state === "complete") {
          this._drawnGeometry = e.detail.graphic?.geometry;
          if (this.reportingArea && this.reportingAreaLayer) {
            await this.queryIntersectingFeatures();
          }
        }
      });
      let debounceTimer;
      this._editor.on("sketch-update", (e) => {
        clearTimeout(debounceTimer);
        debounceTimer = window.setTimeout(async () => {
          this._drawnGeometry = e.detail.graphics[0].geometry;
          if (this.reportingArea && this.reportingAreaLayer) {
            await this.queryIntersectingFeatures();
          }
        }, 50);
      });
    }
  }
  async queryIntersectingFeatures() {
    const polygonLayer = this.mapView && await getLayerOrTable(this.mapView, this.reportingAreaLayer);
    if (polygonLayer) {
      const query = polygonLayer.createQuery();
      query.geometry = this._drawnGeometry;
      query.spatialRelationship = "intersects";
      const intersectingCount = await polygonLayer.queryFeatureCount(query);
      const nonValidGeomtryDrawn = intersectingCount === 0;
      this._inValidGeomtryDrawn = nonValidGeomtryDrawn;
      this.drawComplete.emit(this._inValidGeomtryDrawn);
    }
  }
  editLocation() {
    this.progressStatus.emit(75);
    this.editingLocation.emit();
    this._container?.classList.add("display-none");
    this._mapViewContainer.value?.classList.replace("hide-map", "show-map");
    this._currentPage = "editing";
  }
  async startCreate() {
    await this.hideEditorsElements();
    return new Promise((resolve, reject) => {
      if (this._editor?.viewModel.featureTemplatesViewModel.items?.length) {
        const items = this._editor.viewModel.featureTemplatesViewModel.items[0].items;
        this._editor.viewModel.featureTemplatesViewModel.addHandles(this._editor.viewModel.featureTemplatesViewModel.on("select", () => {
          this.progressStatus.emit(75);
          setTimeout(() => {
            this.hideEditorsElements().then(() => {
              resolve({});
            }, (e) => reject(e));
          }, 700);
        }));
        if (items.length === 1) {
          this._editor.viewModel.featureTemplatesViewModel.select(items[0]);
        }
        const resolvePromise = items.length > 1;
        this.hideEditorsElements().then(() => {
          if (resolvePromise) {
            this._currentPage = "templatePicker";
            resolve({});
          }
        }, (e) => resolvePromise && reject(e));
      }
    });
  }
  async createSearchWidget() {
    if (this._updatedMapView) {
      let searchOptions = {
        view: this._updatedMapView
      };
      if (this.searchConfiguration) {
        const searchConfiguration = this._getSearchConfig(this.searchConfiguration, this._updatedMapView);
        searchOptions = {
          ...searchConfiguration
        };
      }
      this._search = new Search(searchOptions);
      if (!this._search) {
        return;
      }
      this._search.container = "search-widget-ref";
      this._search.popupEnabled = false;
      this._search.resultGraphicEnabled = false;
      let pointGeometry = void 0;
      this._search.viewModel.addHandles(this._search.on("search-complete", (e) => {
        if (e.results[0].results && e.results[0].results[0]) {
          e.results[0].results[0].extent && void this._updatedMapView?.goTo(e.results[0].results[0].extent);
          if (this._selectedLayer?.geometryType === "point") {
            pointGeometry = e.results[0].results[0]?.feature.geometry;
          }
        }
      }));
      const createFeatureHandle = reactiveUtils.watch(() => this._search?.viewModel.state, (state) => {
        if (state === "ready") {
          setTimeout(() => {
            if (this._editor?.viewModel.sketchViewModel?.createGraphic && pointGeometry) {
              this._initializeSketchPoint(pointGeometry);
            } else if (this._editor?.viewModel.sketchViewModel && this._editor.viewModel.sketchViewModel.updateGraphics.length > 0 && pointGeometry) {
              const graphic = this._editor?.viewModel.sketchViewModel?.updateGraphics.getItemAt(0);
              if (graphic) {
                graphic.set("geometry", pointGeometry);
                void this._editor?.viewModel.sketchViewModel?.update(graphic);
                void this.hideEditorsElements();
              }
            }
          }, 100);
        }
      });
      createFeatureHandle && this._search.viewModel.addHandles(createFeatureHandle);
    }
  }
  async _initializeSketchPoint(pointGeometry) {
    if (this._editor?.viewModel.sketchViewModel?.createGraphic) {
      const graphic = this._editor.viewModel.sketchViewModel.createGraphic.set("geometry", pointGeometry);
      const graphicClone = graphic.clone();
      this._editor.viewModel.sketchViewModel.addGraphic(graphicClone);
      this._editor.viewModel.sketchViewModel.emit("create", {
        graphic: graphicClone,
        state: "complete",
        toolEventInfo: null,
        type: "create"
      });
      await this._editor.viewModel.sketchViewModel.update(graphicClone);
      void this.hideEditorsElements();
    }
  }
  _getSearchConfig(searchConfiguration, view) {
    const INCLUDE_DEFAULT_SOURCES = "includeDefaultSources";
    const sources = searchConfiguration.sources;
    if (sources && sources?.length > 0) {
      searchConfiguration[INCLUDE_DEFAULT_SOURCES] = false;
      sources.forEach((source) => {
        const isLayerSource = source.hasOwnProperty("layer");
        if (isLayerSource) {
          const layerSource = source;
          const layerId = layerSource.layer?.id;
          const layerFromMap = layerId ? view.map?.findLayerById(layerId) : "";
          const layerUrl = layerSource?.layer?.url;
          if (layerFromMap) {
            layerSource.layer = layerFromMap;
          } else if (layerUrl) {
            layerSource.layer = new FeatureLayer(layerUrl);
          }
        }
      });
      sources?.forEach((source) => {
        const isLocatorSource = source.hasOwnProperty("locator");
        if (isLocatorSource) {
          const locatorSource = source;
          if (locatorSource?.name === "ArcGIS World Geocoding Service") {
            const outFields = locatorSource.outFields || ["Addr_type", "Match_addr", "StAddr", "City"];
            locatorSource.outFields = outFields;
            locatorSource.singleLineFieldName = "SingleLine";
          }
          locatorSource.url = locatorSource.url;
          delete locatorSource.url;
        }
      });
    } else {
      searchConfiguration = {
        ...searchConfiguration,
        includeDefaultSources: true
      };
    }
    return searchConfiguration;
  }
  async _setFloorLevel(level) {
    if (!level) {
      return;
    }
    const layer = this._selectedLayer;
    const floorField = layer?.floorInfo?.floorField;
    if (floorField) {
      const layerField = layer.fields.find((field) => field.name === floorField);
      if (layerField && !layer?.formTemplate) {
        if (this._editor?.viewModel.featureFormViewModel) {
          this._editor.viewModel.featureFormViewModel.setValue(layerField.name, level);
          layerField.editable = false;
        }
      } else if (layer.formTemplate && this.formElements) {
        const floorInfoExpression = new ExpressionInfo({
          expression: `'${level}'`,
          name: "floor-info-test",
          title: "Floor Info",
          returnType: "string"
        });
        const levelIdFieldElement = new FieldElement({
          label: floorField,
          editableExpression: "false",
          fieldName: floorField,
          input: {
            type: "text-box",
            maxLength: 50,
            minLength: 0
          },
          valueExpression: floorInfoExpression.name
        });
        this._updatedMapView?.map.editableLayers.forEach((layer2) => {
          const orgElements = this.formElements.orgElements;
          const orgExpressionInfos = this.formElements.orgExpressionInfos;
          const elements = [...orgElements];
          elements.push(levelIdFieldElement);
          if (layer2.type === "feature") {
            const featureLayer = layer2;
            const floorInfoTemplate = new FormTemplate({
              title: featureLayer?.formTemplate?.title,
              description: featureLayer?.formTemplate?.description,
              elements,
              expressionInfos: [floorInfoExpression].concat(orgExpressionInfos)
            });
            layer2.formTemplate = floorInfoTemplate;
          }
        });
      }
    }
  }
  _setAttributeValuesFromImageAnalysis() {
    if (this._imageAnalysisInfo?.results) {
      this._imageAnalysisInfo.results.forEach((result) => {
        if (this._editor?.viewModel.featureFormViewModel && result.key && result.success) {
          this._editor.viewModel.featureFormViewModel.setValue(result.key, result.value);
        }
      });
    }
  }
  async hideEditorsElements() {
    if (!this.customizeSubmit) {
      return;
    }
    await this.timeout(700);
    this.el.querySelector(".esri-editor")?.querySelectorAll("calcite-flow-item")?.forEach((flowItem) => {
      const article = flowItem.shadowRoot?.querySelector("calcite-panel")?.shadowRoot?.querySelector("article");
      article?.querySelector("header")?.setAttribute("style", "display: none");
      article?.querySelector("footer")?.setAttribute("style", "display: none");
    });
  }
  async submitted(_evt) {
    let addAttachment = false;
    if (_evt.invalid.length) {
      this._isSubmitBtnClicked = false;
      return;
    }
    if (this._isSubmitBtnClicked) {
      this._isSubmitBtnClicked = false;
      try {
        if (this._editor?.activeWorkflow) {
          if (this._selectedLayer && this._selectedLayer.capabilities.data.supportsAttachment && this._selectedImageBase64) {
            addAttachment = true;
          }
          if (addAttachment) {
            const applyEditsHandler = this._selectedLayer?.on("edits", async (edits) => {
              if (edits.addedFeatures.length > 0) {
                const objectId = edits.addedFeatures[0].objectId;
                try {
                  if (this._uploadedImage && this._selectedLayer) {
                    const file = this._uploadedImage;
                    const form = new FormData();
                    form.set("keywords", "ai-image");
                    form.set("attachment", file);
                    form.append("f", "json");
                    const addedFeature = new Graphic({
                      attributes: {
                        [this._selectedLayer.objectIdField]: objectId
                      }
                    });
                    await this._selectedLayer.addAttachment(addedFeature, form);
                  }
                } catch (err) {
                  console.error("Attachment upload failed", err);
                }
                applyEditsHandler?.remove();
                this.success.emit();
              }
            });
          }
          await this._editor.activeWorkflow.commit();
          if (this._editor.viewModel.failures?.length) {
            this._editor.viewModel.failures.some((failure) => {
              if (failure.error) {
                throw failure.error;
              }
            });
          }
        }
      } catch (e) {
        this.fail.emit(e);
        return;
      }
      if (!addAttachment) {
        this.success.emit();
      }
    }
  }
  async timeout(delay) {
    return new Promise((resolve) => setTimeout(resolve, delay));
  }
}
customElement("create-feature", CreateFeature);
export {
  CreateFeature
};
