<script setup lang="ts">
import { computed, h, ref } from 'vue'
import BigNumber from "bignumber.js";

const unitToByte: { [name: string]: number } = {
  "unit-k-byte": 1000,
  "unit-m-byte": 1000 * 1000,
  "unit-g-byte": 1000 * 1000 * 1000,
  "unit-t-byte": 1000 * 1000 * 1000 * 1000,
  "unit-ki-byte": 1024,
  "unit-mi-byte": 1024 * 1024,
  "unit-gi-byte": 1024 * 1024 * 1024,
  "unit-ti-byte": 1024 * 1024 * 1024 * 1024,
  "unit-byte": 1,
  "unit-bit": 1 / 8,
  "unit-k-bit": 1000 / 8,
  "unit-m-bit": 1000000 / 8,
  "unit-g-bit": 1000000000 / 8,
  "unit-t-bit": 1000000000000 / 8,
}

let variable: { [name: keyof typeof unitToByte]: string } = {
  "unit-k-byte": '',
  "unit-m-byte": '',
  "unit-g-byte": '',
  "unit-t-byte": '',
  "unit-ki-byte": '',
  "unit-mi-byte": '',
  "unit-gi-byte": '',
  "unit-ti-byte": '',
  "unit-byte": '',
  "unit-bit": '',
  "unit-k-bit": '',
  "unit-m-bit": '',
  "unit-g-bit": '',
  "unit-t-bit": '',
}

const size = ref(variable);

function sizeChanged(event: any, unitName: keyof typeof unitToByte) {
  let result: { [name in keyof typeof unitToByte]: string } = Object();
  // assign 0 to current input if nothing is passed
  if (size.value[unitName].length === 0) result[unitName] = '0';
  let inputedBytes = new BigNumber(unitToByte[unitName]).multipliedBy(size.value[unitName]);
  for (const key in unitToByte) {
    result[key] = inputedBytes.div(unitToByte[key]).toString();
  }
  result[unitName] = size.value[unitName];
  for (const key in unitToByte) {
    if (result[key] !== 'NaN') {
      size.value[key] = result[key];
    } else if (result[key] === 'NaN') {
      size.value[key] = '';
    }
  }
}

const isMultipleOf4KiB = computed(() => {
  let userInput = new BigNumber(size.value["unit-ki-byte"])
  if (userInput.toNumber() === 0) return false;
  return userInput.mod(4).toNumber() === 0 ? true : false;
})
</script>

<template>
  <h1>数据单位换算</h1>
  <div class="unit-conversion-computation-area 1000-in-byte">
    <p>1000 进制并以 Byte 计: </p>
    <div class="unit-conversion-computation-node">
      <input class="size-text" id="unit-k-byte" type="text" v-model="size['unit-k-byte']"
        @input="sizeChanged($event, 'unit-k-byte')">
      <span class="unit-name">KB</span>
    </div>
    <div class="unit-conversion-computation-node">
      <input class="size-text" id="unit-m-byte" type="text" v-model="size['unit-m-byte']"
        @input="sizeChanged($event, 'unit-m-byte')">
      <span class="unit-name">MB</span>
    </div>
    <div class="unit-conversion-computation-node">
      <input class="size-text" id="unit-g-byte" type="text" v-model="size['unit-g-byte']"
        @input="sizeChanged($event, 'unit-g-byte')">
      <span class="unit-name">GB</span>
    </div>
    <div class="unit-conversion-computation-node">
      <input class="size-text" id="unit-t-byte" type="text" v-model="size['unit-t-byte']"
        @input="sizeChanged($event, 'unit-t-byte')">
      <span class="unit-name">TB</span>
    </div>
  </div>
  <div class="unit-conversion-computation-area 1024-in-byte">
    <p>1024 进制并以 Byte 计</p>
    <div class="unit-conversion-computation-node">
      <input class="size-text" id="unit-ki-byte" type="text" v-model="size['unit-ki-byte']"
        @input="sizeChanged($event, 'unit-ki-byte')">
      <span class="unit-name">KiB</span>
    </div>
    <div class="unit-conversion-computation-node">
      <input class="size-text" id="unit-mi-byte" type="text" v-model="size['unit-mi-byte']"
        @input="sizeChanged($event, 'unit-mi-byte')">
      <span class="unit-name">MiB</span>
    </div>
    <div class="unit-conversion-computation-node">
      <input class="size-text" id="unit-gi-byte" type="text" v-model="size['unit-gi-byte']"
        @input="sizeChanged($event, 'unit-gi-byte')">
      <span class="unit-name">GiB</span>
    </div>
    <div class="unit-conversion-computation-node">
      <input class="size-text" id="unit-ti-byte" type="text" v-model="size['unit-ti-byte']"
        @input="sizeChanged($event, 'unit-ti-byte')">
      <span class="unit-name">TiB</span>
    </div>
  </div>
  <div class="unit-conversion-computation-area byte-bit">
    <p>以 Byte (B) / bit (b) 计:</p>
    <div class="unit-conversion-computation-node">
      <input class="size-text" id="unit-byte" type="text" v-model="size['unit-byte']"
        @input="sizeChanged($event, 'unit-byte')">
      <span class="unit-name">B</span>
    </div>
    <div class="unit-conversion-computation-node">
      <input class="size-text" id="unit-bit" type="text" v-model="size['unit-bit']"
        @input="sizeChanged($event, 'unit-bit')">
      <span class="unit-name">b</span>
    </div>
  </div>
  <div class="unit-conversion-computation-area 1000-in-bit">
    <p>1000 进制并以 bit 计:</p>
    <div class="unit-conversion-computation-node">
      <input class="size-text" id="unit-k-bit" type="text" v-model="size['unit-k-bit']"
        @input="sizeChanged($event, 'unit-k-bit')">
      <span class="unit-name">Kb</span>
    </div>
    <div class="unit-conversion-computation-node">
      <input class="size-text" id="unit-m-bit" type="text" v-model="size['unit-m-bit']"
        @input="sizeChanged($event, 'unit-m-bit')">
      <span class="unit-name">Mb</span>
    </div>
    <div class="unit-conversion-computation-node">
      <input class="size-text" id="unit-g-bit" type="text" v-model="size['unit-g-bit']"
        @input="sizeChanged($event, 'unit-g-bit')">
      <span class="unit-name">Gb</span>
    </div>
    <div class="unit-conversion-computation-node">
      <input class="size-text" id="unit-t-bit" type="text" v-model="size['unit-t-bit']"
        @input="sizeChanged($event, 'unit-t-bit')">
      <span class="unit-name">Tb</span>
    </div>
  </div>
  <div class="unit-conversion-computation-result">
    <p v-show="isMultipleOf4KiB">该结果值是 4 KiB 的倍数</p>
  </div>
</template>

<style>
h1,
p,
.unit-conversion-computation-node {
  margin: 0.5em 0;
}

.unit-conversion-computation-node {
  float: left;
  width: 170px;
  margin: 0 8px 0 0;
}

.size-text {
  margin: 0 6px 0 0;
  width: 130px
}

@media screen and (max-width: 395px) {
  .unit-conversion-computation-node {
    width: 130px;
  }

  .size-text {
    width: 90px;
  }
}

.unit-conversion-computation-area::after {
  content: '';
  display: block;
  clear: both;
}

.unit-conversion-computation-result {
  margin: 0.5em 0 0.5em 0;
  height: 1em;
}
</style>
