<template>
  <div>
    <v-row dense justify="center">
      <v-dialog
        v-model="isVisible"
        scrollable
        max-width="600px"
        data-cy="reportselector"
        @keydown.esc="cancel"
      >
        <v-card elevation="24">
          <v-card-title class="text-h5 lighten-2" primary-title>
            <span> {{ $sock.t("Report") }} </span>
          </v-card-title>
          <v-card-text style="height: 500px;">
            <v-list>
              <v-list-item
                v-for="item in reportList"
                :key="item.id"
                class="my-n3"
                @click="renderReport(item.id, item.name)"
              >
                <v-list-item-title>{{ item.name }}</v-list-item-title>
                <v-list-item-action class="d-none d-sm-flex">
                  <v-btn x-small icon @click.stop="editReport(item.id)">
                    <v-icon color="primary">$sockiEdit</v-icon>
                  </v-btn>
                </v-list-item-action>
              </v-list-item>
            </v-list>
          </v-card-text>
          <v-divider></v-divider>
          <v-card-actions>
            <v-btn
              v-if="rights.change"
              color="primary"
              text
              data-cy="reportselector:ok"
              class="d-none d-sm-flex"
              @click.native="newReport"
              >{{ $sock.t("New") }}</v-btn
            >
            <v-spacer v-if="!$vuetify.breakpoint.xs"></v-spacer>
            <v-btn
              color="primary"
              text
              data-cy="reportselector:cancel"
              @click.native="cancel"
              >{{ $sock.t("Cancel") }}</v-btn
            >
          </v-card-actions>
        </v-card>
      </v-dialog>
    </v-row>
    <!-- ################################################################################-->
    <!-- ##########################  JOB FORM  ####################################-->
    <!-- ################################################################################-->
    <template>
      <v-row dense justify="center">
        <v-dialog v-model="jobActive" persistent max-width="360px">
          <v-card>
            <v-card-title>{{ $sock.t("RenderingReport") }}</v-card-title>
            <v-card-text>
              <div class="text-center">
                <v-progress-circular
                  indeterminate
                  color="primary"
                  width="10"
                  size="50"
                ></v-progress-circular>
              </div>
            </v-card-text>
            <v-card-actions>
              <v-btn text color="primary" @click="cancelJob">{{
                $sock.t("Cancel")
              }}</v-btn>
            </v-card-actions>
          </v-card>
        </v-dialog>
      </v-row>
    </template>
  </div>
</template>
<script>
export default {
  data: () => ({
    rights: window.$gz.role.getRights(window.$gz.type.Report),
    reportDataOptions: {},
    isVisible: false,
    resolve: null,
    reject: null,
    options: {
      width: 290,
      zIndex: 200
    },
    reportList: [],
    selectedReport: null,
    jobActive: false,
    preSelectReportId: null,
    jobId: null
  }),
  methods: {
    editReport(reportid) {
      this.isVisible = false;
      this.resolve(null);
      this.$router.push({
        name: "sock-report-edit",
        params: {
          recordid: reportid,
          reportDataOptions: this.reportDataOptions
        }
      });
    },
    async cancelJob() {
      if (this.jobId && this.jobId != -1) {
        await window.$gz.api.post(`report/request-cancel/${this.jobId}`);
      }
      this.jobActive = false;
      this.resolve(null);
    },
    async renderReport(reportId, reportName) {
      if (this.$route.params.recordid == 0) {
        return;
      }

      const reportDataOptions = this.reportDataOptions;
      if (!reportDataOptions) {
        this.reject("Missing report data unable to render report");
      }
      reportDataOptions.ReportId = reportId;
      //Meta data from client for use by report script
      reportDataOptions.ClientMeta = window.$gz.api.reportClientMetaData();
      this.jobActive = true;

      try {
        let jobId = await window.$gz.api.upsert(
          "report/render-job",
          reportDataOptions
        );
        if (jobId.error) {
          throw new Error(window.$gz.errorHandler.errorToString(jobId, this));
        }
        jobId = jobId.jobId;
        this.jobActive = true;
        this.jobId = jobId;

        let jobStatus = 1;
        while (this.jobActive == true) {
          await window.$gz.util.sleepAsync(1000);
          jobStatus = await window.$gz.api.get(
            `job-operations/status/${jobId}`
          );
          if (jobStatus.error) {
            throw new Error(
              window.$gz.errorHandler.errorToString(jobStatus, this)
            );
          }
          jobStatus = jobStatus.data;

          /*
 Absent = 0,
        Sleeping = 1,
        Running = 2,
        Completed = 3,
        Failed = 4
*/
          //check for any terminal status
          if (jobStatus != 1 && jobStatus != 2) {
            this.jobActive = false;
            const jobLogRes = await window.$gz.api.get(
              `job-operations/logs/${jobId}`
            );

            //get final entry is error or success
            var finalJobLogMessage = jobLogRes.data[jobLogRes.data.length - 1];
            const finalJobLogObject = JSON.parse(finalJobLogMessage.statusText);

            if (jobStatus == 4 || jobStatus == 0) {
              var e = null;
              //any error should be in a rendererror keyed object
              if (!finalJobLogObject.rendererror) {
                //unusual unknown error, shouldn't happen but just in case
                e = this.$sock.t("JobFailed");
              } else {
                //failure of some kind, either timeout, exception or exception plus pagelog

                if (finalJobLogObject.rendererror.timeout) {
                  //timeout
                  await window.$gz.dialog.displayNoTranslationModalNotificationMessage(
                    window.$gz.translation
                      .get("ReportRenderTimeOut")
                      .replace(
                        "{0}",
                        finalJobLogObject.rendererror.timeoutsetting
                      ),
                    null,
                    "error",
                    `${window.$gz.api.helpUrl()}/sock-report-timeout`
                  );
                  //we're done here
                  return this.reject(this.$sock.t("JobFailed"));
                } else {
                  //exception
                  e = `${this.$sock.t("JobFailed")}: ${
                    finalJobLogObject.rendererror.exception
                  }`;
                  if (finalJobLogObject.rendererror.pagelog) {
                    e +=
                      "\n---------\n" + finalJobLogObject.rendererror.pagelog;
                  }
                }
              }

              throw new Error(e);
            }
            if (jobStatus == 3) {
              //success or cancelled

              //todo handle cancelled type of completed
              //var json = Newtonsoft.Json.JsonConvert.SerializeObject(new { rendererror = new { cancelled = true} }, Newtonsoft.Json.Formatting.None);
              if (!finalJobLogObject.reportfilename) {
                throw new Error(
                  `${this.$sock.t(
                    "JobCompleted"
                  )}: But no file name was returned, cannot open report URL`
                );
              }
              var reportUrl = window.$gz.api.reportDownloadUrl(
                finalJobLogObject.reportfilename
              );
              if (window.open(reportUrl, "Report") == null) {
                this.reject(
                  "Problem displaying report in new window.  Browser must allow pop-ups to view reports; check your browser setting"
                );
              }

              this.isVisible = false;
              if (reportName != null) {
                this.resolve({ name: reportName, id: reportId });
              } else {
                this.resolve(null);
              }
            }
          }
        }
      } catch (error) {
        this.jobActive = false;
        this.reject(error);
      }
    },
    async open(reportDataOptions, preSelectReportId) {
      const vm = this;
      if (reportDataOptions == null) {
        throw new Error("report-selector:Open missing reportDataOptions");
      }
      this.reportDataOptions = reportDataOptions;
      this.preSelectReportId = preSelectReportId;
      if (!preSelectReportId) {
        if (reportDataOptions.SockType == null) {
          throw new Error(
            "report-selector:Open - SockType is missing or empty"
          );
        }
        //get report list from server
        const res = await window.$gz.api.get(
          `report/list/${reportDataOptions.SockType}`
        );
        if (res.error) {
          throw new Error(window.$gz.errorHandler.errorToString(res, vm));
        } else {
          this.reportList = res.data;
        }
        this.isVisible = true;
      } else {
        this.renderReport(this.preSelectReportId);
      }
      return new Promise((resolve, reject) => {
        this.resolve = resolve;
        this.reject = reject;
      });
    },
    cancel() {
      this.isVisible = false;
      this.resolve(null);
    },
    newReport() {
      this.isVisible = false;
      this.resolve(null);
      this.$router.push({
        name: "sock-report-edit",
        params: {
          recordid: 0,
          reportDataOptions: this.reportDataOptions
        }
      });
    }
  }
};
</script>
