import json
import random
from django.conf import settings
from rest_framework import status
from django.http import JsonResponse
from rest_framework.response import Response

from sub_categories.models import Sub_Categories
from .models import ContractorProfile, ContractorWork, Users
from .auth import generate_access_token
from rest_framework.views import APIView
from rest_framework.decorators import api_view
from django.db.models import Q
from utils.helpers import verify_token, send_otp_to_phone
from django.db import transaction

from .serializers import ContractorProfileSerializer

class SendOtp(APIView):

    def post(self, request):

        try:

            mobile = request.data.get("mobile")
            action = request.data.get("type")  # signup/login

            if not mobile:
                return Response({"message": "Mobile number is required", 'status': status.HTTP_200_OK})

            if action not in ["signup", "login"]:
                return Response({"message": "Invalid request type", "status" : status.HTTP_400_BAD_REQUEST})

            user_exists = Users.objects.filter(
                mobile=mobile,
                user_type=3
            ).exists()

            # LOGIN
            if action == "login":

                try:
                    user = Users.objects.get(mobile=mobile, user_type=3)
                except Users.DoesNotExist:
                    return Response({"message": "Contractor account not found", 'status' : status.HTTP_404_NOT_FOUND})

            # ✅ check contractor profile verification
                if hasattr(user, "contractor_profile"):
                    if not user.contractor_profile.is_verified:
                        return Response(
                            {
                                "message": "Your account is not verified yet",
                                "is_verified": False,
                                "status" : status.HTTP_403_FORBIDDEN
                            }
                        )
                else:
                    return Response({"message": "Contractor profile not found", 'status' : status.HTTP_404_NOT_FOUND})
            
            
            
            # SIGNUP

            elif action == "signup":

                if user_exists:
                    return Response(
                        {"message": "Mobile number already registered", "status" : status.HTTP_400_BAD_REQUEST})

            otp = "1234"

            result = send_otp_to_phone(
                mobile,
                otp
            )

            if result:

                request.session["mobile"] = mobile
                request.session["otp"] = otp
                request.session["action"] = action

                return Response(
                    {
                        "message": "OTP sent successfully",
                        "status": status.HTTP_200_OK
                    }
                )

            return Response(
                {
                    "message": "Failed to send OTP",
                    "status" : status.HTTP_400_BAD_REQUEST
                },
                
            )

        except Exception as e:
            print(e)
            return Response(
                {"message": str(e),  'status' : status.HTTP_500_INTERNAL_SERVER_ERROR},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class VerifyOtp(APIView):

    def post(self, request):

        try:

            otp = request.data.get("otp")
            fcm_token = request.data.get("fcm_token", "")

            session_otp = request.session.get("otp")
            mobile = request.session.get("mobile")
            action = request.session.get("action")

            if not session_otp or not mobile:
                return Response(
                    {
                        "message": "OTP session expired",
                        "status": status.HTTP_400_BAD_REQUEST
                    }
                )

            if str(otp) != str(session_otp):
                return Response(
                    {
                        "message": "Invalid OTP",
                        "status": status.HTTP_400_BAD_REQUEST
                    }
                )

            # =====================================
            # LOGIN
            # =====================================
            if action == "login":

                try:

                    user = Users.objects.get(
                        mobile=mobile,
                        user_type=3
                    )

                    user.fcm_token = fcm_token
                    user.save()

                    access_token = generate_access_token(user)

                    return Response(
                        {
                            "message": "Login successfully",
                            "user_id": user.id,
                            "mobile": user.mobile,
                            "token": access_token,
                            "status": status.HTTP_200_OK
                        }
                    )

                except Users.DoesNotExist:

                    return Response(
                        {
                            "message": "Contractor account not found",
                            "status": status.HTTP_404_NOT_FOUND
                        }
                    )

            # =====================================
            # SIGNUP
            # =====================================
            elif action == "signup":

                existing_user = Users.objects.filter(
                    mobile=mobile,
                    user_type=3
                ).first()

                print(existing_user)

                if existing_user:

                    return Response(
                        {
                            "message": "Mobile number already registered",
                            "status": status.HTTP_400_BAD_REQUEST
                        }
                    )


                return Response(
                    {
                        "message": "OTP verified successfully",
                        "status": status.HTTP_200_OK
                    }
                )

            return Response(
                {
                    "message": "Invalid action",
                    "status": status.HTTP_400_BAD_REQUEST
                }
            )

        except Exception as e:

            print(e)

            return Response(
                {
                    "message": "Something went wrong. Please try again later.",
                    "error": str(e),
                    "status": status.HTTP_500_INTERNAL_SERVER_ERROR
                }
            )


@api_view(['get'])
def verifyUser(request):
    user = verify_token(request)
    if user == None:
        return Response({'message' : "User not logged in", 'status':status.HTTP_401_UNAUTHORIZED})
    else:
        try:
            user = Users.objects.get(id = user)
            return Response({'message' : "User logged in", 'name' : user.name, 'id' : user.id, 'profile_pic' : str(user.profile_pic), 'email' : user.email, 'mobile' : user.mobile, 'status':status.HTTP_200_OK})
        except Exception as e:
           print(e)
           return Response({'message' : "User not logged in", 'status':status.HTTP_401_UNAUTHORIZED})




class ContractorProfileView(APIView):

    def get(self, request):

        user_id = verify_token(request)

        if not user_id:
            return Response(
                {"message": "Unauthorized"},
                status=status.HTTP_401_UNAUTHORIZED
            )

        try:

            user = Users.objects.get(id=user_id)

            if user.user_type != 3:
                return Response(
                    {"message": "Only contractors allowed"},
                    status=status.HTTP_403_FORBIDDEN
                )

            profile, _ = ContractorProfile.objects.get_or_create(user=user)

            serializer = ContractorProfileSerializer(profile)

            return Response({
                "message": "Profile fetched successfully",
                "profile": serializer.data,
                'status' : status.HTTP_200_OK
            }, status=status.HTTP_200_OK)

        except Exception as e:
            print(e)
            return Response({"message": str(e)}, status=500)

        


    def post(self, request):

        user_id = verify_token(request)

        if not user_id:
            return Response(
                {"message": "Unauthorized"},
                status=status.HTTP_401_UNAUTHORIZED
            )

        try:

            user = Users.objects.get(id=user_id)

            if user.user_type != 3:
                return Response(
                    {"message": "Only contractors allowed"},
                    status=status.HTTP_403_FORBIDDEN
                )

            profile, _ = ContractorProfile.objects.get_or_create(user=user)

            data = request.data

            # =========================
            # USER FIELDS
            # =========================
            user.name = data.get("name", user.name)
            user.email = data.get("email", user.email)
            user.mobile = data.get("mobile", user.mobile)
            user.address = data.get("address", user.address)

            if request.FILES.get("profile_pic"):
                user.profile_pic = request.FILES.get("profile_pic")

            user.save()

            # =========================
            # PROFILE FIELDS
            # =========================
            profile.bio = data.get("bio", profile.bio)
            profile.experience_years = data.get("experience_years", profile.experience_years)
            profile.location = data.get("address", profile.location)

            profile.save()

            # =========================
            # SUB CATEGORIES
            # =========================
            categories = data.get("sub_categories", [])
            print(categories)

            if isinstance(categories, str):
                categories = categories.split(",")

            if categories:
                subs = Sub_Categories.objects.filter(id__in=categories)
                profile.sub_categories.set(subs)

            return Response(
                {"message": "Profile updated successfully", "status":status.HTTP_200_OK},
                status=status.HTTP_200_OK
            )

        except Exception as e:
            return Response(
                {"message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
        


class ContractorSignupView(APIView):

    @transaction.atomic
    def post(self, request):

        try:
            name = request.data.get("name")
            email = request.data.get("email")
            mobile = request.data.get("mobile")
            bio = request.data.get("bio")
            location = request.data.get("location")

            experience_years = request.data.get("experience_years", 0)

            # ----------------------
            # VALIDATION
            # ----------------------
            if not name:
                return Response({"message": "Name is required"}, status=400)

            if not mobile:
                return Response({"message": "Mobile number is required"}, status=400)

            if Users.objects.filter(mobile=mobile).exists():
                return Response(
                    {"message": "Mobile number already registered"},
                    status=400
                )

            # ----------------------
            # CREATE USER
            # ----------------------
            user = Users.objects.create(
                username=mobile,
                name=name,
                email=email,
                mobile=mobile,
                user_type=3,   # FIX: keep consistent with your model
                is_active=True
            )

            if request.FILES.get("profile_pic"):
                user.profile_pic = request.FILES["profile_pic"]
                user.save()

            # ----------------------
            # CREATE PROFILE
            # ----------------------
            profile = ContractorProfile.objects.create(
                user=user,
                bio=bio,
                location=location,
                experience_years=int(experience_years or 0)
            )

            # ----------------------
            # SUB CATEGORIES (FIXED JSON PARSE)
            # ----------------------
            raw_categories = request.data.get("sub_categories")

            if raw_categories:
                try:
                    category_ids = json.loads(raw_categories)  # ✅ FIX HERE
                except:
                    category_ids = []

                if category_ids:
                    sub_categories = Sub_Categories.objects.filter(id__in=category_ids)
                    profile.sub_categories.set(sub_categories)

            # ----------------------
            # PORTFOLIO WORKS (FIXED)
            # ----------------------
            works_data = []

            for key in request.data.keys():
                if key.startswith("works[") and "]" in key:
                    works_data.append(key.split("]")[0] + "]")

            work_indexes = sorted(set(
                int(k.split("[")[1].split("]")[0])
                for k in works_data
            ))

            for i in work_indexes:

                description = request.data.get(f"works[{i}][description]", "").strip()
                owner_contact = request.data.get(f"works[{i}][owner_contact]", "").strip()
                owner_email = request.data.get(f"works[{i}][owner_email]", "").strip()
                image = request.FILES.get(f"works[{i}][image]")

                # ✅ SKIP IF EVERYTHING IS EMPTY
                if not description and not owner_contact and not owner_email and not image:
                    continue

                ContractorWork.objects.create(
                    profile=profile,
                    description=description if description else None,
                    owner_contact=owner_contact if owner_contact else None,
                    owner_email=owner_email if owner_email else None,
                    file=image
                )

            return Response(
                {
                    "message": "Contractor registered successfully",
                    "user_id": user.id,
                    "status" : status.HTTP_200_OK
                },
                status=status.HTTP_200_OK
            )

        except Exception as e:
            transaction.set_rollback(True)
            return Response(
                {"message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )