import { eventHnalder } from "@/common/app-template";
import { AppID } from "@/common/appids";
import { formatDateStr, today } from "@/common/datetime";
import { initMenuBox, setHeaderButton } from "@/common/header-button";
import { KintoneEvent, 値設定 } from "@/common/kintone-event";
import { makeRecordData } from "@/common/rest-api-client";
import { Message } from "@/exception";
import { EmailID, sendEmail } from "@/mypage/メール";
import { makeReceipt } from "@/mypage/領収証発行";
import bulkRequest from "@/rest-api/bulk";
import { get定期申込予約 } from "@/rest-api/定期申込予約";
import { get顧客マスタ } from "@/rest-api/顧客マスタ";
import { 入金予定結果, 入金予定結果フィールド名 } from "@/types/入金予定結果";
import { 定期申込予約フィールド名 } from "@/types/定期申込予約";
import { 顧客マスタフィールド名 } from "@/types/顧客マスタ";
import { KintoneRestAPIClient } from "@kintone/rest-api-client";
import { addDays, format, setHours } from "date-fns";
import Swal from "sweetalert2";

const client = new KintoneRestAPIClient();

const 残金設定 = (record: 入金予定結果) => {
  record[入金予定結果フィールド名.残金].value = (() => {
    const amount =
      Number(record[入金予定結果フィールド名.支払予定金額].value ?? 0) -
      Number(record[入金予定結果フィールド名.入金額].value ?? 0);
    return String(amount);
  })();
};

const 承認メール送信 = (record: 入金予定結果) => {
  return sendEmail(EmailID.申込承認, {
    season_ticket_contract_entry_record_no: Number(
      record[入金予定結果フィールド名.初回振り込み関連申込レコード番号].value
    ),
  });
};

const 領収証作成 = () => {
  return makeReceipt([Number(kintone.app.record.getId())]);
};

const テスト充当 = async (record: 入金予定結果) => {
  await client.record.updateRecord({
    app: AppID.入金予定結果,
    id: kintone.app.record.getId() ?? "",
    record: makeRecordData({
      [入金予定結果フィールド名.入金日]: format(new Date(), "yyyy-MM-dd"),
      [入金予定結果フィールド名.入金額]:
        record[入金予定結果フィールド名.支払予定金額].value,
      [入金予定結果フィールド名.残金]: "0",
    }),
  });

  await 領収証作成();

  if (
    !!record[入金予定結果フィールド名.初回振り込み関連申込レコード番号].value
  ) {
    await 承認メール送信(record);
  }

  Swal.fire({
    title: "テスト充当完了",
    icon: "success",
    timer: 1000,
    timerProgressBar: true,
  }).then((result) => {
    location.reload();
  });
};

const getCallbackFillAmount = (record: 入金予定結果) => {
  return async () => {
    Swal.fire({
      title: "テスト充当",
      text: "！注意！テスト用の機能",
      showCancelButton: true,
      confirmButtonText: "実行",
      cancelButtonText: "キャンセル",
    }).then((result) => {
      if (result.isConfirmed) {
        テスト充当(record);
      }
    });
  };
};

// クエリパラメータよりフィールドに値をセットする
const setData = (event: any, targets: string[]) => {
  const param = new URLSearchParams(location.search.replace("?", ""));
  targets.forEach((target) => {
    const value = param.get(target);
    if (value === null) return;
    値設定(event, target, value, true);
  });
};
(() => {
  console.info("script build at " + process.env.BUILD_TIME);

  kintone.events.on(
    [KintoneEvent.詳細.レコード詳細画面を表示した後],
    eventHnalder(async (event) => {
      const currentRecord = event.record as 入金予定結果;
      await initMenuBox();
      // 各種ボタンの設置
      if (currentRecord[入金予定結果フィールド名.残金].value !== "0") {
        if (currentRecord.parking_name.value.startsWith("TP")) {
          setHeaderButton("テスト充当", getCallbackFillAmount(currentRecord));
        }
      }
    })
  );

  const 初回請求金額確定チェック = (record: 入金予定結果) => {
    if (!record.first_payment_entry_record_no.value) {
      throw new Message("初回振り込み関連申込レコード番号が入力されていません");
    }

    // 申込の初回振り込み情報を入力する
    const F = 定期申込予約フィールド名;
    const 支払予定日 = record.payment_plan_date.value;
    if (!支払予定日) {
      throw new Message("支払予定日が入力されていません");
    }
    const 支払予定金額 = record.payment_plan_amount.value;
    if (!支払予定金額) {
      throw new Message("支払予定金額が入力されていません");
    }
  };
  const 初回請求金額確定 = async (record: 入金予定結果) => {
    初回請求金額確定チェック(record);

    const 申込 = await get定期申込予約(
      record.first_payment_entry_record_no.value
    );

    // 申込の初回振り込み情報を入力する
    const F = 定期申込予約フィールド名;
    const 支払予定日 = record.payment_plan_date.value ?? "";
    const 支払予定金額 = record.payment_plan_amount.value ?? "";

    const 日割り金額 = Number(支払予定金額) - Number(申込.定期駐車料金.value);
    const 日割り月 = (() => {
      if (日割り金額 === 0) return "";
      let month = Number(record.target_month.value) - 1;
      if (month === 0) {
        month = 12;
      }
      return String(month);
    })();

    bulkRequest.update({
      app: AppID.定期申込予約,
      id: record.first_payment_entry_record_no.value,
      record: makeRecordData({
        [F.振込期日]: 支払予定日,
        [F.初回振り込み合計額]: 支払予定金額,
        [F.請求対象分_月]: record.target_month.value,
        [F.請求対象分_金額]: 申込.定期駐車料金.value,
        [F.日割り分_金額]: String(日割り金額),
        [F.日割り分_月]: 日割り月,
      }),
    });
    await bulkRequest.save();
  };

  kintone.events.on(
    KintoneEvent.追加.レコード追加画面を表示した後,
    eventHnalder(async (event) => {
      const record = event.record as 入金予定結果;
      setData(event, [
        入金予定結果フィールド名.車室情報管理レコード番号,
        入金予定結果フィールド名.初回振り込み関連申込レコード番号,
        入金予定結果フィールド名.支払予定金額,
        入金予定結果フィールド名.支払種別,
        入金予定結果フィールド名.支払方法,
      ]);

      残金設定(record);
      return event;
    })
  );

  kintone.events.on(
    KintoneEvent.追加.保存するとき,
    eventHnalder(async (event: any) => {
      const record = event.record as 入金予定結果;
      // 初回請求確定時にはメールを送信する
      if (
        record[入金予定結果フィールド名.初回振り込み関連申込レコード番号].value
      ) {
        await 初回請求金額確定(record);
      }
    })
  );
  kintone.events.on(
    KintoneEvent.追加.保存に成功した後,
    eventHnalder(async (event: any) => {
      const record = event.record as 入金予定結果;
      // 初回請求確定時にはメールを送信する
      if (
        record[入金予定結果フィールド名.初回振り込み関連申込レコード番号].value
      ) {
        // メール送信
        sendEmail(EmailID.申込受付, {
          season_ticket_contract_entry_record_no: Number(
            record[入金予定結果フィールド名.初回振り込み関連申込レコード番号]
              .value
          ),
        });

        // 口座振替登録催促日時を設定する
        const 口座登録催促日時 = (() => {
          return formatDateStr(setHours(addDays(today(), 5), 9));
        })();
        const 顧客 = await get顧客マスタ({
          顧客コード: Number(record.customer_code.value),
        });
        bulkRequest.update({
          app: AppID.顧客マスタ,
          id: 顧客?.$id.value,
          record: makeRecordData({
            [顧客マスタフィールド名.口座登録催促予定日時]: 口座登録催促日時,
          }),
        });
      }
    })
  );

  kintone.events.on(
    [
      KintoneEvent.追加.フィールドの値を変更したとき(
        入金予定結果フィールド名.支払予定金額
      ),
      KintoneEvent.追加.フィールドの値を変更したとき(
        入金予定結果フィールド名.入金額
      ),
      KintoneEvent.編集.フィールドの値を変更したとき(
        入金予定結果フィールド名.支払予定金額
      ),
      KintoneEvent.編集.フィールドの値を変更したとき(
        入金予定結果フィールド名.入金額
      ),
    ],
    (event) => {
      const record = event.record as 入金予定結果;
      残金設定(record);
      return event;
    }
  );
})();
