# from chat_module import generate_response
from groq_module import chat_with_groq, groq_module_fun
import time
import re
import json
from resume_func import extract_json_from_txt

def calculate_experience_score(expected_experience, current_experience, base_score=80):

    expected_experience = int(expected_experience)
    current_experience = int(current_experience)
    base_score = int(base_score)
    # Calculate the absolute difference between expected and current experience
    difference = abs(expected_experience - current_experience)

    print(f"Expected Experience: {expected_experience} years")
    print(f"Current Experience: {current_experience} years")
    print(f"Difference: {difference} years")

    # Apply conditions based on the difference
    if difference <= 1:
        print("Difference is 1 year or less. No score penalty applied.")
        final_score = base_score
    elif 1 < difference <= 2:
        print("Difference is between 1-2 years. Deducting 15% from the score.")
        final_score = base_score * 0.85
    elif 2 < difference <= 3:
        print("Difference is between 2-3 years. Deducting 20% from the score.")
        final_score = base_score * 0.80
    elif 3 < difference <= 4:
        print("Difference is between 3-4 years. Deducting 25% from the score.")
        final_score = base_score * 0.75
    else:
        print("Difference is more than 4 years. Deducting 30% from the score.")
        final_score = base_score * 0.70

    # Ensure score does not drop below 7% of the base score
    if final_score < (base_score * 0.07):
        print("Final score is less than 7% of the base score. Setting score to 7% of base score.")
        final_score = base_score * 0.07

    return round(final_score, 2)


def extract_json(input_text):
    """
    Extract the JSON block from the provided text.
    """
    try:
        if not input_text:
            raise ValueError("Empty response, cannot extract JSON.")
        start_index = input_text.find("{")
        end_index = input_text.rfind("}") + 1
        if start_index != -1 and end_index != -1:
            json_data = input_text[start_index:end_index]
            return json_data.strip()  # Strip extra spaces or newlines
        else:
            raise ValueError("No JSON data found in the input text.")
    except Exception as e:
        raise ValueError(f"Error extracting JSON: {e}")


def matching_cv_img(cv_base64, title, job_title, description, technologies, experience, max_retries=3, retry_delay=2):
    """
    Match CV with job description and extract required details in JSON format.
    Retries the operation up to max_retries if an error occurs.
    """
    # Define the prompt with the transcription included
    prompt = f'''
    The following is a base64 image of a resume:

    Based on this base64, extract and return the following details of the candidate:
        - First Name
        - Last Name (This is the family name or surname. Ensure to extract this correctly.)
        - Job Title
        - Email
        - Technologies (A list of technologies the candidate has mentioned, such as programming languages or tools.)
        - Total Experience (in years)
        - Certifications
        - Bio (The bio should be extracted from the profile section if available.)
        - Projects (A list of projects the candidate has worked on.)
        - Screening_percentage (match the above CV with the following job Description and return the matching percentage of the CV with job description up to two decimal places.)
    
    Job Description:-
    title: {title}
    job_title: {job_title}
    description: {description}
    technologies: {technologies}
    experience: {experience}
    
    Make sure **all** 10 fields are present in the response, even if some are empty.

    Return the result in **JSON format only** with the following exact keys (case-sensitive):

    Example JSON output:
    {{
        "firstName": "John",
        "lastName": "Doe",
        "jobTitle": "Senior Developer",
        "email": "johndoe@example.com",
        "technologies": ["JavaScript", "TypeScript", "React", "Node.js"],
        "experience": 5, <experience should be in years not months not float>
        "certifications": ["AWS Certified Developer", "Scrum Master"],
        "bio": "Passionate developer with 5 years of experience in web development.",
        "projects": ["Project A", "Project B"],
        "Screening_percentage": 26.98
    }}
    '''
    attempts = 0
    while attempts < max_retries:
        try:
            # Generate response using the provided function
            response = groq_module_fun(prompt,cv_base64)
            
            # Extract JSON data
            json_data_str = extract_json(response)
            json_data = json.loads(json_data_str)
            
            # Write the response to a text file for debugging
            output_file = 'matching_per.txt'
            with open(output_file, 'w') as file:
                file.write(response)
            
            print("File saved successfully.")
            return json_data
        except json.JSONDecodeError as e:
            print(f"Attempt {attempts + 1}: Error decoding JSON - {e}")
        except ValueError as e:
            print(f"Attempt {attempts + 1}: {e}")
        except Exception as e:
            print(f"Attempt {attempts + 1}: An unexpected error occurred - {e}")
        
        attempts += 1
        if attempts < max_retries:
            print(f"Retrying in {retry_delay} seconds...")
            time.sleep(retry_delay)
    
    # If all retries fail, return an error
    return {"error": f"Failed to process after {max_retries} attempts."}

def matching_cv(cv, title, job_title, description, technologies, experience, max_retries=3, retry_delay=2):
    """
    Match CV with job description and extract required details in JSON format.
    Retries the operation up to max_retries if an error occurs.
    """
    # Define the prompt with the transcription included
    prompt = f'''
    The following is a transcription of a resume:
    {cv}

    Based on this transcription, extract and return the following details of the candidate:
        - First Name
        - Last Name (This is the family name or surname. Ensure to extract this correctly.)
        - Job Title
        - Email
        - Technologies (A list of technologies the candidate has mentioned, such as programming languages or tools.)
        - Total Experience (in years)
        - Certifications
        - Bio (The bio should be extracted from the profile section if available.)
        - Projects (A list of projects the candidate has worked on.)
        - Screening_percentage (match the above CV with the following job Description and return the matching percentage of the CV with job description up to two decimal places.)
    
    Job Description:-
    title: {title}
    job_title: {job_title}
    description: {description}
    technologies: {technologies}
    experience: {experience}
    
    Make sure **all** 10 fields are present in the response, even if some are empty.

    Return the result in **JSON format only** with the following exact keys (case-sensitive):

    Example JSON output:
    {{
        "firstName": "John",
        "lastName": "Doe",
        "jobTitle": "Senior Developer",
        "email": "johndoe@example.com",
        "technologies": ["JavaScript", "TypeScript", "React", "Node.js"],
        "experience": 5, <experience should be in years not months not float>
        "certifications": ["AWS Certified Developer", "Scrum Master"],
        "bio": "Passionate developer with 5 years of experience in web development.",
        "projects": ["Project A", "Project B"],
        "Screening_percentage": 26.98
    }}
    '''
    attempts = 0
    while attempts < max_retries:
        try:
            # Generate response using the provided function
            response = chat_with_groq(prompt)

            if not response:
                raise ValueError("Empty response received from LLM")
            
            # Extract JSON data
            json_data_str = extract_json(response)

            if not json_data_str:
                raise ValueError("Failed to extract JSON from LLM response")
            json_data = json.loads(json_data_str)
            
            # Write the response to a text file for debugging
            output_file = 'matching_per.txt'
            with open(output_file, 'w') as file:
                file.write(response)
            
            print("File saved successfully.")
            return json_data
        except json.JSONDecodeError as e:
            print(f"Attempt {attempts + 1}: Error decoding JSON - {e}")
        except ValueError as e:
            print(f"Attempt {attempts + 1}: {e}")
        except Exception as e:
            print(f"Attempt {attempts + 1}: An unexpected error occurred - {e}")
        
        attempts += 1
        if attempts < max_retries:
            print(f"Retrying in {retry_delay} seconds...")
            time.sleep(retry_delay)
    
    # If all retries fail, return an error
    return {"error": f"Failed to process after {max_retries} attempts."}


def extract_cv_img(cv_base64, max_retries=3, retry_delay=2):
    """
    Match CV with job description and extract required details in JSON format.
    Retries the operation up to max_retries if an error occurs.
    """
    # Define the prompt with the transcription included
    prompt = f'''
    The following is a base64 image of a resume:

    Based on this base64, extract and return the following details of the candidate:
        - First Name
        - Last Name (This is the family name or surname. Ensure to extract this correctly.)
        - Job Title
        - Email
        - Technologies (A list of technologies the candidate has mentioned, such as programming languages or tools.)
        - Total Experience (in years)
        - Certifications
        - Bio (The bio should be extracted from the profile section if available.)
        - Projects (A list of projects the candidate has worked on.)
    

    
    Make sure **all** 9 fields are present in the response, even if some are empty.

    Return the result in **JSON format only** with the following exact keys (case-sensitive):

    Example JSON output:
    {{
        "firstName": "John",
        "lastName": "Doe",
        "jobTitle": "Senior Developer",
        "email": "johndoe@example.com",
        "technologies": ["JavaScript", "TypeScript", "React", "Node.js"],
        "experience": 5, <experience should be in years not months not float>
        "certifications": ["AWS Certified Developer", "Scrum Master"],
        "bio": "Passionate developer with 5 years of experience in web development.",
        "projects": ["Project A", "Project B"],
    }}
    '''
    attempts = 0
    while attempts < max_retries:
        try:
            # Generate response using the provided function
            response = groq_module_fun(prompt,cv_base64)
            
            # Extract JSON data
            json_data_str = extract_json(response)
            json_data = json.loads(json_data_str)
            
            # Write the response to a text file for debugging
            output_file = 'matching_per.txt'
            with open(output_file, 'w') as file:
                file.write(response)
            
            print("File saved successfully.")
            return json_data
        except json.JSONDecodeError as e:
            print(f"Attempt {attempts + 1}: Error decoding JSON - {e}")
        except ValueError as e:
            print(f"Attempt {attempts + 1}: {e}")
        except Exception as e:
            print(f"Attempt {attempts + 1}: An unexpected error occurred - {e}")
        
        attempts += 1
        if attempts < max_retries:
            print(f"Retrying in {retry_delay} seconds...")
            time.sleep(retry_delay)
    
    # If all retries fail, return an error
    return {"error": f"Failed to process after {max_retries} attempts."}

def extract_cv(cv, max_retries=3, retry_delay=2):
    """
    Match CV with job description and extract required details in JSON format.
    Retries the operation up to max_retries if an error occurs.
    """
    # Define the prompt with the transcription included
    prompt = f'''
    The following is a transcription of a resume:
    {cv}

    Based on this transcription, extract and return the following details of the candidate:
        - First Name
        - Last Name (This is the family name or surname. Ensure to extract this correctly.)
        - Job Title
        - Email
        - Technologies (A list of technologies the candidate has mentioned, such as programming languages or tools.)
        - Total Experience (in years)
        - Certifications
        - Bio (The bio should be extracted from the profile section if available.)
        - Projects (A list of projects the candidate has worked on.)
    

    
    Make sure **all** 9 fields are present in the response, even if some are empty.

    Return the result in **JSON format only** with the following exact keys (case-sensitive):

    Example JSON output:
    {{
        "firstName": "John",
        "lastName": "Doe",
        "jobTitle": "Senior Developer",
        "email": "johndoe@example.com",
        "technologies": ["JavaScript", "TypeScript", "React", "Node.js"],
        "experience": 5, <experience should be in years not months not float>
        "certifications": ["AWS Certified Developer", "Scrum Master"],
        "bio": "Passionate developer with 5 years of experience in web development.",
        "projects": ["Project A", "Project B"],
    }}
    '''
    attempts = 0
    while attempts < max_retries:
        try:
            # Generate response using the provided function
            response = chat_with_groq(prompt)
            
            # Extract JSON data
            json_data_str = extract_json(response)
            json_data = json.loads(json_data_str)
            
            # Write the response to a text file for debugging
            output_file = 'matching_per.txt'
            with open(output_file, 'w') as file:
                file.write(response)
            
            print("File saved successfully.")
            return json_data
        except json.JSONDecodeError as e:
            print(f"Attempt {attempts + 1}: Error decoding JSON - {e}")
        except ValueError as e:
            print(f"Attempt {attempts + 1}: {e}")
        except Exception as e:
            print(f"Attempt {attempts + 1}: An unexpected error occurred - {e}")
        
        attempts += 1
        if attempts < max_retries:
            print(f"Retrying in {retry_delay} seconds...")
            time.sleep(retry_delay)
    
    # If all retries fail, return an error
    return {"error": f"Failed to process after {max_retries} attempts."}



def validate_cv(cv, max_retries=3, retry_delay=2):
    prompt = f"""
You are an expert resume extractor.  Extract **exactly** these five fields from the text below:
  • firstName    (string)
  • jobTitle     (string)
  • email        (string)
  • technologies (array of strings)
  • experience   (integer years)

  
If any field from these 5 is not present, return it as null.
=== RESUME TEXT START ===
{cv}
=== RESUME TEXT END ===

Return **only** a JSON object with these keys and no extra fields, for example:
{{
  "firstName": "Alice",
  "jobTitle": "Backend Developer",
  "email": "alice@example.com",
  "technologies": ["Python","Django","PostgreSQL"],
  "experience": 5
}}
"""
    for attempt in range(max_retries):
        response = chat_with_groq(prompt)
        try:
            # grab the JSON substring
            raw = extract_json_from_txt(response) if not isinstance(response, dict) else response
            return raw if isinstance(raw, dict) else json.loads(raw)
        except Exception:
            time.sleep(retry_delay)
    return {"error": f"Failed after {max_retries} attempts"}

def validate_cv_img(cv_base64, max_retries=3, retry_delay=2):
    prompt = f"""
You are an expert resume extractor.  Below is a base64-encoded image of a resume.
Extract **exactly** these five fields and return only a JSON object:

  • firstName    (string)
  • jobTitle     (string)
  • email        (string)
  • technologies (array of strings)
  • experience   (integer years)

Return **only** a JSON object, e.g.:
{{
  "firstName": "Bob",
  "jobTitle": "DevOps Engineer",
  "email": "bob@acme.com",
  "technologies": ["AWS","Terraform","Kubernetes"],
  "experience": 4
}}
"""
    for attempt in range(max_retries):
        response = groq_module_fun(prompt, cv_base64)
        try:
            raw = response if isinstance(response, dict) else json.loads(extract_json_from_txt(response))
            return raw
        except Exception:
            time.sleep(retry_delay)
    return {"error": f"Failed after {max_retries} attempts"}