<template>
  <FCollapse class="f-collapse-active" @collapse:opened="loadActivePositionData" :loading="loading">
    <template v-slot:header>
      <div class="collapse-header">
        <div class="collapse-header-row1">
          <div><span class="subheader2">Tax</span> {{ props.taxRate }} %</div>
          <FButton size="tiny" @click="payTax(props.id)">Pay Tax</FButton>
          <div class="position-id">
            <span class="subheader2">ID</span> <span class="number-small">{{ props.id }}</span>
          </div>
        </div>
        <div class="collapse-header-row2">
          <div>
            <div class="profit-stats-item">
              <div><b>Initial Stake</b></div>
              <div>{{ compactNumber(props.amount) }} $KRK</div>
            </div>
          </div>
          <div class="tags-list">
            <FTag v-if="tag">{{ tag }}</FTag>
          </div>
        </div>
        <div class="pnl-metrics">
          <div class="pnl-line1" :class="{ 'pnl-positive': netReturn > 0, 'pnl-negative': netReturn < 0 }">
            Gross: {{ formatPercent(grossReturn) }} · Tax: {{ formatPercent(-taxCostPercent) }} · Net: {{ formatPercent(netReturn) }}
          </div>
          <div class="pnl-line2">
            Held {{ timeHeldFormatted }} · Snatched {{ props.position.snatched }} time{{ props.position.snatched === 1 ? '' : 's' }}
          </div>
        </div>
        <!-- <div class="collapse-amount">
					<span class="number-small">{{ compactNumber(props.amount) }}</span>
					<span class="caption"> $KRK</span>
				</div> -->
      </div>
    </template>
    <div class="collapsed-body">
      <div v-if="error" class="collapsed-body--error">
        <span>{{ error }}</span>
        <FButton size="tiny" outlined @click="loadActivePositionData">Retry</FButton>
      </div>
      <div v-if="unstakeError" class="collapsed-body--error">
        <span>{{ unstakeError }}</span>
      </div>
      <div v-if="!error || taxPaidGes !== undefined" class="profit-stats-wrapper">
        <div class="profit-stats-item">
          <div><b>Tax Cost</b></div>
          <div>{{ taxPaidGes !== undefined ? formatTokenAmount(taxPaidGes) : '...' }} $KRK</div>
        </div>
        <div class="profit-stats-item">
          <div><b>Issuance Earned</b></div>
          <div>{{ profit !== undefined ? formatTokenAmount(profit) : '...' }} $KRK</div>
        </div>
        <div class="profit-stats-item profit-stats-total">
          <div><b>Total</b></div>
          <div>{{ total !== undefined ? formatTokenAmount(total) : '...' }} $KRK</div>
        </div>
      </div>
    </div>
    <div class="collapsed-body--actions">
      <div :class="{ 'collapse-menu-open': showTaxMenu }">
        <FButton size="small" dense block outlined v-if="adjustTaxRate.state === 'SignTransaction'">Sign Transaction ...</FButton>
        <FButton size="small" dense outlined block v-else-if="adjustTaxRate.state === 'Waiting'" @click="unstakePosition"
          >Waiting ...</FButton
        >
        <FButton size="small" dense block v-else-if="adjustTaxRate.state === 'Action' && !showTaxMenu" @click="showTaxMenu = true"
          >Adjust Tax Rate</FButton
        >
        <template v-else>
          <div class="collapse-menu-input">
            <FSelect :items="filteredTaxRates" v-model="newTaxRateIndex"> </FSelect>
          </div>
          <div>
            <FButton size="small" dense @click="changeTax(props.id, newTaxRateIndex)">Confirm</FButton>
            <FButton size="small" dense outlined @click="showTaxMenu = false">Cancel</FButton>
          </div>
        </template>
      </div>
      <div></div>
      <div>
        <FButton size="small" dense block outlined v-if="unstake.state === 'SignTransaction'">Sign Transaction ...</FButton>
        <FButton size="small" dense outlined block v-else-if="unstake.state === 'Waiting'">Waiting ...</FButton>
        <FButton size="small" dense block v-else-if="unstake.state === 'Unstakeable'" @click="unstakePosition">Unstake</FButton>
      </div>
    </div>
  </FCollapse>
</template>

<script setup lang="ts">
import FButton from '@/components/fcomponents/FButton.vue';
import FTag from '@/components/fcomponents/FTag.vue';
import FSelect from '@/components/fcomponents/FSelect.vue';
import FCollapse from '@/components/fcomponents/FCollapse.vue';
import { compactNumber, weiToNumber, formatTokenAmount } from 'kraiken-lib/format';
import { useUnstake } from '@/composables/useUnstake';
import { useAdjustTaxRate } from '@/composables/useAdjustTaxRates';
import { computed, ref, onMounted } from 'vue';
import { getTaxDue, payTax } from '@/contracts/stake';
import { type Position, loadPositions, loadActivePositions } from '@/composables/usePositions';
import { useStatCollection } from '@/composables/useStatCollection';
import { useWallet } from '@/composables/useWallet';
import { DEFAULT_CHAIN_ID } from '@/config';
import { calculateActivePositionProfit } from 'kraiken-lib/position';

const unstake = useUnstake();
const adjustTaxRate = useAdjustTaxRate();
const wallet = useWallet();
const initialChainId = wallet.account.chainId ?? DEFAULT_CHAIN_ID;
const statCollection = useStatCollection(initialChainId);
const currentChainId = computed(() => wallet.account.chainId ?? DEFAULT_CHAIN_ID);

const props = defineProps<{
  taxRate: number;
  taxRateIndex?: number;
  tresholdIndex: number;
  id: bigint;
  amount: number;
  position: Position;
}>();

const showTaxMenu = ref(false);
const newTaxRateIndex = ref<number | null>(null);
const taxDue = ref<bigint>(0n);
const taxPaidGes = ref<number>();
const profit = ref<number>();
const loading = ref<boolean>(false);
const error = ref<string | null>(null);
const unstakeError = ref<string | null>(null);

const tag = computed(() => {
  // Compare by index instead of decimal to avoid floating-point issues
  const idx = props.taxRateIndex ?? props.position.taxRateIndex;
  if (typeof idx === 'number' && idx < props.tresholdIndex) {
    return 'Low Tax!';
  }
  return '';
});

const total = computed(() => {
  if (profit.value === undefined || taxPaidGes.value === undefined) return undefined;
  return props.amount + profit.value - taxPaidGes.value;
});

// P&L calculations (FIXED: Use BigInt math to preserve precision)
const grossReturn = computed(() => {
  try {
    const currentSupply = BigInt(statCollection.kraikenTotalSupply);
    const initSupply = BigInt(props.position.totalSupplyInit);

    if (initSupply === 0n) return 0;

    // Calculate percentage change using BigInt to avoid precision loss
    // Formula: ((current - init) / init) * 100
    // To maintain precision, multiply by 10000 first, then divide by 100 for display
    const diff = currentSupply - initSupply;
    const percentBigInt = (diff * 10000n) / initSupply;

    return Number(percentBigInt) / 100;
  } catch (error) {
    void error; // suppress lint
    return 0;
  }
});

const taxCostPercent = computed(() => {
  try {
    const taxPaid = props.position.taxPaid + taxDue.value;
    const deposit = BigInt(props.position.harbDeposit);

    if (deposit === 0n) return 0;

    // Calculate percentage using BigInt precision
    const percentBigInt = (taxPaid * 10000n) / deposit;

    return Number(percentBigInt) / 100;
  } catch (error) {
    void error; // suppress lint
    return 0;
  }
});

const netReturn = computed(() => {
  return grossReturn.value - taxCostPercent.value;
});

const timeHeldFormatted = computed(() => {
  if (!props.position.creationTime) return '0d 0h';
  // Handle both Date objects and bigint/number timestamps
  let creationTimestamp: number;
  if (props.position.creationTime instanceof Date) {
    creationTimestamp = Math.floor(props.position.creationTime.getTime() / 1000);
  } else {
    creationTimestamp = Number(props.position.creationTime);
  }
  const nowTimestamp = Math.floor(Date.now() / 1000);
  const secondsHeld = nowTimestamp - creationTimestamp;
  const days = Math.floor(secondsHeld / 86400);
  const hours = Math.floor((secondsHeld % 86400) / 3600);
  return `${days}d ${hours}h`;
});

function formatPercent(value: number): string {
  const sign = value >= 0 ? '+' : '';
  return `${sign}${value.toFixed(1)}%`;
}

const filteredTaxRates = computed(() => {
  const currentIndex = props.position.taxRateIndex ?? -1;
  return adjustTaxRate.taxRates.filter(option => option.index > currentIndex);
});

async function changeTax(id: bigint, nextTaxRateIndex: number | null) {
  if (typeof nextTaxRateIndex !== 'number') {
    return;
  }
  await adjustTaxRate.changeTax(id, nextTaxRateIndex);
  showTaxMenu.value = false;
}

async function unstakePosition() {
  unstakeError.value = null;
  let exitSucceeded = false;
  try {
    await unstake.exitPosition(props.id);
    exitSucceeded = true;
    loading.value = true;
    const POLL_INTERVAL_MS = 1000;
    const TIMEOUT_MS = 30_000;
    const deadline = Date.now() + TIMEOUT_MS;
    while (Date.now() < deadline) {
      const { positions } = await loadActivePositions(currentChainId.value);
      if (!positions.some(p => BigInt(p.id) === props.id)) break;
      // eslint-disable-next-line no-restricted-syntax -- Poll interval; Ponder has no push endpoint. See AGENTS.md #Engineering Principles.
      await new Promise<void>(resolve => setTimeout(resolve, POLL_INTERVAL_MS));
    }
    await loadPositions(currentChainId.value);
  } catch (err) {
    // eslint-disable-next-line no-console
    console.error(exitSucceeded ? 'Failed to refresh positions after unstake:' : 'Failed to unstake position:', err);
    unstakeError.value = exitSucceeded
      ? 'Position unstaked, but failed to refresh data.'
      : 'Failed to unstake position.';
  } finally {
    loading.value = false;
  }
}

async function loadActivePositionData() {
  loading.value = true;
  error.value = null;
  taxPaidGes.value = undefined;
  profit.value = undefined;
  try {
    //loadTaxDue
    taxDue.value = await getTaxDue(props.id);
    taxPaidGes.value = weiToNumber(taxDue.value + props.position.taxPaid);

    //loadTotalSupply

    // Calculate issuance earned using kraiken-lib profit calculation
    profit.value = calculateActivePositionProfit(props.position.totalSupplyInit, statCollection.kraikenTotalSupply, props.position.share);
  } catch (err) {
    // eslint-disable-next-line no-console
    console.error('Failed to load active position data:', err);
    error.value = 'Failed to load position data.';
  } finally {
    loading.value = false;
  }
}

onMounted(() => {
  const availableRates = filteredTaxRates.value;
  if (availableRates.length > 0) {
    newTaxRateIndex.value = availableRates[0]?.index ?? null;
  } else if (typeof props.position.taxRateIndex === 'number') {
    newTaxRateIndex.value = props.position.taxRateIndex;
  } else {
    newTaxRateIndex.value = adjustTaxRate.taxRates[0]?.index ?? null;
  }
});
</script>

<style lang="sass">
@use 'collapse'
.f-collapse
    &.f-collapse-active
        background-color: #07111B
        .collapse-header
            width: 100%
            display: flex
            justify-content: space-between
            flex-direction: column
            position: relative
            gap: 16px
            .collapse-header-row1
                display: flex
                flex-direction: row
                gap: 16px
                align-items: center
                // margin-right: 32px

                .position-id
                    margin-left: auto
            .collapse-header-row2
                display: flex
                justify-content: space-between
                >div
                    width: 50%
                    min-height: 22px
                    .profit-stats-item
                        display: grid
                        grid-template-columns: 1fr 1fr
                        gap: 8px
                        div
                            &:last-child
                                text-align: right
                .tags-list
                    margin-right: 32px
                    text-align: right
            .pnl-metrics
                display: flex
                flex-direction: column
                gap: 4px
                padding-top: 8px
                font-size: 13px
                .pnl-line1
                    font-weight: 500
                    &.pnl-positive
                        color: #4ade80
                    &.pnl-negative
                        color: #f87171
                .pnl-line2
                    color: #9A9898
                    font-size: 12px
.collapsableDiv
    .collapsed-body
        display: flex
        flex-direction: column
        margin-right: 32px
        .collapsed-body--header
            justify-content: space-between
        .profit-stats-wrapper
            display: flex

            flex-direction: column
            gap: 4px
            margin: 0
            margin-top: 4px
            width: 100%
            color: white
            @media (min-width: 768px)
                width: 50%
                margin: 4px auto 0 0
            .profit-stats-item
                display: grid
                grid-template-columns: 1fr 1fr
                gap: 8px
                div
                    &:last-child
                        text-align: right
                &.profit-stats-total
                    border-top: 2px solid var(--color-font)
                    padding-top: 2px
        .collapsed-body--error
            display: flex
            flex-wrap: wrap
            align-items: center
            gap: 8px
            color: #f87171
            font-size: 13px
            margin-bottom: 8px
        .collapsed-body--actions
            .collapse-menu-open
                display: flex
                align-items: center
                gap: 4px
                flex: 1 1 auto
                .collapse-menu-input
                    display: flex
                    align-items: center
</style>
