<template>
  <div class="card">
    <header class="card-header is-unselectable">
      <p class="card-header-title" @click="toggle">{{ header }}</p>

      <p v-if="refreshable" class="card-header-icon px-0">
        <button class="tag button icon is-info" @click="refresh">
          <font-awesome-icon
            icon="fa-solid fa-arrows-rotate"
            :spin="is_open && loading"
          />
        </button>
      </p>

      <button class="card-header-icon" @click="toggle">
        <span class="icon">
          <font-awesome-icon
            :icon="'fa-solid fa-angle-' + (is_open ? 'down' : 'right')"
          />
        </span>
      </button>
    </header>

    <template v-if="is_open">
      <div v-if="loading" class="card-content">
        <progress class="progress is-info" max="100" />
      </div>
      <div
        v-else-if="failed"
        class="card-content has-text-danger has-text-centered"
      >
        <span class="icon is-large">
          <font-awesome-icon icon="fa-solid fa-ban" size="3x" />
        </span>
      </div>
      <slot v-else name="default" />
    </template>
  </div>
</template>

<script lang="ts">
import { Options, Vue } from "vue-class-component";

export enum DrawerState {
  Loading,
  Ready,
  Failed,
}

@Options({
  props: {
    header: {
      type: String,
      default: "",
    },
    state: DrawerState,
    refreshable: {
      type: Boolean,
      default: false,
    },
  },
  emits: ["open"],
})
export default class extends Vue {
  public header!: string;
  public state!: DrawerState;
  public refreshable!: boolean;

  public is_open = false;

  public toggle() {
    this.is_open = !this.is_open;
    if (this.is_open) this.$emit("open");
  }

  public refresh() {
    this.is_open = false;
    this.toggle();
  }

  public get loading(): boolean {
    return this.state === DrawerState.Loading;
  }

  public get failed(): boolean {
    return this.state === DrawerState.Failed;
  }
}
</script>

<style lang="scss" scoped>
div.card {
  &:not(:last-child) {
    margin-bottom: 1.5rem;
  }
  > .card-header {
    cursor: pointer;
  }
}
</style>
