<script setup lang="ts">
import type { BucketIn } from "@/client/s3proxy";
import { reactive, onMounted, ref } from "vue";
import BootstrapModal from "@/components/modals/BootstrapModal.vue";
import { useRouter } from "vue-router";
import { Modal } from "bootstrap";
import { useBucketStore } from "@/stores/buckets";

const router = useRouter();
const bucketRepository = useBucketStore();

const bucketCreateForm = ref<HTMLFormElement | undefined>(undefined);
const bucketNameElement = ref<HTMLInputElement | undefined>(undefined);

const bucket = reactive<BucketIn>({ name: "", description: "" });

const formState = reactive<{
  validated: boolean;
  bucketNameTaken: boolean;
  loading: boolean;
}>({
  validated: false,
  bucketNameTaken: false,
  loading: false,
});

const props = defineProps<{
  modalID: string;
}>();

let createBucketModal: Modal | null = null;

onMounted(() => {
  createBucketModal = new Modal("#" + props.modalID);
});

function createBucket() {
  formState.validated = true;
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
  formState.bucketNameTaken = false;
  bucket.description = bucket.description.trim();
  bucket.name = bucket.name.trim();
  bucketNameElement.value?.setCustomValidity("");
  if (bucketCreateForm.value?.checkValidity()) {
    formState.loading = true;
    bucketRepository
      .createBucket(bucket)
      .then((createdBucket) => {
        createBucketModal?.hide();
        bucket.name = "";
        bucket.description = "";
        formState.bucketNameTaken = false;
        formState.validated = false;
        router.push({
          name: "bucket",
          params: { bucketName: createdBucket.name, subFolders: [] },
        });
      })
      .catch((error) => {
        if (
          error.status === 400 &&
          error.body["detail"] === "Bucket name is already taken"
        ) {
          formState.bucketNameTaken = true;
          bucketNameElement.value?.setCustomValidity(
            "Bucket name is already taken",
          );
        }
      })
      .finally(() => {
        formState.loading = false;
      });
  }
}

function modalClosed() {
  formState.validated = false;
  formState.bucketNameTaken = false;
  bucketNameElement.value?.setCustomValidity("");
}
</script>

<template>
  <bootstrap-modal
    :modalId="modalID"
    :static-backdrop="true"
    modal-label="Create Bucket Modal"
    v-on="{ 'hidden.bs.modal': modalClosed }"
  >
    <template v-slot:header> Create new S3 Bucket</template>
    <template v-slot:body>
      <form
        id="bucketCreateForm"
        :class="{ 'was-validated': formState.validated }"
        ref="bucketCreateForm"
      >
        <div class="mb-3">
          <label for="bucketNameInput" class="form-label">Bucket Name</label>
          <div class="input-group">
            <input
              type="text"
              class="form-control"
              id="bucketNameInput"
              required
              minlength="3"
              maxlength="63"
              pattern="(?!(^(\d+\.){3}\d+$))^([a-z0-9](?:[a-z0-9\-]*[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9\-]*[a-z0-9])?$"
              v-model="bucket.name"
              ref="bucketNameElement"
            />
            <div class="invalid-feedback">
              <div v-if="formState.bucketNameTaken">
                Bucket name already taken.
              </div>
              <div>
                Requirements
                <ul>
                  <li>At least 3 Characters long</li>
                  <li>Unique in CloWM</li>
                  <li>
                    Only lowercase letters, numbers, single periods (.) and
                    hyphen (-)
                  </li>
                  <li>Start and end with letter or number</li>
                  <li>
                    A letter or number must be before and after a period (.)
                  </li>
                </ul>
              </div>
            </div>
          </div>
        </div>
        <div class="mb-3">
          <label for="bucketDescriptionInput" class="form-label">
            Description
          </label>
          <div class="input-group">
            <textarea
              class="form-control"
              id="bucketDescriptionInput"
              required
              rows="3"
              minlength="32"
              maxlength="65536"
              v-model="bucket.description"
              placeholder="Describe the purpose of the bucket"
            ></textarea>
            <div class="invalid-feedback">
              Requirements
              <ul>
                <li>At least 32 Characters long</li>
              </ul>
            </div>
          </div>
        </div>
      </form>
    </template>
    <template v-slot:footer>
      <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
        Close
      </button>
      <button
        type="submit"
        form="bucketCreateForm"
        class="btn btn-primary"
        :disabled="formState.loading"
        @click.prevent="createBucket"
      >
        <span
          v-if="formState.loading"
          class="spinner-border spinner-border-sm"
          role="status"
          aria-hidden="true"
        ></span>
        Save
      </button>
    </template>
  </bootstrap-modal>
</template>

<style scoped></style>