import { Spinner, TokenIcon } from '@shared/ui'
import { COIN_ICONS } from '@shared/assets/coins'
import { truncateDecimals } from '@shared/lib/utils/truncateDecimals'
import { WithdrawNotice } from './WithdrawNotice'
import { useStakePositions, getStakingErrorMessage, type StakeChain, type SolPosition } from '@features/staking'
import { SOL_STATE_META } from '../model/meta'
import styles from './PositionsPanel.module.css'

interface Props {
  chain: StakeChain
  onUnstakeEth: (amountHuman: string) => void
  onUnstakeSol: (position: SolPosition) => void
  onClaim: (requestId: string) => void
  unstakePending: boolean
  claimPending: boolean
}

export function PositionsPanel({ chain, onUnstakeEth, onUnstakeSol, onClaim, unstakePending, claimPending }: Props) {
  const { data, isLoading, isError, error } = useStakePositions(chain)

  const badgeClass: Record<'active' | 'ready' | 'muted', string> = {
    active: styles.badgeActive,
    ready: styles.badgeReady,
    muted: styles.badgeMuted,
  }

  const total =
    data?.chain === 'ETH'
      ? data.stEthBalanceWeiHuman
      : data?.chain === 'SOL'
        ? data.positions.reduce((sum, p) => sum + (parseFloat(p.lamportsHuman) || 0), 0).toString()
        : '0'
  const unit = chain === 'ETH' ? 'stETH' : 'SOL'

  const ethEmpty =
    data?.chain === 'ETH' && (parseFloat(data.stEthBalanceWeiHuman) || 0) < 0.00000000001 && data.withdrawalRequests.length === 0
  const solEmpty = data?.chain === 'SOL' && data.positions.length === 0
  const empty = ethEmpty || solEmpty

  return (
    <div className={styles.panel}>
      <div className={styles.inner}>
        <div className={styles.head}>
          <span className={styles.title}>Мои позиции</span>
          <div className={styles.total}>
            {truncateDecimals(isError ? '0' : total, 6)} <span className={styles.totalUnit}>{unit}</span>
          </div>
        </div>

        <div className={styles.body}>
          {!isLoading && !isError && !empty && (
            <WithdrawNotice compact />
          )}

          {isLoading && <Spinner label="Загрузка позиций" />}

          {isError && <div className={styles.empty}>{getStakingErrorMessage(error)}</div>}

          {!isLoading && !isError && (empty || (data?.chain === 'ETH' && (parseFloat(data.stEthBalanceWeiHuman) || 0) < 0.00000000000001)) && (
            <div className={styles.emptyState}>
              <span className={styles.emptyIcon} aria-hidden>
                <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
                  <path d="M3 7.5 12 3l9 4.5-9 4.5z" />
                  <path d="M3 12.5 12 17l9-4.5" />
                  <path d="M3 16.5 12 21l9-4.5" />
                </svg>
              </span>
              <p className={styles.emptyTitle}>Активных позиций пока нет</p>
              <p className={styles.emptyText}>На данный момент у Вас нет активных позиций стейкинга.</p>
            </div>
          )}

          {!isError && data?.chain === 'ETH' && !empty && (
            <>
              {(parseFloat(data.stEthBalanceWeiHuman) || 0) > 0.00000000000001 && (
                <div className={styles.list}>
                  <div className={`${styles.pos} ${data.optimistic ? styles.pending : ''}`}>
                    <div className={styles.posTop}>
                      <span className={styles.coin}>
                        <TokenIcon letter="E" color="var(--grad-center)" logo={COIN_ICONS.ETH} size={24} />
                        stETH
                      </span>
                      <span className={`${styles.badge} ${styles.badgeActive}`}>
                        Активна{data.aprPercent != null ? ` · APR ${data.aprPercent}%` : ''}
                      </span>
                    </div>
                    <div className={styles.amount}>{truncateDecimals(data.stEthBalanceWeiHuman, 8)}</div>
                    <button
                      className={styles.btn}
                      onClick={() => onUnstakeEth(data.stEthBalanceWeiHuman)}
                      disabled={unstakePending}
                    >
                      Вывести
                    </button>
                  </div>
                </div>
              )}

              {(parseFloat(data.withdrawalRequests[0]?.amountStEthWeiHuman) || 0) > 0.00000000000001 && (
                <>
                  <div className={styles.subhead}>Заявки на вывод</div>
                  <div className={styles.list}>
                    {data.withdrawalRequests.map((r) => {
                      const ready = r.isFinalized && !r.isClaimed
                      return (
                        <div key={r.requestId} className={`${styles.pos} ${ready ? styles.reqCard : ''}`}>
                          <div className={styles.posTop}>
                            <span className={styles.coin}>Заявка #{r.requestId}</span>
                            <span
                              className={`${styles.badge} ${r.isClaimed ? styles.badgeMuted : ready ? styles.badgeReady : styles.badgeMuted
                                }`}
                            >
                              {r.isClaimed ? 'Выведено' : ready ? 'Готово к выводу' : 'В очереди'}
                            </span>
                          </div>
                          <div className={styles.amount}>{truncateDecimals(r.amountStEthWeiHuman, 8)} ETH</div>
                          {ready ? (
                            <button
                              className={`${styles.btn} ${styles.btnPrimary}`}
                              onClick={() => onClaim(r.requestId)}
                              disabled={claimPending}
                            >
                              Забрать ETH
                            </button>
                          ) : r.isClaimed ? null : (
                            <div className={styles.note}>Ожидает финализации в Lido</div>
                          )}
                        </div>
                      )
                    })}
                  </div>
                </>
              )}
            </>
          )}

          {!isError && data?.chain === 'SOL' && !empty && (
            <div className={styles.list}>
              {data.positions.map((p) => {
                const st = SOL_STATE_META[p.state]
                return (
                  <div key={p.stakeAccount} className={`${styles.pos} ${p.optimistic ? styles.pending : ''}`}>
                    <div className={styles.posTop}>
                      <span className={styles.coin}>
                        <TokenIcon letter="S" color="var(--grad-center)" logo={COIN_ICONS.SOL} size={24} />
                        SOL
                      </span>
                      <span className={`${styles.badge} ${badgeClass[st.variant]}`}>{st.label}</span>
                    </div>
                    <div className={styles.amount}>{truncateDecimals(p.lamportsHuman, 8)}</div>
                    <div className={styles.meta}>
                      Валидатор: {p.validator} · {p.stakeAccount}
                    </div>
                    {p.state === 'active' && (
                      <button className={styles.btn} onClick={() => onUnstakeSol(p)} disabled={unstakePending}>
                        Вывести
                      </button>
                    )}
                    {p.state === 'inactive' && (
                      <button
                        className={`${styles.btn} ${styles.btnPrimary}`}
                        onClick={() => onUnstakeSol(p)}
                        disabled={unstakePending}
                      >
                        Вывести средства
                      </button>
                    )}
                    {p.state === 'deactivating' && <div className={styles.note}>Разблокируется через 1–2 эпохи</div>}
                    {p.state === 'activating' && <div className={styles.note}>Активируется…</div>}
                  </div>
                )
              })}
            </div>
          )}
        </div>
      </div>
    </div>
  )
}
