<script setup lang="ts">
import {
  trans,
  EXPORT_GENERATION_EXPORT_GENERATION_IS_PENDING,
  EXPORT_GENERATION_TOO_MANY_RETRIES,
  EXPORT_GENERATION_ERROR_WHILE_GENERATING_EXPORT,
  EXPORT_GENERATION_EXPORT_READY,
} from "translator";
import { computed, onMounted, ref } from "vue";
import { StoredObject, StoredObjectStatus } from "ChillDocStoreAssets/types";
import { fetchExportGenerationStatus } from "ChillMainAssets/lib/api/export";
import DocumentActionButtonsGroup from "ChillDocStoreAssets/vuejs/DocumentActionButtonsGroup.vue";
import { ExportGeneration } from "ChillMainAssets/types";

interface AppProps {
  exportGenerationId: string;
  title: string;
  createdDate: string;
}

const props = defineProps<AppProps>();

const exportGeneration = ref<ExportGeneration | null>(null);

const status = computed<StoredObjectStatus>(
  () => exportGeneration.value?.status ?? "pending",
);
const storedObject = computed<null | StoredObject>(() => {
  if (exportGeneration.value === null) {
    return null;
  }

  return exportGeneration.value?.storedObject;
});

const isPending = computed<boolean>(() => status.value === "pending");
const isFetching = computed<boolean>(
  () => tryiesForReady.value < maxTryiesForReady,
);
const isReady = computed<boolean>(() => status.value === "ready");
const isFailure = computed<boolean>(() => status.value === "failure");
const filename = computed<string>(() => `${props.title}-${props.createdDate}`);

/**
 * counter for the number of times that we check for a new status
 */
let tryiesForReady = ref<number>(0);

/**
 * how many times we may check for a new status, once loaded
 */
const maxTryiesForReady = 120;

const checkForReady = function (): void {
  if (
    "ready" === status.value ||
    "empty" === status.value ||
    "failure" === status.value ||
    // stop reloading if the page stays opened for a long time
    tryiesForReady.value > maxTryiesForReady
  ) {
    return;
  }

  tryiesForReady.value = tryiesForReady.value + 1;
  setTimeout(onObjectNewStatusCallback, 5000);
};

const onObjectNewStatusCallback = async function (): Promise<void> {
  exportGeneration.value = await fetchExportGenerationStatus(
    props.exportGenerationId,
  );

  if (isPending.value) {
    checkForReady();
    return Promise.resolve();
  }

  return Promise.resolve();
};

onMounted(() => {
  onObjectNewStatusCallback();
});
</script>

<template>
  <div id="waiting-screen">
    <div v-if="isPending && isFetching" class="alert alert-danger text-center">
      <div>
        <p>
          {{ trans(EXPORT_GENERATION_EXPORT_GENERATION_IS_PENDING) }}
        </p>
      </div>

      <div>
        <i class="fa fa-cog fa-spin fa-3x fa-fw"></i>
        <span class="sr-only">Loading...</span>
      </div>
    </div>
    <div v-if="isPending && !isFetching" class="alert alert-info">
      <div>
        <p>
          {{ trans(EXPORT_GENERATION_TOO_MANY_RETRIES) }}
        </p>
      </div>
    </div>
    <div v-if="isFailure" class="alert alert-danger text-center">
      <div>
        <p>
          {{ trans(EXPORT_GENERATION_ERROR_WHILE_GENERATING_EXPORT) }}
        </p>
      </div>
    </div>
    <div v-if="isReady" class="alert alert-success text-center">
      <div>
        <p>
          {{ trans(EXPORT_GENERATION_EXPORT_READY) }}
        </p>

        <p v-if="storedObject !== null">
          <document-action-buttons-group
            :stored-object="storedObject"
            :filename="filename"
          ></document-action-buttons-group>
        </p>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
#waiting-screen {
  > .alert {
    min-height: 350px;
  }
}
</style>
