<template>
  <div ref="focusElement">
    <FormWrapper
      class="card-select select-component"
      :class="props.states"
      :label="props.label"
      :error="props.error"
      :active="active"
    >
      <div
        class="card-container"
        @click="open"
        tabindex="0"
        @keydown.enter="open"
        @keydown.esc="close"
      >
        <div v-if="state.selectedCard" class="selected-item h600">
          <div class="card-image">
            <img :src="cardImage(state.selectedCard)" />
          </div>
          <p class="card-title ellipsis">
            {{
              state.selectedCard.title
                ? state.selectedCard.title
                : $t("common.tbcBank")
            }}
          </p>
          <p class="card-mask">{{ state.selectedCard.mask }}</p>
        </div>
        <div v-else class="placeholder">
          <div class="icon">
            <SpIcon name="card" />
          </div>
          <p class="h600">{{ $t("card.chooseCard") }}</p>
        </div>

        <div class="icon dropdown-arrow">
          <SpIcon name="dropdown" />
        </div>
      </div>

      <AccordionSheet :active="active" @close="active = false">
        <ul v-if="active" class="main h700">
          <li
            class="no-cards"
            v-if="props.list.length == 0 && props.showNoCards"
          >
            <div>
              <SpIcon name="warning" />

              <p>{{ props.noCardsText }}</p>
            </div>
          </li>
          <li
            v-for="(card, index) in props.list"
            :key="index"
            @click="selectCard(index)"
            :class="{
              disabled: card.isBlocked || isOutdated(card),
              selected: isSelected(card),
            }"
          >
            <div class="item card">
              <div class="card-icon">
                <div class="icon" v-if="isOutdated(card)">
                  <SpIcon name="time" />
                </div>
                <div class="icon" v-else-if="card.isBlocked">
                  <SpIcon name="locked" />
                </div>
                <RadioIcon v-else :active="isSelected(card)" />
              </div>
              <div class="card-image mr-4">
                <img :src="cardImage(card)" alt="Card Image" />
              </div>
              <div class="card-info">
                <p class="card-title ellipsis">
                  {{
                    isAccount(card) ? $t("common.currentAccount") : card.title
                  }}
                </p>
                <div
                  v-if="props.ShowAmount"
                  :class="{
                    'card-balance': true,
                    ellipsis: true,
                    h800: true,
                    positive: card.balance.amount >= 0,
                    negative: card.balance.amount < 0,
                  }"
                >
                  <div class="icon" v-if="isOutdated(card)">
                    <SpIcon name="time" />
                  </div>
                  <div class="icon" v-else-if="card.isBlocked">
                    <SpIcon name="locked" />
                  </div>
                  <span class="balance"
                    >{{ format(card.balance.amount) }}
                    {{ card.balance.currencyCode }}</span
                  >
                </div>
              </div>
              <p v-if="card.mask" class="card-mask ml-4">
                {{ card.mask }}
              </p>
            </div>
          </li>
          <li class="add" @click="addCard">
            <div class="item">
              <div class="icon-frame">
                <div class="icon-container">
                  <div class="icon stroke-blue">
                    <SpIcon name="plus" />
                  </div>
                </div>
              </div>
              <p class="h700">{{ $t("card.addCard") }}</p>
            </div>
          </li>
        </ul>
      </AccordionSheet>
    </FormWrapper>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, PropType, reactive, watch } from "vue";
import { numberFormat } from "@/utils";
import { Card } from "@/models";
import { CardStatus } from "@/enums";
import FormMixin from "@/mixins/FormMixin";
import { useFocusOut } from "@/hooks";

export default defineComponent({
  mixins: [FormMixin],
  props: {
    list: {
      type: Array as PropType<Card[]>,
      default: [],
      required: true,
    },
    ShowAmount: {
      type: Boolean,
      default: true,
    },
    showNoCards: {
      type: Boolean,
      default: false,
    },
    noCardsText: {
      type: String,
      default: "",
    },
  },
  setup(props: any, { emit }) {
    const state = reactive<{
      selectedCard: Card | null;
    }>({
      selectedCard: null,
    });

    const { focusOutElement, active, focusElement } = useFocusOut();
    focusOutElement.value = ".input-container";

    const selectedCardId = computed((): string => {
      if (state.selectedCard) {
        return state.selectedCard.cardId;
      } else {
        return null;
      }
    });

    const isAccount = (card: Card): boolean => {
      return card.status === CardStatus.Unordered;
    };

    const isSelected = (card: Card): boolean => {
      return state.selectedCard && state.selectedCard.cardId === card.cardId;
    };

    const cardImage = (card: Card): string => {
      if (isAccount(card)) {
        return `/img/icons/cards/account.png`;
      } else {
        return `/img/icons/cards/${card.type}.svg`;
      }
    };

    const selectCard = (index: number) => {
      if (props.list[index].isBlocked) {
        emit("blocked");
        return;
      } else if (isOutdated(props.list[index])) {
        emit("outdated");
        return;
      }

      state.selectedCard = props.list[index];
      emit("update:modelValue", state.selectedCard);
      close();
    };

    const isOutdated = (card: Card): boolean => {
      return card.status === CardStatus.Obsolete;
    };

    const format = (amount: number): any => {
      return numberFormat(amount / 100);
    };

    const addCard = (): void => {
      emit("addCard");
      close();
    };

    const selectItem = (index: number): void => {
      state.selectedCard = props.list[index];
      emit("update:modelValue", state.selectedCard);
    };

    const open = (): void => {
      active.value = true;
    };

    const close = (): void => {
      active.value = false;
    };

    watch(
      (): any => props.modelValue,
      (newVal: Card, oldVal: Card): void => {
        if (newVal?.cardId !== oldVal?.cardId) {
          state.selectedCard = newVal;
        }
      }
    );

    return {
      focusElement,
      active,
      selectedCardId,
      isAccount,
      isSelected,
      selectCard,
      isOutdated,
      format,
      addCard,
      selectItem,
      open,
      close,
      cardImage,
      props,
      state,
    };
  },
});
</script>

<style lang="scss">
.card-select {
  .card-container {
    height: var(--form-item-height);
    border-radius: var(--form-border-radius);
    border: 1px solid var(--form-border-color);
    padding: 0 var(--form-side-padding);
    position: relative;
    cursor: pointer;
    outline: none;
    transition: border 0.3s ease;

    &:focus {
      border-color: var(--blue);
    }

    .placeholder {
      height: 100%;
      display: flex;
      align-items: center;
      color: var(--form-placeholder-color);
      pointer-events: none;
      user-select: none;

      .icon {
        margin-right: 8px;
      }
    }

    .dropdown-arrow {
      position: absolute;
      top: 50%;
      right: var(--form-side-padding);
      transform: translateY(-50%);
    }
  }

  ul {
    li {
      cursor: pointer;

      //&.disabled {
      //  .card-info,
      //  .card-mask,
      //  .card-image {
      //    opacity: 0.5;
      //  }
      //}
      &.selected {
        .card-title {
          color: var(--blue);
        }
      }

      &.add {
        padding-left: 32px;

        p {
          transition: color 0.3s ease;
          color: var(--blue);
        }

        .icon-frame {
          width: 62px;
          height: 40px;
          border: 1px solid var(--grey-5);
          border-radius: 4px;
          display: flex;
          align-items: center;
          justify-content: center;
          margin-right: 8px;
        }

        .icon-container {
          width: 28px;
          height: 28px;
          border-radius: 50%;
          background-color: var(--blue-20);

          .icon {
            width: 16px !important;
            height: 16px !important;
            position: relative;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
          }
        }

        &:hover {
          color: var(--blue);
        }
      }

      .item {
        display: flex;
        padding: 8px 16px 8px 0;
        align-items: center;

        .card-icon {
          flex-shrink: 0;
          margin-right: 8px;
        }

        .card-image {
          width: 60px;
          height: 40px;
          flex-shrink: 0;

          img {
            width: 100%;
            height: 100%;
            object-fit: cover;
          }
        }

        .card-info {
          flex-grow: 1;
          overflow: hidden;

          .card-balance {
            color: var(--text-color-secondary);
            display: flex;
            align-items: center;

            .icon {
              display: none;
              width: 16px;
              height: 16px;
              margin-right: 4px;
              margin-bottom: 2px;
            }

            &.positive {
              color: var(--green);
            }

            &.negative {
              color: var(--red);
            }
          }
        }

        .card-mask {
          flex-shrink: 0;
          color: var(--text-color-secondary);
        }
      }

      &:first-child {
        .item {
          padding-top: 12px;
        }
      }

      @include screen-sm() {
        .item {
          min-height: 54px;
        }

        &:hover {
          background-color: var(--fill-quaternary);
        }

        .item {
          padding: 8px 16px;

          .card-icon {
            display: none !important;
          }

          .card-image {
            width: 32px;
            height: 21px;
          }

          .card-info {
            .card-balance {
              .icon {
                display: block;
              }
            }
          }
        }

        &.add {
          padding-left: 0;
          padding-bottom: 4px;

          .icon-frame {
            width: auto;
            height: auto;
            border: none;

            .icon-container {
              width: 32px;
              height: 32px;
            }
          }
        }
      }

      @include screen-lg() {
        .item {
          min-height: 60px;
        }

        &.add {
          .icon-frame {
            margin-right: 16px;
          }
        }
      }
      &.no-cards {
        cursor: default;
        display: none;
        &:hover {
          background: transparent;
        }
        div {
          border-bottom: 1px solid var(--grey-5);
          width: calc(100% - 64px);
          margin: 0 auto 24px auto;
          padding: 61px 0;
          display: flex;
          flex-flow: row wrap;
          justify-content: center;
          justify-items: center;
          p {
            color: var(--grey-1);
            width: 100%;
            text-align: center;
            margin-top: 24px;
            font-size: 16px;
          }
        }

        @include screen-sm-below() {
          display: block;
        }
      }
    }
  }

  .accordion-sheet {
    --scroll-max-height: 270px;
    --scroll-min-height: 72px;
  }

  .selected-item {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    padding-right: 32px;

    .card-image {
      width: 24px;
      height: 16px;
      margin-right: 8px;
      flex-shrink: 0;

      img {
        width: 100%;
        height: 100%;
        object-fit: cover;
      }
    }

    .card-title {
      flex-grow: 1;
    }

    .card-mask {
      flex-shrink: 0;
      color: var(--text-color-secondary);
    }
  }

  @include screen-sm() {
    --list-item-margin: 0px;
    --list-item-padding: 12px 16px;
    --list-item-extra-padding: 16px;
  }

  @include screen-lg() {
    --list-item-padding: 16px 24px;
    --list-item-extra-padding: 23px;

    .accordion-sheet {
      --scroll-max-height: 320px;
    }
  }
}
</style>
