from rest_framework import generics, status, viewsets
from users.models import BlockchainUserInfo
from rest_framework_simplejwt.tokens import AccessToken
from jwt.exceptions import InvalidTokenError
from rest_framework.permissions import IsAuthenticated
from rest_framework_simplejwt.authentication import JWTAuthentication
from institutional.models import CorporateUser, CorporateMember

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.http import JsonResponse, HttpResponse, HttpResponseRedirect, JsonResponse, HttpResponseBadRequest
from django.contrib.auth.models import User
from users.models import UserCredentialsForBlockchain
from .serializers import UserCredentialsForBlockchainSerializer, BlockchainUserInfoSerializer, UserSerializer
from Blockchain2.block_user_info import *
from Blockchain2.web3User import *
from django.contrib.auth import get_user_model
from lpp.certificate.createCertificate import certificateGenrate
from auto_email.views import sendmail


User = get_user_model()

class BlockchainUserFilterView(generics.ListCreateAPIView):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    serializer_class = BlockchainUserInfoSerializer

    def list(self, request):
        queryset = BlockchainUserInfo.objects.all()

        date_param = request.query_params.get('date')
        service_param = request.query_params.get('service')
        user_param = request.query_params.get('user')


        if CorporateMember.objects.filter(user=self.request.user).exists():
            corporate_member = CorporateMember.objects.get(user=self.request.user)
            corporate_users = CorporateUser.objects.filter(this_user_admin_id=corporate_member.corporate_member_uuid)
            corporate_user_ids = corporate_users.values_list('user_id', flat=True)
            queryset = queryset.filter(user_id__in=corporate_user_ids)

            if service_param:
                serialized_data = self.get_serializer(queryset, many=True).data
                data_dict = {}
                for entry in serialized_data:
                    service = entry['service'].replace(" ", "")

                    if service not in data_dict:
                        data_dict[service] = {'transactions': [], 'total_gas_fee': 0}

                    gas_fee = entry['gas_fee']
                    data_dict[service]['total_gas_fee'] += gas_fee
                    data_dict[service]['transactions'].append(entry)

                return Response(data_dict)

            if user_param:
                serialized_data = self.get_serializer(queryset, many=True).data
                data_dict = {}
                for entry in serialized_data:
                    user_id = entry['user']
                    username = User.objects.get(id=user_id).username

                    if username not in data_dict:
                        data_dict[username] = {'transactions': [], 'total_gas_fee': 0}

                    gas_fee = entry['gas_fee']
                    data_dict[username]['total_gas_fee'] += gas_fee
                    data_dict[username]['transactions'].append(entry)

                return JsonResponse(data_dict)

            if date_param:
                queryset = queryset.order_by('-date_at')
                serialized_data = self.get_serializer(queryset, many=True).data
                print("madiha test", serialized_data, queryset)
                sorted_data = []
                total_gas_fee = 0

                for entry in serialized_data:
                    user_id = entry['user']
                    if user_id:
                        user = User.objects.get(id=user_id)
                        entry['uploaded_by'] = user.username
                    else:
                        entry['uploaded_by'] = None
                    sorted_data.append(entry)
                    total_gas_fee += entry['gas_fee']

                response_data = {
                    'data': sorted_data,
                    'total_gas_fee': total_gas_fee,
                }
                return JsonResponse(response_data)

        else:
            if date_param:
                queryset = queryset.order_by('-date_at')
                serialized_data = self.get_serializer(queryset, many=True).data
                total_gas_fee = sum(entry['gas_fee'] for entry in serialized_data)

                response_data = {
                    'data': serialized_data,
                    'total_gas_fee': total_gas_fee,
                }

                return Response(response_data)

            if service_param:
                serialized_data = self.get_serializer(queryset, many=True).data
                data_dict = {}

                for entry in serialized_data:
                    service = entry['service'].replace(" ", "")

                    if service not in data_dict:
                        data_dict[service] = {'transactions': [], 'total_gas_fee': 0}

                    gas_fee = entry['gas_fee']
                    data_dict[service]['total_gas_fee'] += gas_fee
                    data_dict[service]['transactions'].append(entry)

                return Response(data_dict)

        return Response({'detail': 'Invalid query parameters provided.'})


class GetUserPublicKeyView(APIView):
    def get(self, request):
        try:
            credentials = UserCredentialsForBlockchain.objects.get(user=request.user)
            serializer = UserCredentialsForBlockchainSerializer(credentials)
            authentication_classes = [JWTAuthentication]
            permission_classes = [IsAuthenticated]

            return Response(serializer.data, status=status.HTTP_200_OK)
        except UserCredentialsForBlockchain.DoesNotExist:
            return Response({'error': 'Blockchain credentials not found for the user'}, status=status.HTTP_400_BAD_REQUEST)


class GetUserTypeView(APIView):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]

    def get(self, request):
        popup_param = request.query_params.get('popup')
        popup= False
        if popup_param:
            popup = True

        try:
            u_id = request.user.id if request.user.id else 1499
            user = User.objects.get(id=u_id)
            user_data = UserSerializer(user).data
            if CorporateMember.objects.filter(user=request.user).exists():
                corporate_member = CorporateMember.objects.get(user=request.user)
                data = {
                        'is_corporate': True,
                        'user': user_data,
                        'popup':popup
                }
                return Response(data, status=status.HTTP_200_OK)
            else:
                data = {
                    'is_corporate': False,
                    'user': user_data,
                    'popup':popup

                }
                return Response(data, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)


def update_blockchain_info(request):
    try:
        gas= 12
        user_infos = user_info(tx_hash="0x556facdba65b25dfb366d67f2798bf626153722d1c2ef7b2f58a42640a01dfa9", service="Narration", gas_fee=str(gas),script_name = "Narration project")
        addition_result = user_infos.update_info(request)
        # certificatepath = certificateGenrate(request.user.username, "script conversion", "0x556facdba65b25dfb366d67f2798bf626153722d1c2ef7b2f58a42640a01dfa9")
        # certificatepath = certificateGenrate(request.user.username, "script conversion", hash)
        # hash = hash_decrypation(hash)
        # to_email = [request.user.email]
        # email_code = 'BL1'
        # key_value = {
        #     "service": "script conversion",
        #     "hash": "hash",
        #     "public key": "",
        #     "private key": "",
        #     "Transaction Hash": "0x556facdba65b25dfb366d67f2798bf626153722d1c2ef7b2f58a42640a01dfa9"
        # }
        # sendmail(to_email=to_email, email_code=email_code, key_value=key_value, filePath=certificatepath)
        return HttpResponse(f"info=>sucessfully updated for {request.user}")
    except Exception as e:
        print("Error:",e)
        return HttpResponse(f"info=>error{e}")

class GetUserTx_HashReciptView(APIView):
    def get(self, request):
        tx = request.query_params.get('tx_hash')
        popup_param = request.query_params.get('popup')

        try:
            # authentication_classes = [JWTAuthentication]
            # permission_classes = [IsAuthenticated]
            if popup_param:
                popup = True,
            else:
                popup = False,

            response = get_transction_recipt('0xb0df1560040b294fe5b35ca136c98ff5f55e71b4f1593c27a8f43ac597079e9f')
            txn_fee = response.effectiveGasPrice*response.gasUsed/1000000000000000000
            data ={
                'transactionHash': response.transactionHash.hex(),
                'status':response.status,
                'to':response.to,
                'blockNumber':response.blockNumber,
                'popup':popup,
                'txn_fee':txn_fee,
                'gas_used':response.gasUsed,
                'from':'0x54d03ec0c462e9a01f77579c090cde0fc2617817',
                'timestamp': 1713239236,

            }
            return Response(data, status=status.HTTP_200_OK)
        except Exception as e :
            return Response({'error': f'tx details not found{e}'}, status=status.HTTP_400_BAD_REQUEST)