const [
  Point,
  Graphic,

  FeatureSet,
  LinearUnit,
  geoprocessor
] = await $arcgis.import([
  "@arcgis/core/geometry/Point.js",
  "@arcgis/core/Graphic.js",

  "@arcgis/core/rest/support/FeatureSet.js",
  "@arcgis/core/rest/support/LinearUnit.js",
  "@arcgis/core/rest/geoprocessor.js",
]);

// Calcite Web を使用した DOM 要素
const processLoader = document.getElementById("processLoader");
const errorPanel = document.getElementById("errorPanel");

// Scene 要素を取得
const sceneEl = document.querySelector("arcgis-scene");

await sceneEl.viewOnReady();

// エラー通知の表示位置を指定（CSS で display="none" と設定しているため、画面には表示されません）
sceneEl.view.ui.add(errorPanel, "bottom");

// 観測点を描画するためのマーカー シンボル
const markerSym = {
  type: "simple-marker",
  size: "14px",
  color: [240, 145, 153],
  outline: null
}

// 結果を描画するためのポリゴン シンボル
const fillSym = {
  type: "simple-fill",
  color: [255, 255, 0, 0.5],
  outline: null
}

/*
  ステップ：ジオプロセッサの準備
*/
const gpUrl =
  "https://sampleserver6.arcgisonline.com/arcgis/rest/services/Elevation/ESRI_Elevation_World/GPServer/Viewshed";

/*
  ステップ：空間参照の設定
*/
const options = {
  outSpatialReference: {
    wkid: 4326
  }
};

// シーンのクリックで観測点の追加 / ジオプロセッサの実行
sceneEl.addEventListener("arcgisViewClick", executeViewshedTask)

function executeViewshedTask(evt) {
  // グラフィックス レイヤーの初期化
  sceneEl.graphics.removeAll();
  
  // クリック地点の情報から、ジオメトリを作成
  const pointGeom = new Point({
    longitude: evt.detail.mapPoint.longitude,
    latitude: evt.detail.mapPoint.latitude
  });
  // 観測点をシーンに追加
  const inputPoint = new Graphic({
    geometry: pointGeom,
    symbol: markerSym
  });
  sceneEl.graphics.add(inputPoint);

  /*
    ステップ：1 つ目の入力パラメーターの準備
  */
  const featureSet = new FeatureSet({
    features: [inputPoint]
  });

  /*
    ステップ：2 つ目の入力パラメーターの準備
  */
  const vsDistance = new LinearUnit({
    distance: 5,
    units: "kilometers"
  });

  /*
    ステップ：JSON 形式のオブジェクトでジオプロセッサの入力パラメーターを作成
  */
  const gpParams = {
    Input_Observation_Point: featureSet,
    Viewshed_Distance: vsDistance
  };

  /*
    ステップ：ローディング パネルの表示
  */
  processLoader.style.display = "inline";

  /*
    ステップ：ジオプロセッサの実行
  */
  geoprocessor.execute(gpUrl, gpParams, options)
    .then(drawResult, errorFunc);

}

function drawResult(gpResults) {
  /*
    ステップ：結果からフィーチャの配列を取得
  */
  const viewshedResult = gpResults.results[0];
  const viewshedFeatureSet = viewshedResult.value;
  const viewshedFeatures = viewshedFeatureSet.features;

  /*
    ステップ：結果をループして各フィーチャにシンボルを定義して追加
  */
  const viewshedGraphics = viewshedFeatures.map((feature) => {
    feature.symbol = fillSym;
    return feature;
  });
  sceneEl.graphics.addMany(viewshedGraphics);

  // 検索結果にズーム
  sceneEl.goTo({
    target: viewshedGraphics,
    scale: sceneEl.scale,
    tilt: sceneEl.cameraTilt
  }, {
    duration: 1000
  });

  /*
    ステップ：ローディング パネルの非表示
  */
  processLoader.style.display = "none";
}

function errorFunc() {
  processLoader.style.display = "none";
  errorPanel.style.display = "inline";
}
