<template>
  <div class="hold-inner">
    <div class="stake-inner">
      <template v-if="!statCollection.initialized">
        <div>
          <FLoader></FLoader>
        </div>
      </template>

      <template v-else>
        <div class="subheader2">Token Amount</div>
        <FSlider :min="minStakeAmount" :max="maxStakeAmount" v-model="stake.stakingAmountNumber"></FSlider>
        <div class="formular">
          <div class="row row-1">
            <FInput label="Staking Amount" class="staking-amount" v-model="stake.stakingAmountNumber">
              <template v-slot:details>
                <div class="balance">Balance: {{ maxStakeAmount.toFixed(2) }} $KRK</div>
                <div @click="setMaxAmount" class="staking-amount-max">
                  <b>Max</b>
                </div>
              </template>
            </FInput>
            <Icon class="stake-arrow" icon="mdi:chevron-triple-right"></Icon>
            <FInput label="Owner Slots" class="staking-amount" disabled :modelValue="`${stakeSlots}(${supplyFreeze?.toFixed(4)})`">
              <template #info>
                Slots correspond to a percentage of ownership in the protocol.<br /><br />1,000 Slots = 1% Ownership<br /><br />When you
                unstake you get the exact percentage of the current $KRK total supply. When the total supply increased since you staked you
                get more tokens back than before.
              </template>
            </FInput>
          </div>
          <div class="row row-2">
            <FSelect :items="adjustTaxRate.taxRates" label="Tax" v-model="taxRate">
              <template v-slot:info>
                The yearly tax you have to pay to keep your slots open. The tax is paid when unstaking or manually in the dashboard. If
                someone pays a higher tax they can buy you out.
              </template>
            </FSelect>
            <FInput label="Floor Tax" disabled :modelValue="String(snatchSelection.floorTax)">
              <template v-slot:info> This is the current minimum tax you have to pay to claim owner slots from other owners. </template>
            </FInput>
            <FInput label="Positions Buyout" disabled :modelValue="String(snatchSelection.snatchablePositions.value.length)">
              <template v-slot:info>
                This shows you the numbers of staking positions you buy out from current owners by paying a higher tax. If you get bought
                out yourself by new owners you get paid out the current market value of your position incl. your profits.
              </template>
            </FInput>
          </div>
        </div>
        <FButton size="large" disabled block v-if="stake.state === 'NoBalance'">Insufficient Balance</FButton>
        <FButton size="large" disabled block v-else-if="stake.stakingAmountNumber < minStakeAmount">Stake amount too low</FButton>
        <FButton
          size="large"
          disabled
          block
          v-else-if="
            !snatchSelection.openPositionsAvailable && stake.state === 'StakeAble' && snatchSelection.snatchablePositions.value.length === 0
          "
          >taxRate too low to snatch</FButton
        >
        <FButton
          size="large"
          block
          v-else-if="stake.state === 'StakeAble' && snatchSelection.snatchablePositions.value.length === 0"
          @click="stakeSnatch"
          >Stake</FButton
        >
        <FButton
          size="large"
          block
          v-else-if="stake.state === 'StakeAble' && snatchSelection.snatchablePositions.value.length > 0"
          @click="stakeSnatch"
          >Snatch and Stake</FButton
        >
        <FButton size="large" outlined block v-else-if="stake.state === 'SignTransaction'">Sign Transaction ...</FButton>
        <FButton size="large" outlined block v-else-if="stake.state === 'Waiting'">Waiting ...</FButton>
      </template>
    </div>
  </div>
</template>

<script setup lang="ts">
import FButton from '@/components/fcomponents/FButton.vue';
import FInput from '@/components/fcomponents/FInput.vue';
import FSelect from '@/components/fcomponents/FSelect.vue';
import FLoader from '@/components/fcomponents/FLoader.vue';
import FSlider from '@/components/fcomponents/FSlider.vue';
import { Icon } from '@iconify/vue';
import { bigInt2Number } from '@/utils/helper';
import { loadPositions, usePositions, type Position } from '@/composables/usePositions';
import { useStake } from '@/composables/useStake';
import { useClaim } from '@/composables/useClaim';
import { useAdjustTaxRate } from '@/composables/useAdjustTaxRates';
import { useSnatchSelection } from '@/composables/useSnatchSelection';
import { assetsToShares } from '@/contracts/stake';
import { getMinStake } from '@/contracts/harb';
import { useWallet } from '@/composables/useWallet';
import { ref, onMounted, watch, computed, watchEffect } from 'vue';
import { useStatCollection, loadStats } from '@/composables/useStatCollection';
import { useRoute } from 'vue-router';

const demo = sessionStorage.getItem('demo') === 'true';
const route = useRoute();

const adjustTaxRate = useAdjustTaxRate();

const StakeMenuOpen = ref(false);
const taxRate = ref<number>(1.0);
const loading = ref<boolean>(true);
const stakeSnatchLoading = ref<boolean>(false);
const stake = useStake();
const _claim = useClaim();
const wallet = useWallet();
const statCollection = useStatCollection();

const { activePositions: _activePositions } = usePositions();

const minStake = ref(0n);
const stakeSlots = ref();
const supplyFreeze = ref<number>(0);
let debounceTimer: ReturnType<typeof setTimeout>;
watchEffect(() => {
  if (!stake.stakingAmount) {
    supplyFreeze.value = 0;
    return;
  }

  clearTimeout(debounceTimer);
  debounceTimer = setTimeout(async () => {
    stake.stakingAmountShares = await assetsToShares(stake.stakingAmount);
    const stakingAmountSharesNumber = bigInt2Number(stake.stakingAmountShares, 18);
    const stakeableSupplyNumber = bigInt2Number(statCollection.stakeableSupply, 18);
    minStake.value = await getMinStake();

    supplyFreeze.value = stakingAmountSharesNumber / stakeableSupplyNumber;
  }, 500);
});

watchEffect(() => {
  stakeSlots.value = (supplyFreeze.value * 1000)?.toFixed(2);
});

const _tokenIssuance = computed(() => {
  if (statCollection.kraikenTotalSupply === 0n) {
    return 0n;
  }

  return (statCollection.nettoToken7d / statCollection.kraikenTotalSupply) * 100n;
});

async function stakeSnatch() {
  if (snatchSelection.snatchablePositions.value.length === 0) {
    await stake.snatch(stake.stakingAmount, taxRate.value);
  } else {
    const snatchAblePositionsIds = snatchSelection.snatchablePositions.value.map((p: Position) => p.positionId);
    await stake.snatch(stake.stakingAmount, taxRate.value, snatchAblePositionsIds);
  }
  stakeSnatchLoading.value = true;
  await new Promise(resolve => setTimeout(resolve, 10000));
  await loadPositions();
  await loadStats();
  stakeSnatchLoading.value = false;
}

watch(
  route,
  async to => {
    if (to.hash === '#stake') {
      StakeMenuOpen.value = true;
    }
  },
  { flush: 'pre', immediate: true, deep: true }
);

onMounted(async () => {
  try {
    minStake.value = await getMinStake();
    stake.stakingAmountNumber = minStakeAmount.value;
  } finally {
    loading.value = false;
  }
});

const minStakeAmount = computed(() => {
  return bigInt2Number(minStake.value, 18);
});

const maxStakeAmount = computed(() => {
  if (wallet.balance?.value) {
    return bigInt2Number(wallet.balance.value, 18);
  } else {
    return 0;
  }
});

watch(
  minStakeAmount,
  async newValue => {
    if (newValue > stake.stakingAmountNumber && stake.stakingAmountNumber === 0) {
      stake.stakingAmountNumber = minStakeAmount.value;
    }
  },
  { immediate: true }
);

function setMaxAmount() {
  stake.stakingAmountNumber = maxStakeAmount.value;
}

const snatchSelection = useSnatchSelection(demo, taxRate);
</script>

<style lang="sass">

.hold-inner
    .stake-inner
        display: flex
        flex-direction: column
        gap: 24px
        .formular
            display: flex
            flex-direction: column
            gap: 8px
            .row
                >*
                    flex: 1 1 auto
            .row-1
                gap: 12px
                >:nth-child(2)
                    flex: 0 0 auto
                .staking-amount
                    .f-input--details
                        display: flex
                        gap: 8px
                        justify-content: flex-end
                        color: #9A9898
                        font-size: 14px
                        .staking-amount-max
                            font-weight: 600
                            &:hover, &:active, &:focus
                                cursor: pointer
            .row-2
                justify-content: space-between
                >*
                    flex: 0 0 30%
.stake-arrow
    align-self: center
    font-size: 30px
</style>
