/**
 * Copyright (c) 2024-2026 Тарабанов Александр Викторович
 * All rights reserved.
 * 
 * This software is proprietary and confidential.
 * Unauthorized copying, modification, or distribution is prohibited.
 * 
 * For licensing inquiries: info@hb3-accelerator.com
 * Website: https://hb3-accelerator.com
 * GitHub: https://github.com/VC-HB3-Accelerator
 */

import { ref, computed } from 'vue';
import { getProposals } from '@/services/proposalsService';
import { ethers } from 'ethers';
import { useProposalValidation } from './useProposalValidation';
import { voteForProposal, executeProposal as executeProposalUtil, cancelProposal as cancelProposalUtil, checkTokenBalance } from '@/utils/dle-contract';
import api from '@/api/axios';

// Функция checkVoteStatus удалена - в контракте DLE нет публичной функции hasVoted
// Функция checkTokenBalance перенесена в useDleContract.js

// Функция sendTransactionToWallet удалена - теперь используется прямое взаимодействие с контрактом

// Вспомогательная функция для получения имени цепочки
function getChainName(chainId) {
  const chainNames = {
    1: 'Ethereum',
    11155111: 'Sepolia',
    17000: 'Holesky',
    421614: 'Arbitrum Sepolia',
    84532: 'Base Sepolia',
    137: 'Polygon',
    56: 'BSC',
    42161: 'Arbitrum'
  };
  return chainNames[chainId] || `Chain ${chainId}`;
}

export function useProposals(dleAddress, isAuthenticated, userAddress) {
  const proposals = ref([]);
  const filteredProposals = ref([]);
  const isLoading = ref(false);
  const isVoting = ref(false);
  const isExecuting = ref(false);
  const isCancelling = ref(false);
  const statusFilter = ref('');
  const searchQuery = ref('');
  
  // Используем готовые функции из utils/dle-contract.js
  
  // Инициализируем валидацию
  const {
    validateProposals,
    filterRealProposals,
    filterActiveProposals,
    validationStats,
    isValidating
  } = useProposalValidation();

  const loadProposals = async () => {
    try {
      isLoading.value = true;

      // Получаем информацию о всех DLE в разных цепочках
      console.log('[Proposals] Получаем информацию о всех DLE...');
      const dleResponse = await api.get('/dle-v2');

      if (!dleResponse.data.success) {
        console.error('Не удалось получить список DLE');
        return;
      }

      const allDles = dleResponse.data.data || [];
      console.log(`[Proposals] Найдено DLE: ${allDles.length}`, allDles);

      // Группируем предложения по описанию для создания мульти-чейн представлений
      const proposalsByDescription = new Map();

      // Загружаем предложения из каждой цепочки
      for (const dle of allDles) {
        if (!dle.networks || dle.networks.length === 0) continue;

        // КРИТИЧНО: Пропускаем DLE, если ни один из его адресов не совпадает с запрошенным dleAddress
        const hasMatchingAddress = dle.networks.some(network => 
          network.address && network.address.toLowerCase() === (dleAddress.value || '').toLowerCase()
        );
        
        if (dleAddress.value && !hasMatchingAddress) {
          console.log(`[Proposals] Пропускаем DLE ${dle.dleAddress || 'N/A'}: адрес ${dleAddress.value} не найден в networks`);
          continue;
        }

        for (const network of dle.networks) {
          try {
            console.log(`[Proposals] Загружаем предложения из цепочки ${network.chainId}, адрес: ${network.address}`);
            const response = await getProposals(network.address);

            console.log(`[Proposals] Ответ для цепочки ${network.chainId}:`, {
              success: response.success,
              proposalsCount: response.data?.proposals?.length || 0,
              hasError: !!response.error
            });

            if (response.success) {
              // Бэкенд возвращает: { success: true, data: { proposals: [...], totalCount: ... } }
              const chainProposals = (response.data?.data?.proposals || response.data?.proposals || []);
              console.log(`[Proposals] Получено предложений для цепочки ${network.chainId}: ${chainProposals.length}`, chainProposals);

              // Добавляем информацию о цепочке к каждому предложению
              chainProposals.forEach(proposal => {
                proposal.chainId = network.chainId;
                proposal.contractAddress = network.address;
                proposal.networkName = getChainName(network.chainId);

                // Группируем предложения по описанию и инициатору
                const key = `${proposal.description}_${proposal.initiator}`;
                
                // Преобразуем время создания в число для сравнения
                // createdAt может быть ISO строкой или числом, timestamp - число в секундах
                const getTimestamp = (proposal) => {
                  if (proposal.timestamp) return Number(proposal.timestamp); // timestamp в секундах
                  if (proposal.createdAt) {
                    if (typeof proposal.createdAt === 'string') {
                      return Math.floor(new Date(proposal.createdAt).getTime() / 1000); // ISO строка -> секунды
                    }
                    return Number(proposal.createdAt);
                  }
                  return Math.floor(Date.now() / 1000);
                };
                
                const proposalTimestamp = getTimestamp(proposal);
                
                if (!proposalsByDescription.has(key)) {
                  proposalsByDescription.set(key, {
                    id: proposal.id, // ID из первой найденной сети
                    description: proposal.description,
                    initiator: proposal.initiator,
                    deadline: proposal.deadline,
                    chains: new Map(),
                    createdAt: proposalTimestamp, // Время создания в секундах
                    uniqueId: key
                  });
                }

                // Добавляем информацию о цепочке
                const group = proposalsByDescription.get(key);
                // Если в этой сети уже есть предложение с таким ключом, выбираем более позднее (актуальное)
                const existingChainData = group.chains.get(network.chainId);
                
                // Унифицируем state - всегда число
                const normalizedState = typeof proposal.state === 'string' 
                  ? (proposal.state === 'active' ? 0 : NaN) 
                  : Number(proposal.state);
                
                // Убеждаемся, что id есть (fallback к proposalId из события, если id отсутствует)
                const proposalId = proposal.id !== undefined && proposal.id !== null 
                  ? Number(proposal.id) 
                  : (proposal.proposalId !== undefined ? Number(proposal.proposalId) : null);
                
                if (existingChainData) {
                  // Если уже есть предложение в этой сети, сравниваем по времени создания
                  const existingTime = getTimestamp(existingChainData);
                  // Оставляем более позднее предложение (актуальное)
                  if (proposalTimestamp > existingTime) {
                    group.chains.set(network.chainId, {
                      ...proposal,
                      id: proposalId !== null ? proposalId : existingChainData.id, // Используем id с fallback
                      chainId: network.chainId,
                      contractAddress: network.address,
                      networkName: getChainName(network.chainId),
                      state: normalizedState, // Унифицированный state (число)
                      timestamp: proposalTimestamp // Сохраняем числовой timestamp для удобства
                    });
                  }
                  // Иначе оставляем существующее
                } else {
                  // Первое предложение в этой сети для данной группы
                  group.chains.set(network.chainId, {
                    ...proposal,
                    id: proposalId !== null ? proposalId : 0, // Fallback к 0, если id отсутствует
                    chainId: network.chainId,
                    contractAddress: network.address,
                    networkName: getChainName(network.chainId),
                    state: normalizedState, // Унифицированный state (число)
                    timestamp: proposalTimestamp // Сохраняем числовой timestamp для удобства
                  });
                }
                
                // Обновляем createdAt группы - минимальное время из всех предложений
                // После добавления нового предложения пересчитываем минимальное время
                const allChainTimes = Array.from(group.chains.values())
                  .map(c => getTimestamp(c));
                group.createdAt = Math.min(...allChainTimes, proposalTimestamp);
              });
            }
            } catch (error) {
            console.error(`Ошибка загрузки предложений из цепочки ${network.chainId}:`, error);
            console.error(`Детали ошибки для цепочки ${network.chainId}:`, {
              chainId: network.chainId,
              address: network.address,
              errorMessage: error.message,
              errorStack: error.stack
            });
          }
        }
      }

      // Преобразуем в массив для отображения
      const rawProposals = Array.from(proposalsByDescription.values()).map(group => {
        const chainsArray = Array.from(group.chains.values()).map(chain => {
          // Унифицируем state для каждого chain - всегда число
          const normalizedState = typeof chain.state === 'string' 
            ? (chain.state === 'active' ? 0 : NaN) 
            : Number(chain.state);
          
          // Убеждаемся, что id есть (fallback)
          const chainId = chain.id !== undefined && chain.id !== null 
            ? Number(chain.id) 
            : (chain.proposalId !== undefined ? Number(chain.proposalId) : null);
          
          return {
            ...chain,
            id: chainId !== null ? chainId : 0, // Fallback к 0, если id отсутствует
            state: isNaN(normalizedState) ? 0 : normalizedState // Всегда число, fallback к 0
          };
        });
        
        // Определяем общий state группы (число) - минимальный state из всех chains
        const groupState = chainsArray.length > 0 
          ? Math.min(...chainsArray.map(c => Number(c.state || 0)))
          : 0;
        
        return {
          ...group,
          chains: chainsArray,
          // Общий статус - число (0 = Active, 3 = Executed, 4 = Canceled, 5 = ReadyForExecution)
          state: groupState,
          // Общий executed - выполнен если выполнен во всех цепочках
          executed: chainsArray.length > 0 && chainsArray.every(c => c.executed),
          // Общий canceled - отменен если отменен в любой цепочке
          canceled: chainsArray.some(c => c.canceled)
        };
      });

      console.log(`[Proposals] Сгруппировано предложений: ${rawProposals.length}`);
      console.log(`[Proposals] Детали группировки:`, rawProposals);

      // Применяем валидацию предложений
      const validationResult = validateProposals(rawProposals);

      // Фильтруем только реальные предложения
      const realProposals = filterRealProposals(validationResult.validProposals);

      console.log(`[Proposals] Валидных предложений: ${validationResult.validCount}`);
      console.log(`[Proposals] Реальных предложений: ${realProposals.length}`);
      
      // Считаем активные только для статистики/логов (не выкидываем остальные из списка,
      // иначе фильтр "Все/Выполненные/Отмененные" в UI никогда не покажет эти статусы).
      const activeProposals = filterActiveProposals(realProposals);
      console.log(`[Proposals] Активных предложений: ${activeProposals.length}`);

      if (validationResult.errorCount > 0) {
        console.warn(`[Proposals] Найдено ${validationResult.errorCount} предложений с ошибками валидации`);
      }

      // В UI должны попадать ВСЕ реальные предложения; дальше их фильтрует statusFilter/searchQuery
      proposals.value = realProposals;
      filterProposals();
    } catch (error) {
      console.error('Ошибка загрузки предложений:', error);
      proposals.value = [];
    } finally {
      isLoading.value = false;
    }
  };

  const filterProposals = () => {
    if (!proposals.value || proposals.value.length === 0) {
      filteredProposals.value = [];
      return;
    }
    
    let filtered = [...proposals.value];

    if (statusFilter.value) {
      filtered = filtered.filter(proposal => {
        switch (statusFilter.value) {
          case 'active': return proposal.state === 0; // Pending
          case 'succeeded': return proposal.state === 1; // Succeeded
          case 'defeated': return proposal.state === 2; // Defeated
          case 'executed': return proposal.state === 3; // Executed
          case 'cancelled': return proposal.state === 4; // Canceled
          case 'ready': return proposal.state === 5; // ReadyForExecution
          default: return true;
        }
      });
    }

    if (searchQuery.value) {
      const query = searchQuery.value.toLowerCase();
      filtered = filtered.filter(proposal =>
        proposal.description.toLowerCase().includes(query) ||
        proposal.initiator.toLowerCase().includes(query) ||
        proposal.uniqueId.toLowerCase().includes(query)
      );
    }

    filteredProposals.value = filtered;
  };

  const voteOnProposal = async (proposalId, support) => {
    try {
      console.log('🚀 [VOTE] Начинаем голосование через DLE контракт:', { proposalId, support, dleAddress: dleAddress.value, userAddress: userAddress.value });
      isVoting.value = true;
      
      // Проверяем наличие MetaMask
      if (!window.ethereum) {
        throw new Error('MetaMask не найден. Пожалуйста, установите MetaMask.');
      }
      
      // Проверяем состояние предложения
      console.log('🔍 [DEBUG] Проверяем состояние предложения...');
      const proposal = proposals.value.find(p => p.id === proposalId);
      if (!proposal) {
        throw new Error('Предложение не найдено');
      }
      
      // КРИТИЧЕСКИ ВАЖНО: Если предложение мультичейн, используем voteOnMultichainProposal
      if (proposal.chains && proposal.chains.length > 1) {
        console.log('🌐 [VOTE] Обнаружено мультичейн предложение, используем voteOnMultichainProposal');
        return await voteOnMultichainProposal(proposal, support);
      }
      
      console.log('📊 [DEBUG] Данные предложения:', {
        id: proposal.id,
        state: proposal.state,
        deadline: proposal.deadline,
        forVotes: proposal.forVotes,
        againstVotes: proposal.againstVotes,
        executed: proposal.executed,
        canceled: proposal.canceled
      });
      
      // Проверяем, что предложение активно (Pending)
      if (proposal.state !== 0) {
        const statusText = getProposalStatusText(proposal.state);
        throw new Error(`Предложение не активно (статус: ${statusText}). Голосование возможно только для активных предложений.`);
      }
      
      // Проверяем, что предложение не выполнено и не отменено
      if (proposal.executed) {
        throw new Error('Предложение уже выполнено. Голосование невозможно.');
      }
      
      if (proposal.canceled) {
        throw new Error('Предложение отменено. Голосование невозможно.');
      }
      
      // Проверяем deadline
      const currentTime = Math.floor(Date.now() / 1000);
      if (proposal.deadline && currentTime > proposal.deadline) {
        throw new Error('Время голосования истекло. Голосование невозможно.');
      }
      
      // Проверяем баланс токенов пользователя
      console.log('💰 [DEBUG] Проверяем баланс токенов...');
      try {
        const balanceCheck = await checkTokenBalance(dleAddress.value, userAddress.value);
        console.log('💰 [DEBUG] Баланс токенов:', balanceCheck);
        
        if (!balanceCheck.hasTokens) {
          throw new Error('У вас нет токенов для голосования. Необходимо иметь токены DLE для участия в голосовании.');
        }
      } catch (balanceError) {
        console.warn('⚠️ [DEBUG] Ошибка проверки баланса (продолжаем):', balanceError.message);
        // Не останавливаем голосование, если не удалось проверить баланс
      }
      
      // Проверяем сеть кошелька
      console.log('🌐 [DEBUG] Проверяем сеть кошелька...');
      try {
        const chainId = await window.ethereum.request({ method: 'eth_chainId' });
        console.log('🌐 [DEBUG] Текущая сеть:', chainId);
        console.log('🌐 [DEBUG] Сеть предложения:', proposal.chainId);
        
        if (chainId !== proposal.chainId) {
          throw new Error(`Неправильная сеть! Текущая сеть: ${chainId}, требуется: ${proposal.chainId}`);
        }
      } catch (networkError) {
        console.warn('⚠️ [DEBUG] Ошибка проверки сети (продолжаем):', networkError.message);
      }
      
      // Голосуем через готовую функцию из utils/dle-contract.js
      console.log('🗳️ Отправляем голосование через смарт-контракт...');
      const result = await voteForProposal(dleAddress.value, proposalId, support);
      
      console.log('✅ Голосование успешно отправлено:', result.txHash);
      alert(`Голосование успешно отправлено! Хеш транзакции: ${result.txHash}`);
      
      // Принудительно обновляем данные предложения
      console.log('🔄 [VOTE] Обновляем данные после голосования...');
      await loadProposals();
      
      // Дополнительная задержка для подтверждения в блокчейне
      setTimeout(async () => {
        console.log('🔄 [VOTE] Повторное обновление через 3 секунды...');
        await loadProposals();
      }, 3000);
    } catch (error) {
      console.error('❌ Ошибка голосования:', error);
      
      // Улучшенная обработка ошибок
      let errorMessage = error.message;
      
      if (error.message.includes('execution reverted')) {
        if (error.data === '0xe7005635') {
          errorMessage = 'Голосование отклонено смарт-контрактом. Возможные причины:\n' +
            '• Вы уже голосовали за это предложение\n' +
            '• У вас нет токенов для голосования\n' +
            '• Предложение не активно\n' +
            '• Время голосования истекло';
        } else if (error.data === '0xc7567e07') {
          errorMessage = 'Голосование отклонено смарт-контрактом. Возможные причины:\n' +
            '• Вы уже голосовали за это предложение\n' +
            '• У вас нет токенов для голосования\n' +
            '• Предложение не активно\n' +
            '• Время голосования истекло\n' +
            '• Неправильная сеть для голосования';
        } else {
          errorMessage = `Транзакция отклонена смарт-контрактом (код: ${error.data}). Проверьте условия голосования.`;
        }
      } else if (error.message.includes('user rejected')) {
        errorMessage = 'Транзакция отклонена пользователем';
      } else if (error.message.includes('insufficient funds')) {
        errorMessage = 'Недостаточно средств для оплаты газа';
      }
      
      alert('Ошибка при голосовании: ' + errorMessage);
    } finally {
      isVoting.value = false;
    }
  };

  const executeProposal = async (proposalId) => {
    try {
      console.log('⚡ [EXECUTE] Исполняем предложение через DLE контракт:', { proposalId, dleAddress: dleAddress.value });
      isExecuting.value = true;
      
      // Проверяем состояние предложения перед выполнением
      console.log('🔍 [DEBUG] Проверяем состояние предложения для выполнения...');
      const proposal = proposals.value.find(p => p.id === proposalId);
      if (!proposal) {
        throw new Error('Предложение не найдено');
      }
      
      // КРИТИЧЕСКИ ВАЖНО: Если предложение мультичейн, используем executeMultichainProposal
      if (proposal.chains && proposal.chains.length > 1) {
        console.log('🌐 [EXECUTE] Обнаружено мультичейн предложение, используем executeMultichainProposal');
        return await executeMultichainProposal(proposal);
      }
      
      console.log('📊 [DEBUG] Данные предложения для выполнения:', {
        id: proposal.id,
        state: proposal.state,
        executed: proposal.executed,
        canceled: proposal.canceled,
        quorumReached: proposal.quorumReached
      });
      
      // Проверяем, что предложение можно выполнить
      if (proposal.executed) {
        throw new Error('Предложение уже выполнено. Повторное выполнение невозможно.');
      }
      
      if (proposal.canceled) {
        throw new Error('Предложение отменено. Выполнение невозможно.');
      }
      
      // Проверяем, что предложение готово к выполнению
      if (proposal.state !== 5) {
        const statusText = getProposalStatusText(proposal.state);
        throw new Error(`Предложение не готово к выполнению (статус: ${statusText}). Выполнение возможно только для предложений в статусе "Готово к выполнению".`);
      }
      
      // Исполняем предложение через готовую функцию из utils/dle-contract.js
      const result = await executeProposalUtil(dleAddress.value, proposalId);
      
      console.log('✅ Предложение успешно исполнено:', result.txHash);
      alert(`Предложение успешно исполнено! Хеш транзакции: ${result.txHash}`);
      
      // Принудительно обновляем состояние предложения в UI
      updateProposalState(proposalId, {
        executed: true,
        state: 1, // Выполнено
        canceled: false
      });
      
      await loadProposals(); // Перезагружаем данные
    } catch (error) {
      console.error('❌ Ошибка выполнения предложения:', error);
      
      // Улучшенная обработка ошибок
      let errorMessage = error.message;
      
      if (error.message.includes('execution reverted')) {
        errorMessage = 'Выполнение отклонено смарт-контрактом. Возможные причины:\n' +
          '• Предложение уже выполнено\n' +
          '• Предложение отменено\n' +
          '• Кворум не достигнут\n' +
          '• Предложение не активно';
      } else if (error.message.includes('user rejected')) {
        errorMessage = 'Транзакция отклонена пользователем';
      } else if (error.message.includes('insufficient funds')) {
        errorMessage = 'Недостаточно средств для оплаты газа';
      }
      
      alert('Ошибка при исполнении предложения: ' + errorMessage);
    } finally {
      isExecuting.value = false;
    }
  };

  const cancelProposal = async (proposalId, reason = 'Отменено пользователем') => {
    try {
      console.log('❌ [CANCEL] Отменяем предложение через DLE контракт:', { proposalId, reason, dleAddress: dleAddress.value });
      isCancelling.value = true;
      
      // Проверяем состояние предложения перед отменой
      console.log('🔍 [DEBUG] Проверяем состояние предложения для отмены...');
      const proposal = proposals.value.find(p => p.id === proposalId);
      if (!proposal) {
        throw new Error('Предложение не найдено');
      }
      
      console.log('📊 [DEBUG] Данные предложения для отмены:', {
        id: proposal.id,
        state: proposal.state,
        executed: proposal.executed,
        canceled: proposal.canceled,
        deadline: proposal.deadline,
        chains: proposal.chains?.length || 0
      });
      
      // Проверяем, что предложение можно отменить
      if (proposal.executed) {
        throw new Error('Предложение уже выполнено. Отмена невозможна.');
      }
      
      if (proposal.canceled) {
        throw new Error('Предложение уже отменено. Повторная отмена невозможна.');
      }
      
      // Проверяем, что пользователь является инициатором
      if (proposal.initiator?.toLowerCase() !== userAddress.value?.toLowerCase()) {
        throw new Error('Только инициатор предложения может его отменить.');
      }
      
      // Проверяем deadline (нужен запас 15 минут)
      const currentTime = Math.floor(Date.now() / 1000);
      if (proposal.deadline) {
        const timeRemaining = proposal.deadline - currentTime;
        if (timeRemaining <= 900) { // 15 минут запас
          throw new Error('Время для отмены истекло. Отмена возможна только за 15 минут до окончания голосования.');
        }
      }
      
      // КРИТИЧЕСКИ ВАЖНО: Мультичейн отмена - последовательно во всех активных сетях
      if (proposal.chains && proposal.chains.length > 0) {
        // Фильтруем только активные цепочки (можно отменить)
        const activeChains = proposal.chains.filter(chain => 
          canCancel(chain) && !chain.canceled && !chain.executed
        );
        
        if (activeChains.length === 0) {
          throw new Error('Не найдено ни одной активной цепочки для отмены');
        }
        
        console.log(`🚀 [MULTI-CANCEL] Начинаем отмену в ${activeChains.length} цепочках последовательно...`);
        
        const { switchToVotingNetwork } = await import('@/utils/dle-contract');
        const results = [];
        
        // КРИТИЧЕСКИ ВАЖНО: Отменяем ПОСЛЕДОВАТЕЛЬНО, а не параллельно!
        // MetaMask может работать только с одной сетью одновременно
        for (let index = 0; index < activeChains.length; index++) {
          const chain = activeChains[index];
          console.log(`📝 [${index + 1}/${activeChains.length}] Отмена в цепочке ${chain.networkName} (${chain.chainId})`);
          
          try {
            // Переключаемся на нужную сеть
            console.log(`🔄 [${index + 1}/${activeChains.length}] Переключаемся на сеть ${chain.chainId}...`);
            const switched = await switchToVotingNetwork(chain.chainId);
            if (!switched) {
              throw new Error(`Не удалось переключиться на сеть ${chain.networkName} (${chain.chainId})`);
            }
            
            // Задержка после переключения сети
            await new Promise(resolve => setTimeout(resolve, 1000));
            
            const contractAddress = chain.contractAddress || chain.address || dleAddress.value;
            // Используем ID предложения из конкретной цепочки (с fallback)
            let chainProposalId = chain.id !== undefined && chain.id !== null 
              ? Number(chain.id) 
              : (chain.proposalId !== undefined ? Number(chain.proposalId) : null);
            
            // Fallback к proposalId, если chain.id отсутствует
            if (chainProposalId === null || isNaN(chainProposalId)) {
              chainProposalId = proposalId !== undefined && proposalId !== null ? Number(proposalId) : null;
            }
            
            if (chainProposalId === null || isNaN(chainProposalId)) {
              throw new Error(`Неверный ID предложения для цепочки ${chain.networkName} (${chain.chainId}). chain.id=${chain.id}, proposalId=${proposalId}`);
            }
            
            chainProposalId = Number(chainProposalId); // Убеждаемся, что это число
            
            console.log(`🔍 [${index + 1}/${activeChains.length}] Используем ID предложения: ${chainProposalId} для отмены в цепочке ${chain.chainId}`);
            
            // Отменяем предложение
            console.log(`❌ [${index + 1}/${activeChains.length}] Отправляем отмену...`);
            const result = await cancelProposalUtil(contractAddress, chainProposalId, reason);
            
            console.log(`✅ [${index + 1}/${activeChains.length}] Предложение успешно отменено в ${chain.networkName}:`, result.txHash);
            
            // Задержка после подтверждения транзакции (для Base Sepolia больше)
            const delay = chain.chainId === 84532 ? 5000 : 3000;
            await new Promise(resolve => setTimeout(resolve, delay));
            
            results.push({
              chainId: chain.chainId,
              networkName: chain.networkName,
              success: true,
              txHash: result.txHash
            });
          } catch (error) {
            console.error(`❌ [${index + 1}/${activeChains.length}] Ошибка отмены в ${chain.networkName}:`, error);
            results.push({
              chainId: chain.chainId,
              networkName: chain.networkName,
              success: false,
              error: error.message
            });
            // Продолжаем отменять в других цепочках даже при ошибке
          }
        }
        
        // Подводим итоги
        const successful = results.filter(r => r.success);
        const failed = results.filter(r => !r.success);
        
        console.log(`📊 [MULTI-CANCEL] Отмена завершена: успешно в ${successful.length} из ${activeChains.length} цепочек`);
        
        if (successful.length > 0) {
          alert(`Предложение отменено в ${successful.length} из ${activeChains.length} цепочек!\n${failed.length > 0 ? `Ошибки в ${failed.length} цепочках.` : ''}`);
        } else {
          throw new Error('Не удалось отменить предложение ни в одной цепочке');
        }
      } else {
        // Одиночное предложение (без мультичейн)
        const result = await cancelProposalUtil(dleAddress.value, proposalId, reason);
        console.log('✅ Предложение успешно отменено:', result.txHash);
        alert(`Предложение успешно отменено! Хеш транзакции: ${result.txHash}`);
      }
      
      // Принудительно обновляем состояние предложения в UI
      updateProposalState(proposalId, {
        canceled: true,
        state: 4, // Canceled
        executed: false
      });
      
      await loadProposals(); // Перезагружаем данные
    } catch (error) {
      console.error('❌ Ошибка отмены предложения:', error);
      
      // Улучшенная обработка ошибок
      let errorMessage = error.message;
      
      if (error.message.includes('execution reverted')) {
        errorMessage = 'Отмена отклонена смарт-контрактом. Возможные причины:\n' +
          '• Предложение уже отменено\n' +
          '• Предложение уже выполнено\n' +
          '• Предложение не активно\n' +
          '• Недостаточно прав для отмены';
      } else if (error.message.includes('user rejected')) {
        errorMessage = 'Транзакция отклонена пользователем';
      } else if (error.message.includes('insufficient funds')) {
        errorMessage = 'Недостаточно средств для оплаты газа';
      }
      
      alert('Ошибка при отмене предложения: ' + errorMessage);
    } finally {
      isCancelling.value = false;
    }
  };

  const getProposalStatusClass = (state) => {
    switch (state) {
      case 0: return 'status-active';        // Pending
      case 1: return 'status-succeeded';      // Succeeded
      case 2: return 'status-defeated';       // Defeated
      case 3: return 'status-executed';       // Executed
      case 4: return 'status-cancelled';     // Canceled
      case 5: return 'status-ready';          // ReadyForExecution
      default: return 'status-active';
    }
  };

  const getProposalStatusText = (state) => {
    switch (state) {
      case 0: return 'Активное';
      case 1: return 'Успешное';
      case 2: return 'Отклоненное';
      case 3: return 'Выполнено';
      case 4: return 'Отменено';
      case 5: return 'Готово к выполнению';
      default: return 'Неизвестно';
    }
  };

  const getQuorumPercentage = (proposal) => {
    // Получаем реальные данные из предложения
    const forVotes = Number(proposal.forVotes || 0);
    const againstVotes = Number(proposal.againstVotes || 0);
    const totalVotes = forVotes + againstVotes;
    
    // Используем реальный totalSupply из предложения или fallback
    const totalSupply = Number(proposal.totalSupply || 3e+24); // Fallback к 3M DLE
    
    console.log(`📊 [QUORUM] Предложение ${proposal.id}:`, {
      forVotes: forVotes,
      againstVotes: againstVotes,
      totalVotes: totalVotes,
      totalSupply: totalSupply,
      forVotesFormatted: `${(forVotes / 1e+18).toFixed(2)} DLE`,
      againstVotesFormatted: `${(againstVotes / 1e+18).toFixed(2)} DLE`,
      totalVotesFormatted: `${(totalVotes / 1e+18).toFixed(2)} DLE`,
      totalSupplyFormatted: `${(totalSupply / 1e+18).toFixed(2)} DLE`
    });
    
    const percentage = totalSupply > 0 ? (totalVotes / totalSupply) * 100 : 0;
    return percentage.toFixed(2);
  };

  const getRequiredQuorumPercentage = (proposal) => {
    // Получаем требуемый кворум из предложения
    const requiredQuorum = Number(proposal.quorumRequired || 0);
    
    // Используем реальный totalSupply из предложения или fallback
    const totalSupply = Number(proposal.totalSupply || 3e+24); // Fallback к 3M DLE
    
    console.log(`📊 [REQUIRED QUORUM] Предложение ${proposal.id}:`, {
      requiredQuorum: requiredQuorum,
      totalSupply: totalSupply,
      requiredQuorumFormatted: `${(requiredQuorum / 1e+18).toFixed(2)} DLE`,
      totalSupplyFormatted: `${(totalSupply / 1e+18).toFixed(2)} DLE`
    });
    
    const percentage = totalSupply > 0 ? (requiredQuorum / totalSupply) * 100 : 0;
    return percentage.toFixed(2);
  };

  const canVote = (proposal) => {
    // Для мультичейн предложений используем canVoteMultichain
    if (proposal.chains && proposal.chains.length > 1) {
      return canVoteMultichain(proposal);
    }
    // Унифицируем state - всегда число
    const state = typeof proposal.state === 'string' 
      ? (proposal.state === 'active' ? 0 : NaN) 
      : Number(proposal.state);
    return state === 0; // Pending - только активные предложения
  };

  const canExecute = (proposal) => {
    // Унифицируем state - всегда число
    const state = typeof proposal.state === 'string' 
      ? (proposal.state === 'active' ? 0 : NaN) 
      : Number(proposal.state);
    return state === 5; // ReadyForExecution - готово к выполнению
  };

  const canCancel = (proposal) => {
    // Унифицируем state - всегда число
    const state = typeof proposal.state === 'string' 
      ? (proposal.state === 'active' ? 0 : NaN) 
      : Number(proposal.state);
    // Можно отменить только активные предложения (Pending)
    return state === 0 && 
           !proposal.executed && 
           !proposal.canceled;
  };

  // Принудительное обновление состояния предложения в UI
  const updateProposalState = (proposalId, updates) => {
    const proposal = proposals.value.find(p => p.id === proposalId);
    if (proposal) {
      Object.assign(proposal, updates);
      console.log(`🔄 [UI] Обновлено состояние предложения ${proposalId}:`, updates);

      // Принудительно обновляем фильтрацию
      filterProposals();
    }
  };

  // Мульти-чейн функции
  const voteOnMultichainProposal = async (proposal, support) => {
    try {
      isVoting.value = true;

      // Фильтруем только активные цепочки (state === 0 или 'active', не выполнены, не отменены)
      const activeChains = proposal.chains.filter(chain => canVote(chain));
      
      if (activeChains.length === 0) {
        throw new Error('Не найдено ни одной активной цепочки для голосования');
      }

      console.log(`🌐 [MULTI-VOTE] Начинаем голосование в ${activeChains.length} цепочках последовательно...`);

      const { switchToVotingNetwork } = await import('@/utils/dle-contract');
      const results = [];

      // КРИТИЧЕСКИ ВАЖНО: Голосуем ПОСЛЕДОВАТЕЛЬНО, а не параллельно!
      // MetaMask может работать только с одной сетью одновременно
      for (let index = 0; index < activeChains.length; index++) {
        const chain = activeChains[index];
        console.log(`📝 [${index + 1}/${activeChains.length}] Голосование в цепочке ${chain.networkName} (${chain.chainId})`);
        
        try {
          // Переключаемся на нужную сеть
          console.log(`🔄 [${index + 1}/${activeChains.length}] Переключаемся на сеть ${chain.chainId}...`);
          const switched = await switchToVotingNetwork(chain.chainId);
          if (!switched) {
            throw new Error(`Не удалось переключиться на сеть ${chain.networkName} (${chain.chainId})`);
          }
          
          // Задержка после переключения сети
          await new Promise(resolve => setTimeout(resolve, 1000));
          
          const contractAddress = chain.contractAddress || chain.address || dleAddress.value;
          // Используем ID предложения из конкретной цепочки (с fallback)
          let chainProposalId = chain.id !== undefined && chain.id !== null 
            ? Number(chain.id) 
            : (chain.proposalId !== undefined ? Number(chain.proposalId) : null);
          
          // Fallback к proposal.id, если chain.id отсутствует
          if (chainProposalId === null || isNaN(chainProposalId)) {
            chainProposalId = proposal.id !== undefined && proposal.id !== null ? Number(proposal.id) : null;
          }
          
          if (chainProposalId === null || isNaN(chainProposalId)) {
            throw new Error(`Неверный ID предложения для цепочки ${chain.networkName} (${chain.chainId}). chain.id=${chain.id}, proposal.id=${proposal.id}`);
          }
          
          chainProposalId = Number(chainProposalId); // Убеждаемся, что это число
          
          console.log(`🔍 [${index + 1}/${activeChains.length}] Используем ID предложения: ${chainProposalId} для голосования в цепочке ${chain.chainId}`);
          
          // Проверяем баланс токенов в каждой сети (балансы могут отличаться в разных сетях)
          console.log(`💰 [${index + 1}/${activeChains.length}] Проверяем баланс токенов в ${chain.networkName}...`);
          try {
            const balanceCheck = await checkTokenBalance(contractAddress, userAddress.value);
            console.log(`💰 [${index + 1}/${activeChains.length}] Баланс токенов в ${chain.networkName}:`, balanceCheck);
            
            if (!balanceCheck.hasTokens) {
              console.warn(`⚠️ [${index + 1}/${activeChains.length}] Нет токенов в ${chain.networkName}, пропускаем голосование в этой сети`);
              results.push({
                chainId: chain.chainId,
                networkName: chain.networkName,
                success: false,
                error: `Нет токенов DLE в сети ${chain.networkName} для голосования`
              });
              // Продолжаем с следующей сетью
              continue;
            }
          } catch (balanceError) {
            console.warn(`⚠️ [${index + 1}/${activeChains.length}] Ошибка проверки баланса в ${chain.networkName} (продолжаем):`, balanceError.message);
            // При ошибке проверки баланса продолжаем попытку голосования
            // Контракт сам проверит баланс и вернет ошибку, если токенов нет
          }
          
          // Голосуем
          console.log(`🗳️ [${index + 1}/${activeChains.length}] Отправляем голосование для proposalId=${chainProposalId} в ${chain.networkName}...`);
          const result = await voteForProposal(contractAddress, chainProposalId, support);
          
          console.log(`✅ [${index + 1}/${activeChains.length}] Голосование успешно в ${chain.networkName}:`, result.txHash);
          
          // Задержка после подтверждения транзакции (для Base Sepolia больше)
          const delay = chain.chainId === 84532 ? 5000 : 3000;
          await new Promise(resolve => setTimeout(resolve, delay));
          
          results.push({
            chainId: chain.chainId,
            networkName: chain.networkName,
            success: true,
            txHash: result.txHash
          });
        } catch (error) {
          console.error(`❌ [${index + 1}/${activeChains.length}] Ошибка голосования в ${chain.networkName}:`, error);
          results.push({
            chainId: chain.chainId,
            networkName: chain.networkName,
            success: false,
            error: error.message
          });
          // Продолжаем голосовать в других цепочках даже при ошибке
        }
      }

      // Подводим итоги
      const successful = results.filter(r => r.success);
      const failed = results.filter(r => !r.success);
      
      console.log(`📊 [MULTI-VOTE] Голосование завершено: успешно в ${successful.length} из ${activeChains.length} цепочек`);

      // Перезагружаем предложения
      await loadProposals();

    } catch (error) {
      console.error('[MULTI-VOTE] Критическая ошибка:', error);
      throw error;
    } finally {
      isVoting.value = false;
    }
  };

  const executeMultichainProposal = async (proposal) => {
    try {
      isExecuting.value = true;

      // Фильтруем только готовые к выполнению цепочки
      const readyChains = proposal.chains.filter(chain => canExecute(chain));
      
      if (readyChains.length === 0) {
        throw new Error('Нет цепочек, готовых к выполнению');
      }

      console.log(`🚀 [MULTI-EXECUTE] Начинаем исполнение в ${readyChains.length} цепочках последовательно...`);

      const { switchToVotingNetwork } = await import('@/utils/dle-contract');
      const results = [];

      // КРИТИЧЕСКИ ВАЖНО: Исполняем ПОСЛЕДОВАТЕЛЬНО, а не параллельно!
      // MetaMask может работать только с одной сетью одновременно
      for (let index = 0; index < readyChains.length; index++) {
        const chain = readyChains[index];
        console.log(`📝 [${index + 1}/${readyChains.length}] Выполнение в цепочке ${chain.networkName} (${chain.chainId})`);
        
        try {
          // Переключаемся на нужную сеть
          console.log(`🔄 [${index + 1}/${readyChains.length}] Переключаемся на сеть ${chain.chainId}...`);
          const switched = await switchToVotingNetwork(chain.chainId);
          if (!switched) {
            throw new Error(`Не удалось переключиться на сеть ${chain.networkName} (${chain.chainId})`);
          }
          
          // Задержка после переключения сети
          await new Promise(resolve => setTimeout(resolve, 1000));
          
          const contractAddress = chain.contractAddress || chain.address || dleAddress.value;
          // Используем ID предложения из конкретной цепочки (с fallback)
          let chainProposalId = chain.id !== undefined && chain.id !== null 
            ? Number(chain.id) 
            : (chain.proposalId !== undefined ? Number(chain.proposalId) : null);
          
          // Fallback к proposal.id, если chain.id отсутствует
          if (chainProposalId === null || isNaN(chainProposalId)) {
            chainProposalId = proposal.id !== undefined && proposal.id !== null ? Number(proposal.id) : null;
          }
          
          if (chainProposalId === null || isNaN(chainProposalId)) {
            throw new Error(`Неверный ID предложения для цепочки ${chain.networkName} (${chain.chainId}). chain.id=${chain.id}, proposal.id=${proposal.id}`);
          }
          
          chainProposalId = Number(chainProposalId); // Убеждаемся, что это число
          
          console.log(`🔍 [${index + 1}/${readyChains.length}] Используем ID предложения: ${chainProposalId} для выполнения в цепочке ${chain.chainId}`);
          
          // Выполняем предложение
          console.log(`⚡ [${index + 1}/${readyChains.length}] Отправляем выполнение...`);
          const result = await executeProposalUtil(contractAddress, chainProposalId);
          
          console.log(`✅ [${index + 1}/${readyChains.length}] Предложение успешно выполнено в ${chain.networkName}:`, result.txHash);
          
          // Задержка после подтверждения транзакции (для Base Sepolia больше)
          const delay = chain.chainId === 84532 ? 5000 : 3000;
          await new Promise(resolve => setTimeout(resolve, delay));
          
          results.push({
            chainId: chain.chainId,
            networkName: chain.networkName,
            success: true,
            txHash: result.txHash
          });
        } catch (error) {
          console.error(`❌ [${index + 1}/${readyChains.length}] Ошибка выполнения в ${chain.networkName}:`, error);
          results.push({
            chainId: chain.chainId,
            networkName: chain.networkName,
            success: false,
            error: error.message
          });
          // Продолжаем выполнять в других цепочках даже при ошибке
        }
      }

      // Подводим итоги
      const successful = results.filter(r => r.success);
      const failed = results.filter(r => !r.success);
      
      console.log(`📊 [MULTI-EXECUTE] Выполнение завершено: успешно в ${successful.length} из ${readyChains.length} цепочек`);

      // Перезагружаем предложения
      await loadProposals();

    } catch (error) {
      console.error('[MULTI-EXECUTE] Критическая ошибка:', error);
      throw error;
    } finally {
      isExecuting.value = false;
    }
  };

  const canVoteMultichain = (proposal) => {
    // Можно голосовать если есть хотя бы одна активная цепочка
    return proposal.chains.some(chain => canVote(chain));
  };

  const canExecuteMultichain = (proposal) => {
    // Можно исполнить только если кворум достигнут во ВСЕХ цепочках
    return proposal.chains.every(chain => canExecute(chain));
  };

  const getChainStatusClass = (chain) => {
    if (chain.executed) return 'executed';
    if (chain.state === 'active') return 'active';
    if (chain.deadline && chain.deadline < Date.now() / 1000) return 'expired';
    return 'inactive';
  };

  const getChainStatusText = (chain) => {
    if (chain.executed) return 'Исполнено';
    if (chain.state === 'active') return 'Активно';
    if (chain.deadline && chain.deadline < Date.now() / 1000) return 'Истекло';
    return 'Неактивно';
  };

  return {
    // ... существующие поля
    proposals,
    filteredProposals,
    isLoading,
    isVoting,
    isExecuting,
    isCancelling,
    statusFilter,
    searchQuery,
    loadProposals,
    filterProposals,
    voteOnProposal,
    voteOnMultichainProposal,
    executeProposal,
    executeMultichainProposal,
    cancelProposal,
    getProposalStatusClass,
    getProposalStatusText,
    getQuorumPercentage,
    getRequiredQuorumPercentage,
    canVote,
    canVoteMultichain,
    canExecute,
    canExecuteMultichain,
    canCancel,
    getChainStatusClass,
    getChainStatusText,
    updateProposalState,
    // Валидация
    validationStats,
    isValidating
  };
}