import hmac
import hashlib
import time
import json
from decimal import Decimal
import logging

import requests
from django.conf import settings
from django.db import transaction as db_transaction
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework import status

from .models import Transaction

logger = logging.getLogger(__name__)

class VerifyPaymentView(APIView):
    """
    ইউজারের দেওয়া TXID এবং Amount Binance API দিয়ে ভেরিফাই করে
    Mock Verification完全没有 - শুধু Real Binance API
    """
    permission_classes = [IsAuthenticated]
    
    def post(self, request):
        # ---------- ডাটা এক্সট্র্যাক্ট ----------
        txid = request.data.get('txid')
        amount = request.data.get('amount')
        
        logger.info(f"VerifyPayment - User: {request.user.email}, TXID: {txid}, Amount: {amount}")
        
        # ---------- ভ্যালিডেশন ----------
        if not txid or not amount:
            return Response(
                {'error': 'TXID and amount are required'}, 
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # TXID আগে ব্যবহার হয়েছে কিনা চেক
        if Transaction.objects.filter(txid=txid).exists():
            return Response(
                {'error': 'This TXID has already been used'}, 
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # ---------- Binance API দিয়ে ভেরিফিকেশন (শুধু Real) ----------
        verification_result = self.verify_with_binance(txid, amount)
        
        if not verification_result['success']:
            return Response(
                {'error': verification_result.get('error', 'Verification failed')}, 
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # ---------- ডাটাবেজ আপডেট ----------
        try:
            with db_transaction.atomic():
                # ট্রানজেকশন সেভ
                transaction = Transaction.objects.create(
                    user=request.user,
                    txid=txid,
                    amount=amount,
                    status='COMPLETED'
                )
                
                # ইউজারের প্রোফাইলে ব্যালেন্স আপডেট
                profile = request.user.profile
                profile.balance += Decimal(str(amount))
                profile.save()
            
            # সাকসেস রেসপন্স
            return Response({
                'success': True,
                'message': 'Payment verified successfully',
                'new_balance': float(profile.balance),
                'transaction': {
                    'id': str(transaction.id),
                    'txid': transaction.txid,
                    'amount': float(transaction.amount),
                    'status': transaction.status,
                    'date': transaction.created_at.strftime('%Y-%m-%d %H:%M:%S')
                }
            })
            
        except Exception as e:
            logger.error(f"Database error: {str(e)}")
            return Response(
                {'error': 'Failed to update balance. Please contact support.'}, 
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    def verify_with_binance(self, txid, amount):
        """
        Binance API কল করে TXID ভেরিফাই করে
        Mock Verification নেই - সবসময় Real API কল
        """
        try:
            # ---------- API Key চেক ----------
            if not settings.BINANCE_API_KEY or not settings.BINANCE_SECRET_KEY:
                logger.error("Binance API keys not configured")
                return {
                    'success': False, 
                    'error': 'Payment verification service not configured'
                }
            
            # ---------- সিগনেচার জেনারেট ----------
            timestamp = int(time.time() * 1000)
            query_string = f"coin=USDT&timestamp={timestamp}"
            
            signature = hmac.new(
                settings.BINANCE_SECRET_KEY.encode('utf-8'),
                query_string.encode('utf-8'),
                hashlib.sha256
            ).hexdigest()
            
            # ---------- API কল ----------
            headers = {'X-MBX-APIKEY': settings.BINANCE_API_KEY}
            params = {
                'coin': 'USDT',
                'timestamp': timestamp,
                'signature': signature
            }
            
            logger.info(f"Calling Binance API with params: {params}")
            
            response = requests.get(
                f"{settings.BINANCE_BASE_URL}/sapi/v1/capital/deposit/hisrec",
                params=params,
                headers=headers,
                timeout=10
            )
            
            # ---------- রেসপন্স হ্যান্ডলিং ----------
            if response.status_code != 200:
                logger.error(f"Binance API error: {response.text}")
                
                # ইউজার-ফ্রেন্ডলি এরর মেসেজ
                if response.status_code == 401:
                    return {
                        'success': False,
                        'error': 'API authentication failed'
                    }
                elif response.status_code == 429:
                    return {
                        'success': False,
                        'error': 'Too many requests. Please try again later.'
                    }
                else:
                    return {
                        'success': False,
                        'error': 'Payment verification service temporarily unavailable'
                    }
            
            data = response.json()
            logger.info(f"Binance API response received: {len(data)} transactions")
            
            # ---------- TXID খুঁজে দেখা ----------
            for item in data:
                if item.get('txId') == txid:
                    # স্ট্যাটাস চেক (1 = সফল)
                    status_code = item.get('status')
                    if status_code != 1:
                        status_map = {
                            0: 'Pending',
                            6: 'Credited but cannot withdraw'
                        }
                        return {
                            'success': False,
                            'error': f'Transaction status: {status_map.get(status_code, "Unknown")}'
                        }
                    
                    # অ্যামাউন্ট চেক
                    tx_amount = float(item.get('amount', 0))
                    if abs(tx_amount - float(amount)) > 0.01:  # 0.01 USDT tolerance
                        return {
                            'success': False,
                            'error': f'Amount mismatch. Expected: {amount}, Found: {tx_amount}'
                        }
                    
                    # ওয়ালেট অ্যাড্রেস চেক (অপশনাল)
                    if item.get('address') != settings.USDT_WALLET_ADDRESS:
                        logger.warning(f"Address mismatch: {item.get('address')} != {settings.USDT_WALLET_ADDRESS}")
                        # এই চেক না করলেও চলে, কিন্তু করলে বেশি নিরাপদ
                    
                    # সব ঠিক আছে
                    logger.info(f"Transaction verified successfully: {txid}")
                    return {'success': True}
            
            # TXID পাওয়া যায়নি
            logger.warning(f"Transaction ID not found in Binance history: {txid}")
            return {
                'success': False,
                'error': 'Transaction ID not found in Binance. Please check and try again.'
            }
            
        except requests.exceptions.Timeout:
            logger.error("Binance API timeout")
            return {
                'success': False,
                'error': 'Verification service timeout. Please try again.'
            }
        except requests.exceptions.ConnectionError:
            logger.error("Binance API connection error")
            return {
                'success': False,
                'error': 'Network error. Please check your connection.'
            }
        except Exception as e:
            logger.error(f"Verification error: {str(e)}")
            return {
                'success': False,
                'error': 'Verification failed. Please try again later.'
            }


class MyTransactionsView(APIView):
    """
    ইউজারের নিজের ট্রানজেকশন দেখায়
    """
    permission_classes = [IsAuthenticated]
    
    def get(self, request):
        try:
            transactions = Transaction.objects.filter(
                user=request.user
            ).order_by('-created_at')[:50]
            
            data = []
            for t in transactions:
                data.append({
                    'id': str(t.id),
                    'txid': t.txid[:20] + '...' if len(t.txid) > 20 else t.txid,
                    'amount': float(t.amount),
                    'status': t.status,
                    'date': t.created_at.strftime('%Y-%m-%d %H:%M')
                })
            
            return Response({
                'success': True,
                'transactions': data,
                'total': transactions.count()
            })
            
        except Exception as e:
            logger.error(f"Error fetching transactions: {str(e)}")
            return Response(
                {'error': 'Failed to fetch transactions'}, 
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class BalanceView(APIView):
    """
    ইউজারের বর্তমান ব্যালেন্স দেখায়
    """
    permission_classes = [IsAuthenticated]
    
    def get(self, request):
        try:
            balance = float(request.user.profile.balance)
            
            return Response({
                'success': True,
                'balance': balance,
                'currency': 'USDT'
            })
            
        except Exception as e:
            logger.error(f"Error fetching balance: {str(e)}")
            return Response(
                {'error': 'Failed to fetch balance'}, 
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class AllTransactionsView(APIView):
    """
    অ্যাডমিনের জন্য সব ট্রানজেকশন দেখায়
    """
    permission_classes = [IsAuthenticated]
    
    def get(self, request):
        # অ্যাডমিন চেক
        if not request.user.is_superuser:
            return Response(
                {'error': 'Admin access required'}, 
                status=status.HTTP_403_FORBIDDEN
            )
        
        try:
            transactions = Transaction.objects.all().select_related('user')[:100]
            
            data = []
            for t in transactions:
                data.append({
                    'id': str(t.id),
                    'user': t.user.email,
                    'user_name': t.user.name,
                    'txid': t.txid,
                    'amount': float(t.amount),
                    'status': t.status,
                    'date': t.created_at.strftime('%Y-%m-%d %H:%M')
                })
            
            return Response({
                'success': True,
                'transactions': data,
                'total': transactions.count()
            })
            
        except Exception as e:
            logger.error(f"Error fetching all transactions: {str(e)}")
            return Response(
                {'error': 'Failed to fetch transactions'}, 
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class GetUSDTAddressView(APIView):
    """
    ইউজারকে USDT ওয়ালেট অ্যাড্রেস দেখায়
    """
    permission_classes = [IsAuthenticated]
    
    def get(self, request):
        try:
            return Response({
                'success': True,
                'address': settings.USDT_WALLET_ADDRESS,
                'network': settings.USDT_WALLET_NETWORK,
                'note': f'Send only USDT via {settings.USDT_WALLET_NETWORK} network to this address'
            })
            
        except Exception as e:
            logger.error(f"Error fetching wallet address: {str(e)}")
            return Response(
                {'error': 'Failed to fetch wallet address'}, 
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )