import { useState } from 'react'
import { Notification } from '@shared/ui'
import { truncateDecimals } from '@shared/lib/utils/truncateDecimals'
import { ChainToggle } from './ChainToggle'
import { StakeCard } from './StakeCard'
import { PositionsPanel } from './PositionsPanel'
import { UnstakeModal } from './UnstakeModal'
import {
  useStake,
  useUnstake,
  useClaim,
  getStakingErrorMessage,
  type StakeChain,
  type SolPosition,
} from '@features/staking'
import { CHAIN_META } from '../model/meta'
import styles from './StakingWidget.module.css'

type ModalState = { kind: 'eth'; amount: string } | { kind: 'sol'; position: SolPosition } | null

type Toast = { status: 'success' | 'error' | 'info'; message: string } | null

export function StakingWidget() {
  const [chain, setChain] = useState<StakeChain>('ETH')
  const [amount, setAmount] = useState('')
  const [modal, setModal] = useState<ModalState>(null)
  const [toast, setToast] = useState<Toast>(null)

  const stakeM = useStake()
  const unstakeM = useUnstake()
  const claimM = useClaim()

  function handleChain(next: StakeChain) {
    setChain(next)
    setAmount('')
  }

  // stakeAmountHuman — это сумма стейка A (= введённое − газ), её и отправляем на бэкенд.
  function handleStake(stakeAmountHuman: string) {
    stakeM.mutate(
      { chain, amountHuman: stakeAmountHuman },
      {
        onSuccess: () => {
          setToast({
            status: 'success',
            message: `Стейкинг ${truncateDecimals(stakeAmountHuman, 6)} ${CHAIN_META[chain].symbol} выполнен`,
          })
          setAmount('')
        },
        onError: (e) => setToast({ status: 'error', message: getStakingErrorMessage(e) }),
      }
    )
  }

  function handleConfirm(mode?: 'swap' | 'queue') {
    if (modal?.kind === 'eth') {
      const selected = mode ?? 'swap'
      unstakeM.mutate(
        { chain: 'ETH', amountHuman: modal.amount, mode: selected },
        {
          onSuccess: () => {
            setModal(null)
            setToast({
              status: 'success',
              message:
                selected === 'queue' ? 'Заявка на вывод добавлена в очередь Lido' : 'Вывод stETH → ETH выполнен',
            })
          },
          onError: (e) => setToast({ status: 'error', message: getStakingErrorMessage(e) }),
        }
      )
    } else if (modal?.kind === 'sol') {
      unstakeM.mutate(
        { chain: 'SOL', stakeAccount: modal.position.stakeAccount },
        {
          onSuccess: (res) => {
            setModal(null)
            const withdrawn = 'action' in res && res.action === 'withdraw'
            setToast({
              status: 'success',
              message: withdrawn ? 'Средства выведены на кошелёк' : 'Деактивация запущена — вывод через 1–2 эпохи',
            })
          },
          onError: (e) => setToast({ status: 'error', message: getStakingErrorMessage(e) }),
        }
      )
    }
  }

  function handleClaim(requestId: string) {
    claimM.mutate(requestId, {
      onSuccess: () => setToast({ status: 'success', message: 'ETH забран на кошелёк' }),
      onError: (e) => setToast({ status: 'error', message: getStakingErrorMessage(e) }),
    })
  }

  return (
    <div className={styles.widget}>
      <ChainToggle value={chain} onChange={handleChain} />

      <div className={styles.grid}>
        <StakeCard
          chain={chain}
          amount={amount}
          onAmountChange={setAmount}
          onStake={handleStake}
          isStaking={stakeM.isPending}
        />
        <PositionsPanel
          chain={chain}
          onUnstakeEth={(amountHuman) => setModal({ kind: 'eth', amount: amountHuman })}
          onUnstakeSol={(position) => setModal({ kind: 'sol', position })}
          onClaim={handleClaim}
          unstakePending={unstakeM.isPending}
          claimPending={claimM.isPending}
        />
      </div>

      {modal?.kind === 'eth' && (
        <UnstakeModal
          chain="ETH"
          symbol="ETH"
          amount={modal.amount}
          pending={unstakeM.isPending}
          onConfirm={handleConfirm}
          onClose={() => setModal(null)}
        />
      )}
      {modal?.kind === 'sol' && (
        <UnstakeModal
          chain="SOL"
          symbol="SOL"
          amount={modal.position.lamportsHuman}
          solState={modal.position.state}
          pending={unstakeM.isPending}
          onConfirm={handleConfirm}
          onClose={() => setModal(null)}
        />
      )}

      {toast && <Notification status={toast.status} message={toast.message} onClose={() => setToast(null)} duration={5000} />}
    </div>
  )
}
