import { useState, useEffect, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import { useWallet } from '../context/WalletContext';
import axios from 'axios';
import TokenIcon, { TOKEN_ICON_MAP } from '../components/TokenIcon';
import useStakingRates from '../hooks/useStakingRates';

const FALLBACK_TOP_SYMBOLS = ['TRUMP', 'STRK', 'ATOM'];
const FALLBACK_APRS = {
  TRUMP: 26.1,
  STRK: 25.3,
  ATOM: 22.1
};

const hexToRgba = (hex, alpha = 0.15) => {
  if (!hex || !/^#?[0-9a-fA-F]{3,6}$/.test(hex)) {
    return `rgba(72, 255, 145, ${alpha})`;
  }
  const normalized = hex.replace('#', '');
  const bigint = parseInt(normalized.length === 3 ? normalized.repeat(2) : normalized, 16);
  const r = (bigint >> 16) & 255;
  const g = (bigint >> 8) & 255;
  const b = bigint & 255;
  return `rgba(${r}, ${g}, ${b}, ${alpha})`;
};

const buildGradient = (primary, secondary) =>
  `linear-gradient(135deg, ${hexToRgba(primary, 0.18)} 0%, ${hexToRgba(secondary, 0.18)} 100%)`;

const EarnPage = () => {
  const navigate = useNavigate();
  const { activeWallet, refreshSession } = useWallet();
  const [loading, setLoading] = useState(true);
  const [stakingData, setStakingData] = useState(null);
  const [claimLoading, setClaimLoading] = useState({});
  const [actionMessage, setActionMessage] = useState(null);
  const [actionType, setActionType] = useState(null);
  const { rates } = useStakingRates(activeWallet?.mnemonic);

  const topStakingOptions = useMemo(() => {
    const list = Object.entries(rates || {})
      .map(([symbol, config]) => {
        const aprValue = Number(config?.apr ?? 0);
        if (!aprValue || Number.isNaN(aprValue)) return null;
        const iconMeta = TOKEN_ICON_MAP[symbol] || {};
        return {
          symbol,
          name: symbol,
          apr: Number(aprValue.toFixed(2)),
          gradient: buildGradient(iconMeta.mainColor, iconMeta.networkColor)
        };
      })
      .filter(Boolean)
      .sort((a, b) => b.apr - a.apr)
      .slice(0, 3);

    if (list.length > 0) {
      return list;
    }

    return FALLBACK_TOP_SYMBOLS.map((symbol) => {
      const iconMeta = TOKEN_ICON_MAP[symbol] || {};
      return {
        symbol,
        name: symbol,
        apr: FALLBACK_APRS[symbol] ?? 0,
        gradient: buildGradient(iconMeta.mainColor, iconMeta.networkColor)
      };
    });
  }, [rates]);

  useEffect(() => {
    loadStakingPortfolio(true);
  }, [activeWallet]);

  const loadStakingPortfolio = async (withLoader = false) => {
    if (!activeWallet || !activeWallet.mnemonic) {
      if (withLoader) {
        setLoading(false);
      }
      return;
    }

    try {
      if (withLoader) {
        setLoading(true);
      }
      const response = await axios.get('/api/staking/info', {
        params: { phrase: activeWallet.mnemonic }
      });

      if (response.data.success) {
        setStakingData(response.data.data);
      }
    } catch (error) {
      console.error('Error loading staking portfolio:', error);
    } finally {
      if (withLoader) {
        setLoading(false);
      }
    }
  };

  const usdFormatter = useMemo(
    () =>
      new Intl.NumberFormat('en-US', {
        style: 'currency',
        currency: 'USD',
        minimumFractionDigits: 2,
        maximumFractionDigits: 2
      }),
    []
  );

  const tokenMetaMap = useMemo(() => {
    const map = {};

    if (activeWallet?.tokens) {
      activeWallet.tokens.forEach((token) => {
        const symbol = token.tokenInfo?.symbol;
        if (!symbol) return;
        map[symbol] = {
          name: token.tokenInfo?.name || symbol,
          price: parseFloat(token.tokenInfo?.price) || 0,
          icon: token.tokenInfo?.icon || null
        };
      });
    }

    return map;
  }, [activeWallet]);

  const aggregatedPositions = useMemo(() => {
    if (!stakingData?.positions?.length) return [];

    const groups = stakingData.positions.reduce((acc, position) => {
      const token = position.token_symbol;
      if (!acc[token]) {
        acc[token] = {
          token,
          totalStaked: 0,
          totalRewards: 0,
          positions: [],
          weightedApr: 0
        };
      }
      acc[token].totalStaked += position.amount;
      acc[token].totalRewards += position.total_rewards;
      acc[token].weightedApr += position.apr * position.amount;
      acc[token].positions.push(position);
      return acc;
    }, {});

    return Object.values(groups).map((group) => {
      const meta = tokenMetaMap[group.token] || {};
      const price = meta.price || 0;
      const totalValue = group.totalStaked * price;
      const rewardsValue = group.totalRewards * price;
      const avgApr = group.totalStaked > 0 ? group.weightedApr / group.totalStaked : 0;

      const earliestPosition = group.positions.reduce((soonest, pos) => {
        if (!soonest) return pos;
        return new Date(pos.unlockDate) < new Date(soonest.unlockDate) ? pos : soonest;
      }, null);

      let progress = 0;
      let remainingLabel = 'Готово';

      if (earliestPosition) {
        const unlockDate = earliestPosition.unlockDate ? new Date(earliestPosition.unlockDate) : null;
        const startDate = earliestPosition.start_date
          ? new Date(earliestPosition.start_date)
          : (earliestPosition.created_at ? new Date(earliestPosition.created_at) : null);

        if (unlockDate && startDate && unlockDate.getTime() > startDate.getTime()) {
          const now = Date.now();
          progress = Math.min(
            1,
            Math.max(0, (now - startDate.getTime()) / (unlockDate.getTime() - startDate.getTime()))
          );
        } else if (earliestPosition.canUnlock) {
          progress = 1;
        }

        const remainingDays = earliestPosition.daysRemaining ?? 0;
        if (earliestPosition.canUnlock) {
          remainingLabel = 'Готово';
        } else if (remainingDays <= 0) {
          remainingLabel = 'менее дня';
        } else if (remainingDays === 1) {
          remainingLabel = '1 день';
        } else {
          remainingLabel = `${remainingDays} дней`;
        }
      }

      return {
        token: group.token,
        name: meta.name || group.token,
        price,
        totalStaked: group.totalStaked,
        totalRewards: group.totalRewards,
        totalValue,
        rewardsValue,
        avgApr,
        positions: group.positions,
        progress,
        remainingLabel,
        canClaim: group.positions.some((pos) => pos.total_rewards > 0)
      };
    });
  }, [stakingData, tokenMetaMap]);

  const totalUSD = useMemo(
    () => aggregatedPositions.reduce((sum, position) => sum + position.totalValue, 0),
    [aggregatedPositions]
  );

  const totalRewardsUSD = useMemo(
    () => aggregatedPositions.reduce((sum, position) => sum + position.rewardsValue, 0),
    [aggregatedPositions]
  );

  const hasStaking = aggregatedPositions.length > 0;

  const handleClaimAll = async (token) => {
    if (!stakingData?.positions || !activeWallet?.mnemonic) return;

    const positionsToClaim = stakingData.positions.filter(
      (position) => position.token_symbol === token && position.total_rewards > 0
    );

    if (!positionsToClaim.length) {
      setActionMessage(`По токену ${token} нет наград для получения`);
      setActionType('info');
      return;
    }

    setClaimLoading((prev) => ({ ...prev, [token]: true }));
    setActionMessage(null);

    try {
      for (const pos of positionsToClaim) {
        await axios.post('/api/staking/claim', {
          phrase: activeWallet.mnemonic,
          positionId: pos.id
        });
      }

      setActionMessage(`Награды по ${token} успешно получены`);
      setActionType('success');

      await loadStakingPortfolio(false);
      if (typeof refreshSession === 'function') {
        await refreshSession();
      }
    } catch (error) {
      console.error('Error claiming rewards:', error);
      setActionMessage(error.response?.data?.error || 'Не удалось получить награды');
      setActionType('error');
    } finally {
      setClaimLoading((prev) => ({ ...prev, [token]: false }));
    }
  };

  const formatTokenAmount = (value) => value.toFixed(4);
  const formatRewardsAmount = (value) => value.toFixed(6);

  return (
    <div className="min-h-screen bg-[#1b1b1c] pb-32">
      {/* Header */}
      <div className="sticky top-0 z-10 bg-[#1b1b1c]/95 backdrop-blur-sm border-b border-gray-800">
        <div className="max-w-md mx-auto px-4 py-4 flex items-center">
          <button
            onClick={() => navigate(-1)}
            className="mr-4 text-gray-400 hover:text-white transition-colors"
          >
            <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
            </svg>
          </button>
          <h1 className="text-xl font-semibold text-white">Earn</h1>
        </div>
      </div>

      <div className="max-w-md mx-auto px-4 py-6 space-y-6">
        {loading ? (
          <div className="flex justify-center items-center py-12">
            <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-[#48ff91]"></div>
          </div>
        ) : (
          <>
            {/* Общая статистика */}
            <div className="bg-gradient-to-br from-[#48ff91]/10 to-transparent rounded-2xl p-6 border border-[#48ff91]/20">
              <div className="text-gray-400 text-sm mb-2">Портфолио стейкинга</div>
              
              {/* Общий баланс в USD */}
              <div className="mb-4">
                <div className="text-4xl font-bold text-white">
                  {usdFormatter.format(totalUSD || 0)}
                </div>
              </div>
              
              <div className="grid grid-cols-2 gap-4">
                <div className="bg-gray-800/30 rounded-xl p-3">
                  <div className="text-gray-400 text-xs mb-1">Активных позиций</div>
                  <div className="text-white text-lg font-semibold">
                    {stakingData?.summary?.activePositions || 0}
                  </div>
                  <div className="text-gray-500 text-xs">
                    {aggregatedPositions.length} Tokens
                  </div>
                </div>
                
                <div className="bg-gray-800/30 rounded-xl p-3">
                  <div className="text-gray-400 text-xs mb-1">Награды</div>
                  <div className="text-[#48ff91] text-lg font-semibold">
                    {usdFormatter.format(totalRewardsUSD || 0)}
                  </div>
                  <div className="text-gray-500 text-xs">доступно к выводу</div>
                </div>
              </div>
            </div>

            {/* Активные позиции по токенам */}
            {hasStaking && (
              <div>
                <h2 className="text-white font-semibold mb-3 px-1">Мои позиции</h2>

                {actionMessage && (
                  <div
                    className={`mb-3 px-3 py-2 rounded-lg text-sm ${
                      actionType === 'success'
                        ? 'bg-green-500/10 border border-green-500/40 text-green-300'
                        : actionType === 'error'
                        ? 'bg-red-500/10 border border-red-500/40 text-red-300'
                        : 'bg-yellow-500/10 border border-yellow-500/40 text-yellow-200'
                    }`}
                  >
                    {actionMessage}
                  </div>
                )}

                <div className="space-y-3">
                  {aggregatedPositions.map((group) => (
                    <div key={group.token} className="w-full bg-gray-800/30 rounded-xl p-4">
                      <div className="flex items-start justify-between">
                        <div className="flex items-center space-x-3">
                          <TokenIcon symbol={group.token} size="w-12 h-12" />
                          <div>
                            <div className="flex items-center space-x-2">
                              <span className="text-white font-semibold text-base">{group.name}</span>
                              <span className="text-gray-500 text-xs uppercase">{group.token}</span>
                            </div>
                            <div className="text-sm text-gray-400">
                              {group.positions.length}{' '}
                              {group.positions.length === 1 ? 'позиция' : 'позиций'}
                            </div>
                          </div>
                        </div>

                        <div className="text-right">
                          <div className="text-white font-semibold text-sm">
                            {usdFormatter.format(group.totalValue || 0)}
                          </div>
                          <div className="text-xs text-gray-400">
                            {formatTokenAmount(group.totalStaked)} {group.token}
                          </div>
                          <div className="text-xs text-[#48ff91] mt-1">
                            +{formatRewardsAmount(group.totalRewards)} {group.token}
                          </div>
                        </div>
                      </div>

                      <div className="grid grid-cols-3 gap-3 text-xs text-gray-400 mt-3">
                        <div>
                          <div className="text-gray-500">APR</div>
                          <div className="text-white font-medium">{group.avgApr.toFixed(2)}%</div>
                        </div>
                        <div>
                          <div className="text-gray-500">Награды (USD)</div>
                          <div className="text-[#48ff91] font-medium">
                            {usdFormatter.format(group.rewardsValue || 0)}
                          </div>
                        </div>
                        <div>
                          <div className="text-gray-500">До разблокировки</div>
                          <div className="text-white font-medium">{group.remainingLabel}</div>
                        </div>
                      </div>

                      <div className="mt-4 flex gap-2 flex-col sm:flex-row">
                        <button
                          onClick={() => handleClaimAll(group.token)}
                          disabled={!group.canClaim || claimLoading[group.token]}
                          className={`w-full py-2 rounded-lg text-sm font-medium transition-all ${
                            group.canClaim && !claimLoading[group.token]
                              ? 'bg-[#48ff91]/20 text-[#48ff91] hover:bg-[#48ff91]/30'
                              : 'bg-gray-800 text-gray-500 cursor-not-allowed'
                          }`}
                        >
                          {claimLoading[group.token] ? 'Получение...' : 'Забрать награды'}
                        </button>
                        <button
                          onClick={() => navigate(`/staking/${group.token}`)}
                          className="w-full py-2 rounded-lg text-sm font-medium bg-[#48ff91] text-[#1b1b1c] hover:bg-[#3de484] transition-all"
                        >
                          Управлять стейкингом
                        </button>
                      </div>
                    </div>
                  ))}
                </div>
              </div>
            )}

            {/* Топ предложения для стейкинга */}
            <div>
              <h2 className="text-white font-semibold mb-3 px-1">
                {hasStaking ? 'Больше возможностей' : 'Начните зарабатывать'}
              </h2>
              <div className="space-y-3">
                {topStakingOptions.map((option) => {
                  const isStaked = aggregatedPositions.find((group) => group.token === option.symbol);
                  return (
                    <button
                      key={option.symbol}
                      onClick={() => navigate(`/currency/${option.symbol}`)}
                      className="w-full rounded-xl p-4 hover:bg-gray-800/50 transition-colors relative overflow-hidden bg-gray-800/30"
                    >
                      {/* Градиентный фон */}
                      <div
                        className="absolute inset-0 opacity-60"
                        style={{ background: option.gradient }}
                      ></div>
                      
                      <div className="relative flex items-center justify-between">
                        <div className="flex items-center space-x-3">
                          <TokenIcon symbol={option.symbol} size="w-12 h-12" />
                          <div className="text-left">
                            <div className="text-white font-medium flex items-center space-x-2">
                              <span>{option.name}</span>
                              {isStaked && (
                                <span className="text-xs bg-[#48ff91]/20 text-[#48ff91] px-2 py-0.5 rounded">
                                  Активен
                                </span>
                              )}
                            </div>
                            <div className="text-gray-400 text-sm">
                              Стейкинг {option.symbol}
                            </div>
                          </div>
                        </div>
                        
                        <div className="text-right">
                          <div className="text-[#48ff91] text-xl font-bold">
                            {option.apr}%
                          </div>
                          <div className="text-gray-400 text-xs">APR</div>
                        </div>
                      </div>
                    </button>
                  );
                })}
              </div>
            </div>

            {/* Информационный блок */}
            {!hasStaking && (
              <div className="bg-gray-800/20 rounded-xl p-4 border border-gray-700/50">
                <div className="flex items-start space-x-3">
                  <div className="text-2xl">💡</div>
                  <div>
                    <div className="text-white font-medium mb-1">
                      Как начать зарабатывать?
                    </div>
                    <ul className="text-gray-400 text-sm space-y-2">
                      <li className="flex items-start">
                        <span className="text-[#48ff91] mr-2">1.</span>
                        <span>Выберите криптовалюту из списка выше</span>
                      </li>
                      <li className="flex items-start">
                        <span className="text-[#48ff91] mr-2">2.</span>
                        <span>Разместите средства в стейкинг</span>
                      </li>
                      <li className="flex items-start">
                        <span className="text-[#48ff91] mr-2">3.</span>
                        <span>Получайте награды каждый день</span>
                      </li>
                    </ul>
                  </div>
                </div>
              </div>
            )}

            {/* Преимущества стейкинга */}
            <div className="bg-gradient-to-br from-gray-800/30 to-transparent rounded-xl p-4 border border-gray-700/50">
              <h3 className="text-white font-medium mb-3">Преимущества стейкинга</h3>
              <div className="space-y-3">
                <div className="flex items-start space-x-3">
                  <div className="text-[#48ff91] text-xl">✓</div>
                  <div>
                    <div className="text-white text-sm font-medium">Пассивный доход</div>
                    <div className="text-gray-400 text-xs">
                      Зарабатывайте награды без активных действий
                    </div>
                  </div>
                </div>
                <div className="flex items-start space-x-3">
                  <div className="text-[#48ff91] text-xl">✓</div>
                  <div>
                    <div className="text-white text-sm font-medium">Гибкость</div>
                    <div className="text-gray-400 text-xs">
                      Короткий период блокировки всего 4 дня
                    </div>
                  </div>
                </div>
                <div className="flex items-start space-x-3">
                  <div className="text-[#48ff91] text-xl">✓</div>
                  <div>
                    <div className="text-white text-sm font-medium">Высокие ставки</div>
                    <div className="text-gray-400 text-xs">
                      APR обновляется динамически для каждого токена
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </>
        )}
      </div>
    </div>
  );
};

export default EarnPage;
