import os
import time
import random
import re
import json
import requests
from langchain_community.embeddings import OllamaEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_core.prompts import ChatPromptTemplate
from crawl4ai import AsyncWebCrawler
import asyncio
from langchain_groq import ChatGroq
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser, PydanticOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_community.document_loaders import PyPDFLoader, TextLoader, Docx2txtLoader, UnstructuredPowerPointLoader
from PyPDF2 import PdfReader
from langchain_experimental.text_splitter import SemanticChunker
from pydantic import BaseModel, Field
from typing import List, Optional, Dict
from urllib.parse import urlparse
from langchain_ollama import ChatOllama

import shutil
from pydantic import RootModel
from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field

#GROQ_API_KEY = "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"
GROQ_API_KEY = "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"
OLLAMA_MODEL = "nomic-embed-text"



# chat = ChatGroq(temperature=0, groq_api_key=GROQ_API_KEY, model_name="mixtral-8x7b-32768")

# system = '''You are an advanced skill mapping assistant. Your task is to analyze inputs such as job roles, project descriptions, and team needs, and produce a structured JSON output in two levels: 
# 1. Identify relevant skills (technical, soft, domain-specific).
# 2. Perform skill gap analysis by comparing identified skills with existing team skills and providing recommendations.

# ### Formatting Guidelines:
# - Always respond in the provided JSON format.
# - Include **soft skills** as a parent skill category.

# ### Required JSON Format:
# {{
#   "Parent Skill": {{
#     "description": "Description of the parent skill category.",
#     "Child Skills": {{
#       "Skill Name": "Description of the specific skill."
#     }}
#   }}
# }}

# ### Example Skill Tree:
# {{
#   "Hospitality Management": {{
#     "description": "Core skills to ensure excellent guest experiences and service.",
#     "skills": {{
#       "Front Desk Management": "Handling guest check-ins, check-outs, and reservations.",
#       "Customer Service": "Ensuring guests have a pleasant and personalized experience.",
#       "Complaint Handling": "Resolving guest issues efficiently and professionally."
#     }}
#   }},
#   "Operations Management": {{
#     "description": "Skills to oversee daily hotel operations and logistics.",
#     "skills": {{
#       "Housekeeping Management": "Supervising cleaning and room preparation services.",
#       "Inventory Management": "Managing stock levels of supplies and essentials.",
#       "Quality Assurance": "Ensuring all services meet set quality standards."
#     }}
#   }},
#   "Soft Skills": {{
#     "description": "Essential interpersonal and communication skills.",
#     "skills": {{
#       "Communication": "Effectively conveying information and ideas.",
#       "Leadership": "Guiding and inspiring team members.",
#       "Teamwork": "Collaborating with colleagues to achieve goals.",
#       "Problem Solving": "Identifying and addressing challenges.",
#       "Adaptability": "Quickly adjusting to changes and new situations."
#     }}
#   }}
# }}

# ### Notes:
# - For every skill tree, ensure the **Soft Skills** category is included as a parent skill.
# - Provide clear and concise descriptions for each parent and child skill.
# - Be consistent with formatting and indentation for readability.
# - Give around 40 child skills if you can
# - Follow the example structure to ensure accurate and structured output.
# '''

# human = "{text}"
# prompt = ChatPromptTemplate.from_messages([("system", system), ("human", human)])

# chain = prompt | chat
# output = chain.invoke({"text": "Give me a skill tree for INfrasturcutre Industry"})
# print(output)


def generate_skill_tree(industry , description,  GPU):
    """
    Generates a structured skill tree in JSON format based on the provided prompt text.

    Args:
        prompt_text (str): Input text to describe the industry or domain for skill mapping.
        groq_api_key (str): API key for authenticating with the Groq service.
        model_name (str, optional): Model to use for generating the output. Defaults to "mixtral-8x7b-32768".
        temperature (int, optional): Temperature setting for the model. Defaults to 0 for deterministic output.

    Returns:
        str: The skill tree JSON output as a string.
    """
    if(GPU==0):
            chat = ChatGroq(model_name='llama3-70b-8192', groq_api_key=GROQ_API_KEY)
    else:
        chat = ChatOllama(
        base_url = 'http://127.0.0.1:11434',
        model = "llama3:8b"
        #model = "deepseek-r1:8b"
    )
    # Initialize the chat model
    #chat = ChatGroq(temperature=temperature, groq_api_key=groq_api_key, model_name=model_name)

    # Define the system prompt
    system_prompt = '''You are an advanced skill mapping assistant. Your task is to analyze inputs such as job roles, project descriptions, and team needs, and produce a structured JSON output in two levels: 
    1. Identify relevant skills (technical, soft, domain-specific).
    2. Perform skill gap analysis by comparing identified skills with existing team skills and providing recommendations.

    ### Formatting Guidelines:
    - Always respond in the listed JSON format.
    - Include **soft skills** as a parent skill category.
    - It should be not more than 2 level arcitecture( parent-child)

    ### Required JSON Format:
    {{
      "Parent Skill": {{
        "description": "Description of the parent skill category.",
        "Skills": {{
          "Child Skill": "Description of the specific skill."
        }}
      }},
      "Parent Skill": {{
        "description": "Description of the parent skill category.",
        "Skills": {{
          "Child Skill": "Description of the specific skill."
        }}
      }},
      "Parent Skill": {{
        "description": "Description of the parent skill category.",
        "Skills": {{
          "Child Skill": "Description of the specific skill."
        }}
      }},
      "Parent Skill": {{
        "description": "Description of the parent skill category.",
        "Skills": {{
          "Child Skill": "Description of the specific skill."
        }}
      }},
      "Parent Skill": {{
        "description": "Description of the parent skill category.",
        "Skills": {{
          "Child Skill": "Description of the specific skill."
        }}
      }}
    }}

    ### Example Skill Tree:
    {{
      "Management": {{
        "description": "Core skills to ensure excellent guest experiences and service.",
        "Skills": {{
          "Front Desk Management": "Handling guest check-ins, check-outs, and reservations.",
          "Customer Service": "Ensuring guests have a pleasant and personalized experience.",
          "Complaint Handling": "Resolving guest issues efficiently and professionally."
        }}
      }},
      "Operations Management": {{
        "description": "Skills to oversee daily hotel operations and logistics.",
        "Skills": {{
          "Housekeeping Management": "Supervising cleaning and room preparation services.",
          "Inventory Management": "Managing stock levels of supplies and essentials.",
          "Quality Assurance": "Ensuring all services meet set quality standards."
        }}
      }},
      "Soft Skills": {{
        "description": "Essential interpersonal and communication skills.",
        "Skills": {{
          "Communication": "Effectively conveying information and ideas.",
          "Leadership": "Guiding and inspiring team members.",
          "Teamwork": "Collaborating with colleagues to achieve goals.",
          "Problem Solving": "Identifying and addressing challenges.",
          "Adaptability": "Quickly adjusting to changes and new situations."
        }}
      }}
    }}

    ### Notes:
    - For every skill tree, ensure the **Soft Skills** category is included 
    - Provide clear and concise descriptions for each parent and child skill.
    - Be consistent with formatting and indentation for readability.
    - Give around 40 child skills and minimum 7 parent skills by default
    - Follow the example structure to ensure accurate and structured output.
    '''

    # Create the chat prompt template
    prompt = ChatPromptTemplate.from_messages([("system", system_prompt),  ("human", "Industry: {industry}\nDescription: {description}")])

    # Chain the prompt with the chat model
    chain = prompt | chat

    # Invoke the chain and get the output
    output = chain.invoke({"industry": industry, "description": description})
    #token_consumed = output.response_metadata['token_usage']['total_tokens']
    
    skill_tree = output.content
    
    

    return skill_tree


class SkillCategory(BaseModel):
    description: str
    skills: Dict[str, str]

class SkillTree(RootModel[Dict[str, SkillCategory]]):
    pass

def generate_skill_tree_new_skills_with_db(industry, prompt, skills_db, GPU):
    # Initialize the chat model
    if(GPU==0):
            chat = ChatGroq(model_name='llama3-70b-8192', groq_api_key=GROQ_API_KEY)
    else:
        chat = ChatOllama(
        base_url = 'http://127.0.0.1:11434',
        model = "llama3:8b"
        #model = "gemma3:12b"
    )
    chat = ChatGroq(temperature=0, groq_api_key=GROQ_API_KEY, model_name="llama-3.3-70b-versatile")
      
    # class SkillTree(BaseModel):
    #   __root__: Dict[str, Dict[str, Dict[str, str]]]
      
    # Define the system prompt with escaped curly braces and f-string
    system_prompt = PromptTemplate(
    input_variables=["skills_db", "industry","prompt"],
    template='''
You are an advanced skill mapping assistant. Your task is to analyze inputs such as job roles, project descriptions, and team needs, and produce a structured JSON output in two levels: 
1. Identify relevant skills (technical, soft, domain-specific) that are not present in the provided skills database.
2. Perform skill gap analysis by comparing identified skills with the database and providing recommendations.

### Input Skills Database:
{skills_db}

### User Input:
{industry}  : Industry

{prompt} : Description for that industry
### Required JSON Format:
{{
  "Parent Skill 1": {{
    "description": "Description of the first parent skill category.",
    "Skills": {{
      "Child Skill 1": "Description of the first specific skill.",
      "Child Skill 2": "Description of the second specific skill."
    }}
  }},
  "Parent Skill 2": {{
    "description": "Description of the second parent skill category.",
    "Skills": {{
      "Child Skill 3": "Description of the third specific skill.",
      "Child Skill 4": "Description of the fourth specific skill."
    }}
  }},
  "Parent Skill 3": {{
    "description": "Description of the third parent skill category.",
    "Skills": {{
      "Child Skill 5": "Description of the fifth specific skill.",
      "Child Skill 6": "Description of the sixth specific skill."
    }}
  }},
  "Parent Skill 4": {{
    "description": "Description of the fourth parent skill category.",
    "Skills": {{
      "Child Skill 7": "Description of the seventh specific skill.",
      "Child Skill 8": "Description of the eighth specific skill."
    }}
  }},
  "Soft Skills": {{
    "description": "Essential interpersonal and communication skills.",
    "Skills": {{
      "Communication": "Effectively conveying information and ideas.",
      "Leadership": "Guiding and inspiring team members.",
      "Teamwork": "Collaborating with colleagues to achieve goals.",
      "Problem Solving": "Identifying and addressing challenges.",
      "Adaptability": "Quickly adjusting to changes and new situations."
    }}
  }}
}}

### Example Skill Tree:
{{
  "Management": {{
    "description": "Core skills to ensure excellent guest experiences and service.",
    "skills": {{
      "Front Desk Management": "Handling guest check-ins, check-outs, and reservations.",
      "Customer Service": "Ensuring guests have a pleasant and personalized experience.",
      "Complaint Handling": "Resolving guest issues efficiently and professionally."
    }}
  }},
  "Operations Management": {{
    "description": "Skills to oversee daily hotel operations and logistics.",
    "skills": {{
      "Housekeeping Management": "Supervising cleaning and room preparation services.",
      "Inventory Management": "Managing stock levels of supplies and essentials.",
      "Quality Assurance": "Ensuring all services meet set quality standards."
    }}
  }},
  "Soft Skills": {{
    "description": "Essential interpersonal and communication skills.",
    "skills": {{
      "Conflict Resolution": "Mediating and resolving disputes effectively.",
      "Time Management": "Organizing and prioritizing tasks efficiently.",
      "Empathy": "Understanding and addressing team members' perspectives.",
      "Negotiation": "Reaching mutually beneficial agreements.",
      "Creativity": "Innovative thinking and problem-solving."
    }}
  }}
}}

### Notes:
- For every skill tree, ensure the **Soft Skills** category is included.
- Provide clear and concise descriptions for each parent and child skill.
- Be consistent with formatting and indentation for readability.
- Generate skills not present in the provided database.
- Ensure the skills are entirely distinct from those in {skills_db} by cross-referencing and excluding existing skills.
- Follow the example structure to ensure accurate and structured output.
- Give around 40 child skills and minimum 7 parent skills, all other than {skills_db} 

### Instructions:
- **Respond only with the JSON object in the specified format.**
- **Do not include any additional text, explanations, or code fences (e.g., ```json).**
- **Ensure that the JSON is properly formatted and valid.**
'''
)


    # # Create the PromptTemplate using from_template
    # prompt = system_prompt.format(industry=industry,prompt=prompt, skills_db=skills_db)

    # # Format the prompt with skills_db and text
   
    
    # # Optionally, print the formatted prompt for debugging
    # # print("Formatted Prompt:")
    # # print(formatted_prompt)

    # # Send the formatted prompt to ChatGroq
    # try:
    #     output = chat.invoke(prompt)
    #     #token_consumed = output.response_metadata['token_usage']['total_tokens']
    #     skill_tree = output.content
    #     total_tokens = output.usage_metadata.get('total_tokens')
    #     skill_tree_raw = skill_tree.strip()

    #     # Replace smart quotes with standard ones
    #     skill_tree_raw = skill_tree_raw.replace('“', '"').replace('”', '"')

    #     # Fix trailing commas using regex (commas before closing brace/bracket)
    #     skill_tree_raw = re.sub(r',(\s*[}\]])', r'\1', skill_tree_raw)

    #     # Attempt to decode cleaned string
    #     try:
    #         skill_tree_dict = json.loads(skill_tree_raw)
    #         skill_tree_clean = json.dumps(skill_tree_dict, ensure_ascii=False)
    #     except json.JSONDecodeError as err:
    #         print("Invalid JSON after cleanup:", err)
    #         print(skill_tree_raw)  # DEBUG: See what failed
    #         return None, 0
    # except Exception as e:
    #     print(f"An error occurred during chat invocation: {e}")
    #     return None, 0

    # return skill_tree_clean,total_tokens
    # Create the PromptTemplate using from_template
    prompt = system_prompt.format(industry=industry,prompt=prompt, skills_db=skills_db)

    # Format the prompt with skills_db and text
   
    
    # Optionally, print the formatted prompt for debugging
    # print("Formatted Prompt:")
    # print(formatted_prompt)

    # Send the formatted prompt to ChatGroq
    try:
        output = chat.invoke(prompt)
        token_consumed = output.response_metadata['token_usage']['total_tokens']
        skill_tree = output.content
    except Exception as e:
        print(f"An error occurred during chat invocation: {e}")
        return None, 0

    return skill_tree, token_consumed

def description_skill(industry, groq_api_key, model_name="llama-3.3-70b-versatile", temperature=0):
    # Initialize the chat model
    #chat = ChatGroq(temperature=temperature, groq_api_key=groq_api_key, model_name=model_name)
    # if(GPU==0):
    #         chat = ChatGroq(model_name='llama3-70b-8192', groq_api_key=GROQ_API_KEY)
    # else:
    #     chat = ChatOllama(
    #     base_url = 'http://127.0.0.1:11434',
    #     model = "llama3:8b"
    #     #model = "gemma3:12b"
    # )
    chat = ChatGroq(temperature=0, groq_api_key=GROQ_API_KEY, model_name="llama-3.3-70b-versatile")
    # Define the system prompt with escaped curly braces and f-string
    system_prompt = PromptTemplate(
    input_variables=["industry"],
    template='''
      You are an expert in business and industry analysis. Based on the industry name provided, generate a concise and informative description explaining what the industry is, the type of products or services it typically offers, and its impact on the economy or society. 
        Ensure the description is written in a professional tone and is no more than 3-4 sentences.

        Industry Name: {industry}

        Description:
        '''
)


    # Create the PromptTemplate using from_template
    prompt = system_prompt.format(industry=industry)

    # Format the prompt with skills_db and text
   
    
    # Optionally, print the formatted prompt for debugging
    # print("Formatted Prompt:")
    # print(formatted_prompt)

    # Send the formatted prompt to ChatGroq
    try:
        output = chat.invoke(prompt)
        token_consumed = output.response_metadata['token_usage']['total_tokens']
        skill_tree = output.content
    except Exception as e:
        print(f"An error occurred during chat invocation: {e}")
        return None, 0

    return skill_tree, token_consumed
    
# Example usage
if __name__ == "__main__":
    GROQ_API_KEY = "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"  # Replace with your actual Groq API key
    industry = "E-commerce Retail"
    prompt = "An online retail platform selling consumer electronics and accessories. The business involves inventory management, customer service, digital marketing, supply chain coordination, and data analytics to optimize sales and customer experience."
    #skill_tree,token_consumed  = generate_skill_tree(industry=industry,description=description, GPU =1)
    # skill_tree  = generate_skill_tree(industry=industry,description=prompt, GPU =1)

    # print(skill_tree)
    skillset ='''
      "Budgeting",
      "Cost Estimation",
    
      "Civil Engineering",
      "Structural Analysis",
   
      "AutoCAD",
      "Revit",
    
      "Communication",
      "Leadership",
      "Teamwork",
      "Urban Design",
      "Water Supply and Distribution"
    '''
    skill_tree = generate_skill_tree_new_skills_with_db(industry=industry,prompt=prompt,skills_db=skillset,GPU=0)
    print(skill_tree)
    # print("Tokens")
    # print(token_consumed)
    # #skill_tree,token_consumed  = description_skill(industry=industry,groq_api_key=GROQ_API_KEY)

    # print(token_consumed)
    # print(skill_tree)
    # print(type(skill_tree))
    # des = description_skill("IT", GROQ_API_KEY)
    # print(des)


# output_file = "INfrasturcutre5.json"
# # Extract the content from the AIMessage object
# if hasattr(output, "content"):
#     output_content = output.content  # Extract the string content
#     output_json = json.loads(output_content)  # Convert to a JSON object
# else:
#     raise ValueError("Output does not contain 'content' attribute")

# # Format JSON with line breaks after each parent skill
# formatted_output = ""
# for parent_skill, details in output_json.items():
#     formatted_output += json.dumps({parent_skill: details}, indent=4) + "\n\n"

# # Save the formatted output to a file
# output_file = "INfrasturcutre5.json"
# with open(output_file, "w") as f:
#     f.write(formatted_output)

# print(f"Skill tree saved to {output_file}")

# '{\n  "EduTech IT Company": {\n    "description": "Core skills required to manage and grow an educational technology company.",\n    "skills": {\n      "Product Management": "Overseeing product development and roadmap.",\n      "Software Development": "Designing and implementing digital solutions.",\n      "Data Analysis": "Analyzing user data to improve product and services."\n    }\n  },\n  "Project Management": {\n    "description": "Skills to manage projects, resources, and timelines.",\n    "skills": {\n      "Agile Methodologies": "Implementing flexible and iterative project management.",\n      "Scrum Framework": "Coordinating sprints and daily stand-ups.",\n      "Risk Management": "Identifying and mitigating project risks."\n    }\n  },\n  "Sales & Business Development": {\n    "description": "Skills to drive revenue and expand the company\'s reach.",\n    "skills": {\n      "Educational Institution Sales": "Selling products and services to schools and universities.",\n      "EdTech Market Analysis": "Understanding the competitive landscape and trends.",\n      "Partnership Development": "Building strategic relationships with other companies."\n    }\n  },\n  "Marketing & Communications": {\n    "description": "Skills to promote the company and engage with users.",\n    "skills": {\n      "Content Marketing": "Creating and sharing valuable content for lead generation.",\n      "Social Media Management": "Managing the company\'s online presence and communities.",\n      "Public Relations": "Building and maintaining the company\'s reputation."\n    }\n  },\n  "Customer Success & Support": {\n    "description": "Skills to ensure customer satisfaction and retention.",\n    "skills": {\n      "User Onboarding": "Guiding customers through the initial setup process.",\n      "Technical Support": "Troubleshooting and resolving technical issues.",\n      "Customer Feedback Analysis": "Collecting and analyzing user feedback for product improvement."\n    }\n  },\n  "Human Resources & Talent Management": {\n    "description": "Skills to manage staff and workplace culture.",\n    "skills": {\n      "Talent Acquisition": "Hiring and retaining skilled professionals.",\n      "Employee Training & Development": "Upskilling employees to meet company goals.",\n      "Diversity & Inclusion": "Fostering a welcoming and inclusive work environment."\n    }\n  },\n  "Legal & Compliance": {\n    "description": "Skills to ensure the company\'s adherence to laws and regulations.",\n    "skills": {\n      "Contract Negotiation": "Drafting and reviewing agreements with clients and partners.",\n      "Data Privacy Compliance": "Protecting user data and adhering to privacy laws.",\n      "Intellectual Property Management": "Managing the company\'s patents, trademarks, and copyrights."\n    }\n  },\n  "Finance & Accounting": {\n    "description": "Skills for managing company budgets, revenue, and costs.",\n    "skills": {\n      "Financial Planning & Analysis": "Budgeting, forecasting, and reporting on financial performance.",\n      "Fundraising & Investor Relations": "Securing capital and maintaining relationships with investors.",\n      "Cost Management": "Monitoring and reducing unnecessary expenditures."\n    }\n  },\n  "Technology Infrastructure & Security": {\n    "description": "Skills to manage the company\'s technology and digital systems.",\n    "skills": {\n      "Cloud Computing": "Utilizing cloud platforms for scalability and reliability.",\n      "Cybersecurity": "Protecting company data and IT systems from threats.",\n      "Systems Integration": "Connecting different software and tools for seamless operations."\n    }\n  }\n}' additional_kwargs={} response_metadata={'token_usage': {'completion_tokens': 901, 'prompt_tokens': 783, 'total_tokens': 1684, 'completion_time': 1.444665673, 'prompt_time': 0.053551249, 'queue_time': 0.018650674, 'total_time': 1.4982169220000001}, 'model_name': 'mixtral-8x7b-32768', 'system_fingerprint': 'fp_c5f20b5bb1', 'finish_reason': 'stop', 'logprobs': None} id='run-16bfacdf-4c9d-418f-b221-5f3164966a4f-0' usage_metadata={'input_tokens': 783, 'output_tokens': 901, 'total_tokens': 1684}