
(function () {
  "use strict";
  const FIELD_CODE = "ユニークキー";

  // ------------------- 画面表示時の処理 -------------------
  // 詳細画面/印刷画面表示時の処理
  kintone.events.on(['app.record.detail.show', 'app.record.print.show'], function (event) {
    hideField(FIELD_CODE);
    return event;
  });

  // 編集画面/新規作成画面表示時の処理
  kintone.events.on(['app.record.edit.show', 'app.record.create.show'], function (event) {
    if (event.type === "app.record.create.show") {
      // レコード複製作成時には既存のユニークキーを削除する
      event.record[FIELD_CODE].value = "";
    }
    hideField(FIELD_CODE);
    return event;
  });

  // 一覧画面での編集モード表示時の処理
  kintone.events.on(['app.record.index.edit.show'], (event) => {
    disableField(event.record, FIELD_CODE);
    return event
  })

  function hideField(fieldCode) {
    kintone.app.record.setFieldShown(fieldCode, false);
  }

  function disableField(record, fieldCode) {
    record[fieldCode]['disabled'] = true;
  }

  // ------------------- 新規保存時の処理 -------------------
  kintone.events.on(['app.record.create.submit.success'], async function (event) {
    // 新規作成したレコードのIDをユニークキーとして設定
    const api = new KintoneRestAPIClient();
    await updateUniqueKey(api, event);
    return event;
  });

  // ------------------- 編集保存時の処理 -------------------
  // 関連アプリ情報の定義
  // uniqueKeyField 園児台帳を参照するフィールドコード
  // dateField 日付範囲指定用フィールド
  const LOOKUP_APPS_INFO = {
    "園児別出欠簿入力": {
      uniqueKeyField: "園児ユニークキー",
      dateField: "登園日"
    }
  }

  async function updateUniqueKey(api, event) {
    await api.record.updateRecord({
      app: env["園児台帳"].appId,
      id: event.recordId,
      record: {
        [FIELD_CODE]: {
          value: event.recordId
        }
      }
    });
  }

  // 保存成功後イベント処理（編集/一覧編集）
  kintone.events.on([
    'app.record.edit.submit.success',
    'app.record.index.edit.submit.success'
  ], async (event) => {
    loading(true, 'データを反映中...');

    const api = new KintoneRestAPIClient();
    const uniqueKeyValue = event.record[FIELD_CODE]['value'];
    const yearRange = getYearRange()

    // レガシーキー判別（旧方式： 出席番号＋学年+クラス+名前）
    const isLegacyUniqueKey = (event.recordId + "") !== uniqueKeyValue
    let newKeyGetter;

    if (isLegacyUniqueKey) {
      // 旧キー方式から移行する処理：レコードIDを使用するように変更し、関連する全ての参照箇所を更新する必要があります
      await updateUniqueKey(api, event);
      newKeyGetter = () => event.recordId
    }

    for (const appName of Object.keys(LOOKUP_APPS_INFO)) {
      // 対象年度の関連レコードを取得
      const records = await getAllUpdatedRecords(api, appName, uniqueKeyValue, yearRange, newKeyGetter)
      if (!records || records.length === 0) {
        continue;
      }

      try {
        const updateResult = await api.record.updateAllRecords({
          app: env[appName].appId,
          records
        });

        updateResult.yearRange = yearRange;
        showSuccessDialog(updateResult)
      } catch (e) {
        showError(true, `アプリ「${appName}」のデータ上書処理中にエラーが発生しました\n - ` + e);
      }
    }

    loading(false)
    return event;
  });

  async function getAllUpdatedRecords(api, appName, uniqueKeyValue, yearRange, newKeyGetter) {
    const uniqueKeyField = LOOKUP_APPS_INFO[appName].uniqueKeyField
    const dateField = LOOKUP_APPS_INFO[appName].dateField
    newKeyGetter = newKeyGetter || (record => record[uniqueKeyField].value)

    try {
      const records = await api.record.getAllRecordsWithId({
        app: env[appName].appId,
        condition: `${uniqueKeyField} = "${uniqueKeyValue}" and ${dateField} >= "${yearRange.start}" and ${dateField} <= "${yearRange.end}"`
      });
      return records.map((record) => {
        return {
          id: record.$id.value,
          record: {
            [uniqueKeyField]: {
              value: newKeyGetter(record)
            }
          }
        };
      });
    } catch (e) {
      showError(true, `アプリ「${appName}」のデータ上書のためにデータを取得中にエラーが発生しました\n - ` + e);
    }
  }

  function showSuccessDialog(updateResult) {
    const contentEl = document.createElement('div');
    contentEl.style.fontSize = '16px';
    contentEl.innerHTML = `${updateResult.yearRange.start.split("-")[0]}年度の${updateResult.records.length}件のデータを更新しました。`;

    showDialog({
      title: '更新が完了しました',
      content: contentEl,
      cancel: false
    });
  }

})();