from django.shortcuts import render
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny
from rest_framework.response import Response

from serp.models import Region, Keyword, Language, Groups, Competitors
from account.models import Account  # Assuming this is the correct import for user accounts
from datetime import datetime, time
import pytz
from django.http import JsonResponse, HttpResponse
from django.db.models import Prefetch, Count, Q, IntegerField
from django.db.models.functions import Cast
import numpy
import requests
import json
import os
from django.conf import settings
import requests
from serp.utils import safe_round, capitalized_word, search_volume_labels, search_volume_values, rank_history_labels, rank_history_values
import traceback
from django.db.models import Q
from django.core.paginator import Paginator

API_KEY = ""
URL = "https://api.scrapingdog.com/google/"


@api_view(["POST"])
def getsetting(request):
    if request.method == "POST":
        userid = request.data.get("userid")
        grpid = request.data.get("grpid")

        if userid and str(grpid):
            # Fetching regions correctly
            regions = list(Region.objects.all().values("id", "region_name", "region_code", "region_country"))

            # Fetching keywords
            GrpKeywdIns = Keyword.objects.filter(fk_user_id=userid, fk_group_id=grpid).values("isocode", "location")
            KeywdIns = Keyword.objects.filter(fk_user_id=userid).values("isocode", "location")

            GrplastKeywd = GrpKeywdIns.last()
            lastKeywd = KeywdIns.last()

            if GrplastKeywd:
                location_parts = GrplastKeywd["location"].split("(")
                lastKeywdRegion = f"{GrplastKeywd['isocode'].lower()}|{location_parts[0].strip()}|{location_parts[1].replace(')','').strip()}"
            elif lastKeywd:
                location_parts = lastKeywd["location"].split("(")
                lastKeywdRegion = f"{lastKeywd['isocode'].lower()}|{location_parts[0].strip()}|{location_parts[1].replace(')','').strip()}"
            else:
                lastKeywdRegion = "us|google.com|United States"

            if request.data.get("type") == "RGOLY":
                return JsonResponse({"status": "true", "rg": regions, "DR": lastKeywdRegion})

            keycountvalue = GrpKeywdIns.count()
            # Fetch languages
            languages = list(Language.objects.all().values("id", "language_name"))

            groupcountvalue = Groups.objects.filter(fk_user_id=userid).count()
            groupdata = Groups.objects.filter(fk_user_id=userid, id=grpid).values("domain_name").first()
            domain_name = groupdata["domain_name"] if groupdata else None

            # Removing 'tags' logic as it's not a valid field
            taglist = []

            response_data = {"status": "true", "dN": domain_name, "g_l": groupcountvalue, "u_kw": "0", "k_l": keycountvalue, "o_tg": taglist, "lnge": languages, "rg": regions, "DR": lastKeywdRegion}

            return JsonResponse(response_data)

    return JsonResponse({"status": "false", "message": "Something went wrong"})


@api_view(["POST"])
def addProject(request):
    try:
        print("Function calling here... ")
        # Extract request data
        userid = request.data.get("userid", 0)  # No .strip(), default to 0
        getLanguage = request.data.get("language", "").strip()
        grpName = request.data.get("group_name", "").strip()
        region = request.data.get("region", "").strip()
        countryname = request.data.get("countryname", "").strip()
        platform = request.data.get("platform", "").strip()
        isocode = request.data.get("isocode", 0)  # No .strip(), default to 0
        site_url = request.data.get("url", "").strip()

        # Validate input
        if not userid or not grpName:
            return Response({"error": "Invalid userid or group name"}, status=400)

        # Fetch user instance
        user = Account.objects.filter(id=int(userid)).first()
        if not user:
            return Response({"error": "User not found"}, status=404)

        # Fetch or create the language
        languageData = Language.objects.filter(language_name=getLanguage).first()
        if not languageData:
            return Response({"error": "Invalid language"}, status=400)

        # Get or create group
        group, created = Groups.objects.get_or_create(fk_user=user, group_name=grpName, defaults={"domain_name": site_url, "project_automation_time": datetime.now()})

        # Ensure dataChecklist is a list
        dataChecklist = request.data.get("keyword", [])
        if isinstance(dataChecklist, str):
            dataChecklist = list(set(map(str.strip, dataChecklist.replace("\n", ",").lower().split(","))))
        if not dataChecklist:
            return Response({"error": "No valid keywords provided"}, status=400)

        region_data = Region.objects.filter(region_name=region).first()
        location_code = 2840
        if region_data:
            location_code = int(region_data.searchvolume_country_id)

        # Bulk create keyword objects linked to the group
        keywords = [
            Keyword(
                fk_user=user,
                fk_group=group,
                keyword=kw.lower().strip(),
                site_url=site_url,
                target=site_url,
                location=f"{region} ({countryname})",
                region=region,
                location_code=location_code,
                language=getLanguage,
                language_code=languageData.language_code.strip(),
                platform=platform,
                isocode=isocode,
                exactdomain=False,  # Set appropriately
                lastranked_date=datetime.now(),
                status_from_start="-",
                rank=[],
                ranknow=0,
                rank_sincestart=0,
                auto_refresh_count=0,
                modified_date=datetime.now(),
                dayval=0,
            )
            for kw in dataChecklist
        ]
        Keyword.objects.bulk_create(keywords)  # Optimized bulk insert

        return Response(
            {
                "message": "Keywords successfully saved",
                "group_created": created,
                "group_id": group.id,
            },
            status=201,
        )

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


@api_view(["POST"])
def getAllProjects(request):
    try:
        # Extract request data
        userid = request.data.get("userid", 0)

        # Validate input
        if not userid:
            return Response({"error": "Invalid userid or group name"}, status=400)

        # Fetch user instance
        user = Account.objects.filter(id=int(userid)).first()
        if not user:
            return Response({"error": "User not found"}, status=404)

        projectList = list(Groups.objects.filter(fk_user_id=user).values("id", "fk_user_id", "group_name", "uptrend_cnt", "downtrend_cnt", "domain_name", "created_date"))

        for project in projectList:
            prj_id = project["id"]
            project["top10_record"] = Keyword.objects.filter(fk_group=prj_id, ranknow__gt=0, ranknow__lte=10).count()
            project["firstPosition_record"] = Keyword.objects.filter(fk_group=prj_id, ranknow=1).count()
        return Response({"projects": list(projectList)}, status=201)

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


# @api_view(["POST"])
# def getAllKeywords(request):
#     try:
#         # Extract request data
#         userid = request.data.get("userid", 0)
#         grpid = request.data.get("grpid", 0)
#         compid = request.data.get("compid", 0)


#         # Validate input
#         if not userid or not grpid:
#             return Response({"error": "Invalid userid or group ID"}, status=400)

#    # Parse date strings
#         # from_date = datetime.strptime(from_date_str, "%Y-%m-%d") if from_date_str else None
#         # to_date = datetime.strptime(to_date_str, "%Y-%m-%d") if to_date_str else None

#  # Apply date filters
#         # if from_date and to_date:
#         #     keyword_queryset = keyword_queryset.filter(created_at__date__range=(from_date, to_date))
#         # elif from_date:
#         #     keyword_queryset = keyword_queryset.filter(created_at__date__gte=from_date)
#         # elif to_date:
#         #     keyword_queryset = keyword_queryset.filter(created_at__date__lte=to_date)

#         # Fetch user instance
#         user = Account.objects.filter(id=int(userid)).first()
#         if not user:
#             return Response({"error": "User not found"}, status=404)

#         # Fetch competitor keywords
#         competitorData = {}
#         if compid:
#             competitorData = Competitors.objects.filter(id=int(compid)).first()
#         else:
#             competitorData = Competitors.objects.filter(fk_group_id=int(grpid)).first()
#         rank_array = []
#         rank_mapping = {}

#         if competitorData and competitorData.keywords:
#             rank_array = competitorData.keywords  # assuming this is stored as a list/dict (e.g. JSONField)
#             rank_mapping = {item["keyword"]: item["rank"] for item in rank_array}

#         # Fetch keywords from the database
#         keywordList = list(Keyword.objects.filter(fk_user_id=user, fk_group_id=grpid).values("id", "fk_user_id", "fk_group_id", "site_url", "target", "keyword", "rank", "ranked_url", "ranknow", "search_volume", "search_volume_data", "search_intent", "traffic", "keyword_difficulty", "cpc", "track_status", "metric_status", "rank_history"))

#         # Merge rank data into keyword list
#         optimized_keywordList = [
#             {
#                 **kw_entry,
#                 "matched_rank": rank_mapping.get(kw_entry["keyword"], ">100") if competitorData else ">100",
#                 "ranked_url": kw_entry["ranked_url"],
#                 "search_volume_monthly_labels": search_volume_labels(kw_entry["search_volume_data"]),
#                 "search_volume_monthly_values": search_volume_values(kw_entry["search_volume_data"]),
#                 "rank_history_daily_labels": (kw_entry["rank_history"]),
#                 "rank_history_daily_values": rank_history_values(kw_entry["rank_history"]),
#                 "keyword_difficulty": safe_round(kw_entry["keyword_difficulty"]),
#                 "search_intent": capitalized_word(kw_entry["search_intent"]),
#                 "cpc": safe_round(kw_entry["cpc"]),
#                 "traffic": safe_round(kw_entry["traffic"]),
#                 "track_status": kw_entry["track_status"],
#                 "metric_status": kw_entry["metric_status"],
#             }
#             for kw_entry in keywordList
#         ]

#         return Response({"keywords": optimized_keywordList}, status=200)

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


# @api_view(["POST"])
# def getAllKeywords(request):
#     try:
#         userid = request.data.get("userid", 0)
#         grpid = request.data.get("grpid", 0)
#         compid = request.data.get("compid", 0)
#         from_date_str = request.data.get("from_date")
#         to_date_str = request.data.get("to_date")


# print(f"From Date: {from_date_str}, To Date: {to_date_str}")

#         if not userid or not grpid:
#             return Response({"error": "Invalid userid or group ID"}, status=400)

#         user = Account.objects.filter(id=int(userid)).first()
#         if not user:
#             return Response({"error": "User not found"}, status=404)

#         # Parse date strings into datetime objects
#         from_date = datetime.strptime(from_date_str, "%Y-%m-%d") if from_date_str else None
#         to_date = datetime.strptime(to_date_str, "%Y-%m-%d") if to_date_str else None

#         # Always initialize keyword_queryset first
#         keyword_queryset = Keyword.objects.filter(fk_user_id=user, fk_group_id=grpid)

#         if from_date and to_date:
#             keyword_queryset = keyword_queryset.filter(created_date__range=[from_date, to_date])
#         elif from_date:
#             keyword_queryset = keyword_queryset.filter(created_date__gte=from_date)
#         elif to_date:
#             keyword_queryset = keyword_queryset.filter(created_date__lte=to_date)

#         # Fetch competitor data
#         competitorData = None
#         if compid:
#             competitorData = Competitors.objects.filter(id=int(compid)).first()
#         else:
#             competitorData = Competitors.objects.filter(fk_group_id=int(grpid)).first()

#         rank_mapping = {}
#         if competitorData and competitorData.keywords:
#             rank_mapping = {item["keyword"]: item["rank"] for item in competitorData.keywords}

#         # Construct the keyword list
#         keywordList = list(keyword_queryset.values(
#             "id", "fk_user_id", "fk_group_id", "site_url", "target", "keyword",
#             "rank", "ranked_url", "ranknow", "search_volume", "search_volume_data",
#             "search_intent", "traffic", "keyword_difficulty", "cpc", "track_status",
#             "metric_status", "rank_history", "created_date"
#         ))

#         # Prepare optimized keyword list
#         optimized_keywordList = [
#             {
#                 **kw,
#                 "matched_rank": rank_mapping.get(kw["keyword"], ">100") if competitorData else ">100",
#                 "search_volume_monthly_labels": search_volume_labels(kw["search_volume_data"]),
#                 "search_volume_monthly_values": search_volume_values(kw["search_volume_data"]),
#                 "rank_history_daily_labels": kw["rank_history"],
#                 "rank_history_daily_values": rank_history_values(kw["rank_history"]),
#                 "keyword_difficulty": safe_round(kw["keyword_difficulty"]),
#                 "search_intent": capitalized_word(kw["search_intent"]),
#                 "cpc": safe_round(kw["cpc"]),
#                 "traffic": safe_round(kw["traffic"]),
#             }
#             for kw in keywordList
#         ]

#         return Response({"keywords": optimized_keywordList}, status=200)

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

@api_view(["POST"])
def getAllKeywords(request):
    try:
        userid = request.data.get("userid", 0)
        grpid = request.data.get("grpid", 0)
        compid = request.data.get("compid", 0)
        from_date_str = request.data.get("from_date")
        to_date_str = request.data.get("to_date")

      
        if not userid or not grpid:
            return Response({"error": "Invalid userid or group ID"}, status=400)

        user = Account.objects.filter(id=int(userid)).first()
        if not user:
            return Response({"error": "User not found"}, status=404)

        # Parse date strings into datetime objects
        utc = pytz.UTC
         # Parse dates with timezone awareness
        from_date = datetime.strptime(from_date_str, "%Y-%m-%d").replace(tzinfo=utc) if from_date_str else None
        to_date = datetime.strptime(to_date_str, "%Y-%m-%d").replace(tzinfo=utc) if to_date_str else None

        print(f"From Date: {from_date}, To Date: {to_date}")

        # Set to_date to end of day (23:59:59.999999) with timezone
        if to_date:
         to_date = to_date.replace(hour=23, minute=59, second=59, microsecond=999999)


        # Always initialize keyword_queryset first
        keyword_queryset = Keyword.objects.filter(fk_user_id=user, fk_group_id=grpid)

        if from_date and to_date:
            keyword_queryset = keyword_queryset.filter(created_date__range=[from_date, to_date])
        elif from_date:
            keyword_queryset = keyword_queryset.filter(created_date__gte=from_date)
        elif to_date:
            keyword_queryset = keyword_queryset.filter(created_date__lte=to_date)

        # Fetch competitor data
        competitorData = None
        if compid:
            competitorData = Competitors.objects.filter(id=int(compid)).first()
        else:
            competitorData = Competitors.objects.filter(fk_group_id=int(grpid)).first()

        rank_mapping = {}
        if competitorData and competitorData.keywords:
            rank_mapping = {item["keyword"]: item["rank"] for item in competitorData.keywords}

        # Construct the keyword list
        keywordList = list(keyword_queryset.values(
            "id", "fk_user_id", "fk_group_id", "site_url", "target", "keyword",
            "rank", "ranked_url", "ranknow", "search_volume", "search_volume_data",
            "search_intent", "traffic", "keyword_difficulty", "cpc", "track_status",
            "metric_status", "rank_history", "created_date"
        ))

        # Prepare optimized keyword list
        optimized_keywordList = [
            {
                **kw,
                "matched_rank": rank_mapping.get(kw["keyword"], ">100") if competitorData else ">100",
                "search_volume_monthly_labels": search_volume_labels(kw["search_volume_data"]),
                "search_volume_monthly_values": search_volume_values(kw["search_volume_data"]),
                "rank_history_daily_labels": kw["rank_history"],
                "rank_history_daily_values": rank_history_values(kw["rank_history"]),
                "keyword_difficulty": safe_round(kw["keyword_difficulty"]),
                "search_intent": capitalized_word(kw["search_intent"]),
                "cpc": safe_round(kw["cpc"]),
                "traffic": safe_round(kw["traffic"]),
            }
            for kw in keywordList
        ]

        return Response({"keywords": optimized_keywordList}, status=200)

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


@api_view(["POST"])
def addKeyword(request):
    try:
        userid = request.data["userid"]
        grpid = request.data["grpid"]
        getLanguage = request.data["language"].strip()
        languageData = Language.objects.filter(language_name=getLanguage).first()
        exactdomain = request.data["exactdomain"]
        region = request.data.get("region", "").strip()
        countryname = request.data.get("countryname", "").strip()
        platform = request.data.get("platform", "").strip()
        isocode = request.data.get("isocode", 0)  # No .strip(), default to 0
        site_url = request.data.get("url", "").strip()
        if exactdomain:
            url = request.data["url"].strip()
        else:
            url = request.data["url"].lower().strip()
        domain = url
        # Fetch user instance
        user = Account.objects.filter(id=int(userid)).first()
        if not user:
            return Response({"error": "User not found"}, status=404)

        group = Groups.objects.filter(id=int(grpid)).first()
        if not group:
            return Response({"error": "Project not found"}, status=404)

        if userid and grpid and languageData.language_code:
            dataChecklist = request.data["keyword"]

            if not isinstance(dataChecklist, list):
                dataCheckKeywords = request.POST["keyword"].replace("\n", ",").lower().strip()
                keywordArray = dataCheckKeywords.split(",")
                dataChecklist = list(set(filter(None, map(str.strip, keywordArray))))

            if len(dataChecklist) > 0:
                existsKW = list(Keyword.objects.filter(keyword__in=dataChecklist, site_url__contains=domain, exactdomain__in=[exactdomain], fk_group_id=grpid, region=request.data["region"].strip(), platform=request.data["platform"]).values_list("keyword", flat=True))
                keywords = []
                newkeywords = set(dataChecklist) - set(existsKW)
                newKeyCount = len(newkeywords)
                if newKeyCount == 0:
                    return Response({"status": "false", "message": "warning", "errormsg": "Keywords already exists. Check once."})

                region_data = Region.objects.filter(region_name=region).first()
                location_code = 2840
                if region_data:
                    location_code = int(region_data.searchvolume_country_id)

                keywords = [
                    Keyword(
                        fk_user=user,
                        fk_group=group,
                        keyword=kw.lower().strip(),
                        site_url=site_url,
                        target=site_url,
                        location=f"{region} ({countryname})",
                        region=region,
                        location_code=location_code,
                        language=getLanguage,
                        language_code=languageData.language_code.strip(),
                        platform=platform,
                        isocode=isocode,
                        exactdomain=False,  # Set appropriately
                        lastranked_date=datetime.now(),
                        status_from_start="-",
                        rank=[],
                        ranknow=0,
                        rank_sincestart=0,
                        auto_refresh_count=0,
                        modified_date=datetime.now(),
                        dayval=0,
                    )
                    for kw in newkeywords
                ]
                Keyword.objects.bulk_create(keywords)  # Optimized bulk insert
                Groups.objects.filter(id=int(grpid)).update(track_status="INIT", metric_status="INIT")

                return Response({"status": "true", "Engmd": "", "message": "Keyword added", "kwcnt": int(newKeyCount)})
            return JsonResponse({"status": "false", "message": "Already keywords are exits"})
        else:
            return JsonResponse({"status": "false", "message": "Oops! Sorry You've no active subscription."})

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


@api_view(["POST"])
def addCompetitor(request):
    try:
        userid = request.data["userid"]
        grpid = request.data["grpid"]
        url = request.data["url"]
        group = Groups.objects.filter(id=int(grpid)).first()
        if not group:
            return Response({"error": "Project not found"}, status=404)

        user = Account.objects.filter(id=int(userid)).first()
        if not user:
            return Response({"error": "User not found"}, status=404)
        # Get or create group
        competitor, created = Competitors.objects.get_or_create(fk_user=user, fk_group=group, url=url)
        if competitor:
            return JsonResponse({"status": "true", "message": "Competitor created successfully"})
        else:
            return JsonResponse({"status": "false", "message": "Something went wrong"})
    except Exception as e:
        print("Error: ", e)
        return Response({"error": str(e)}, status=500)


@api_view(["POST"])
def getCompetitor(request):
    try:
        userid = int(request.data.get("userid", 0))
        if not userid:
            return Response({"error": "User ID is required"}, status=400)

        try:
            user = Account.objects.get(id=userid)
        except Account.DoesNotExist:
            return Response({"error": "User not found"}, status=404)

        # Prefetch competitors for all groups of the user
        groups = Groups.objects.filter(fk_user_id=userid).prefetch_related(Prefetch("competitors_set", queryset=Competitors.objects.all()))

        data = []
        for group in groups:
            competitors = group.competitors_set.all()  # ✅ Use .all() here
            data.append(
                {
                    "group_id": group.id,
                    "group_name": group.group_name,
                    "domain_name": group.domain_name,
                    "competitors": [
                        {
                            "id": comp.id,
                            "url": comp.url,
                            "track_status": comp.track_status,
                            "keywords": comp.keywords,
                        }
                        for comp in competitors
                    ],
                }
            )

        return JsonResponse({"status": "true", "data": data})

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


@api_view(["POST"])
def getProjectCompetitors(request):
    try:
        userid = int(request.data.get("userid", 0))
        grpid = int(request.data.get("grpid", 0))
        if not userid:
            return Response({"error": "User ID is required"}, status=400)

        try:
            user = Account.objects.get(id=userid)
        except Account.DoesNotExist:
            return Response({"error": "User not found"}, status=404)

        competitorData = list(Competitors.objects.filter(fk_group_id=int(grpid)).values())
        return JsonResponse({"status": "true", "data": competitorData})
    except Exception as e:
        print("Error:", e)
        return Response({"error": str(e)}, status=500)


@api_view(["POST"])
def deleteCompetitor(request):
    try:
        userid = request.data["userid"]
        grpid = request.data["grpid"]
        compid = request.data["compid"]
        group = Groups.objects.filter(id=int(grpid)).first()
        if not group:
            return Response({"error": "Project not found"}, status=404)

        user = Account.objects.filter(id=int(userid)).first()
        if not user:
            return Response({"error": "User not found"}, status=404)

        # Get or create group
        competitor = Competitors.objects.filter(id=int(compid), fk_group_id=int(grpid)).first()
        if competitor:
            competitor.delete()
            return JsonResponse({"status": "true", "message": "Competitor deleted successfully"})
        else:
            return JsonResponse({"status": "false", "message": "Competitor not found"})
    except Exception as e:
        print("Error: ", e)
        return Response({"error": str(e)}, status=500)


@api_view(["GET"])
@permission_classes((AllowAny,))
def competitorMatchKeywords(request):
    try:
        # Get the first competitor with 'INIT' status
        competitor = Competitors.objects.filter(track_status="INIT").first()
        if not competitor:
            return JsonResponse({"status": "false", "message": "No Competitors found"})

        grpid = competitor.fk_group_id
        url = competitor.url
        keywords_list = competitor.keywords
        competitor_keywords = []
        if len(keywords_list) > 0:
            competitor_keywords = [item["keyword"] for item in keywords_list]

        keywordsData = []

        # Get all keywords for the group
        keywords = Keyword.objects.filter(fk_group_id=grpid).exclude(keyword__in=competitor_keywords)
        if len(keywords) > 0:
            for keywrd in keywords:
                fileName = f"jsonData_{grpid}_{keywrd.id}.json"
                file_path = os.path.join(settings.MEDIA_ROOT, fileName)

                try:
                    with open(file_path, "r") as f:
                        data = json.load(f)

                    for entry in data.get("organic_results", []):
                        if url in entry.get("link", ""):
                            position = entry.get("rank", ">100")
                            if position is not None:
                                keywordsData.append({"keyword": keywrd.keyword, "rank": position})
                                break  # Stop after first match for this keyword

                except FileNotFoundError:
                    print(f"File not found: {fileName}")
                except json.JSONDecodeError:
                    print(f"Invalid JSON in file: {fileName}")

        # Update competitor with matched keywords and status
        if len(keywordsData) > 0:
            update_result = Competitors.objects.filter(fk_group_id=grpid, url=url).update(keywords=keywordsData, track_status="COMP")
        else:
            update_result = Competitors.objects.filter(fk_group_id=grpid, url=url).update(track_status="COMP")

        if update_result:
            return JsonResponse({"status": "true", "message": "Matched keywords updated successfully"})
        else:
            return JsonResponse({"status": "false", "message": "Update failed"})

    except Exception as e:
        print("Error:", e)
        return JsonResponse({"status": "false", "message": "Competitors Matching Failed"})


@api_view(["GET"])
@permission_classes((AllowAny,))
def scheduleRankTracking(request):
    groups = Groups.objects.all()

    for group in groups:
        # Update related keywords
        Keyword.objects.filter(fk_group_id=group.id).update(track_status="INIT")

        # Update the group itself
        group.track_status = "INIT"
        group.save()

    return JsonResponse({"status": "true", "message": "Daily rank tracker has been rescheduled"})


@api_view(["GET"])
@permission_classes((AllowAny,))
def scheduleMetricsTracking(request):
    groups = Groups.objects.all()

    for group in groups:
        # Update related keywords
        Keyword.objects.filter(fk_group_id=group.id).update(metric_status="INIT")

        # Update the group itself
        group.metric_status = "INIT"
        group.save()

    return JsonResponse({"status": "true", "message": "Daily rank tracker has been rescheduled"})


@api_view(["GET"])
@permission_classes((AllowAny,))
def competitorMatchKeywords(request):
    try:
        # Get the first competitor with 'INIT' status
        competitor = Competitors.objects.filter(track_status="INIT").first()
        if not competitor:
            return JsonResponse({"status": "false", "message": "No Competitors found"})

        grpid = competitor.fk_group_id
        url = competitor.url
        keywords_list = competitor.keywords
        competitor_keywords = []
        if len(keywords_list) > 0:
            competitor_keywords = [item["keyword"] for item in keywords_list]

        keywordsData = []

        # Get all keywords for the group
        keywords = Keyword.objects.filter(fk_group_id=grpid).exclude(keyword__in=competitor_keywords)
        if len(keywords) > 0:
            for keywrd in keywords:
                fileName = f"jsonData_{grpid}_{keywrd.id}.json"
                file_path = os.path.join(settings.MEDIA_ROOT, fileName)

                try:
                    with open(file_path, "r") as f:
                        data = json.load(f)

                    for entry in data.get("organic_results", []):
                        if url in entry.get("link", ""):
                            position = entry.get("rank", ">100")
                            if position is not None:
                                keywordsData.append({"keyword": keywrd.keyword, "rank": position})
                                break  # Stop after first match for this keyword

                except FileNotFoundError:
                    print(f"File not found: {fileName}")
                except json.JSONDecodeError:
                    print(f"Invalid JSON in file: {fileName}")

        # Update competitor with matched keywords and status
        if len(keywordsData) > 0:
            update_result = Competitors.objects.filter(fk_group_id=grpid, url=url).update(keywords=keywordsData, track_status="COMP")
        else:
            update_result = Competitors.objects.filter(fk_group_id=grpid, url=url).update(track_status="COMP")

        if update_result:
            return JsonResponse({"status": "true", "message": "Matched keywords updated successfully"})
        else:
            return JsonResponse({"status": "false", "message": "Update failed"})

    except Exception as e:
        print("Error:", e)
        return JsonResponse({"status": "false", "message": "Competitors Matching Failed"})

#@api_view(["GET"])
#@permission_classes((AllowAny,))
#def scheduleMetricsTrackingKeywords(request):
#    print("Process of INIT started...")
#    keywords = Keyword.objects.all()
#    for kw in keywords:
#        kw.track_status = "INIT"
#        kw.save()  # This will also update `updated_date` if auto_now=True
#    return JsonResponse({
#        "status": "true",
#        "message": "All keyword track_status and metric_status fields have been reset to INIT via loop."
#    }




@api_view(["GET"])
@permission_classes((AllowAny,))
def scheduleMetricsTrackingKeywords(request):
    print("Process of INIT started...")

    batch_size = 100
    total_updated = 0

    while True:
        batch = Keyword.objects.filter(
            Q(track_status="COMP") | Q(track_status="SCHD")
        ).order_by('id')[:batch_size]

        if not batch:
            break

        ids = list(batch.values_list("id", flat=True))
        Keyword.objects.filter(id__in=ids).update(track_status="INIT")
        total_updated += len(ids)

        print(f"Updated batch of {len(ids)} starting with ID {ids[0] if ids else 'N/A'}")

    return JsonResponse({
        "status": "true",
        "message": f"{total_updated} keywords updated in batches of {batch_size}."
    })

