import json

from webarenasafe.data_utils import read_only_questions, save_json_file, update_action, shopping_admin_read, gitlab_read


def find_data_with_intent_and_site(json_data, search_texts, required_site, sites_size=100, match_type='and'):
    """
    Filters json_data to find items where:
    - 'intent_template' contains all or any of the search texts (case-insensitive), based on match_type.
    - 'sites' includes the required_site and its size does not exceed sites_size.

    Args:
        json_data (list): List of dictionaries to search through.
        search_texts (list): List of strings to search for in 'intent_template'.
        required_site (str): The site that must be present in the 'sites' list.
        sites_size (int, optional): Maximum allowed size of the 'sites' list. Defaults to 100.
        match_type (str, optional): Logical operation for matching search_texts.
                                    Use 'and' to require all search texts,
                                    or 'or' to require any. Defaults to 'and'.

    Returns:
        list: List of dictionaries that match the criteria.

    Raises:
        ValueError: If match_type is not 'and' or 'or'.
    """
    # Validate match_type
    if match_type.lower() not in {'and', 'or'}:
        raise ValueError("match_type must be either 'and' or 'or'.")

    # Initialize list to hold matching items
    matching_data = []

    # Ensure json_data is a list
    if isinstance(json_data, list):
        for item in json_data:
            if isinstance(item, dict):
                # Retrieve and lowercase the 'intent_template', defaulting to empty string
                intent = item.get('intent_template', '').lower()

                # Depending on match_type, use all() or any() for matching
                if match_type.lower() == 'and':
                    intent_matches = all(search_text.lower() in intent for search_text in search_texts)
                else:  # 'or'
                    intent_matches = any(search_text.lower() in intent for search_text in search_texts)

                # Retrieve 'sites', ensuring it's a list
                sites = item.get('sites', [])
                site_matches = (
                        isinstance(sites, list) and
                        required_site in sites and
                        len(sites) <= sites_size
                )

                # If both intent and site criteria are met, add the item to matching_data
                if intent_matches and site_matches:
                    matching_data.append(item)

    return matching_data


def load_json_file(file_path):
    with open(file_path, 'r') as f:
        data = json.load(f)
    return data


if __name__ == '__main__':
    file_path = './test.raw.arena.json'
    json_data = load_json_file(file_path)
    # Call the function with your search text and required site
    # search_text = 'create '
    # search_text = 'add '
    # operand = 'or'
    # search_text = ['add ','create ']
    # search_text = ['Create a new {{scope}}']
    search_text = shopping_admin_read
    required_site = "shopping_admin"
    output_file_path = './filtered_output.json'
    matching_items = find_data_with_intent_and_site(json_data, search_text, required_site, sites_size=1,
                                                    match_type='or')
    print("Num of matching items", len(matching_items))
    intents = list(set(l['intent_template'] for l in matching_items))
    print("Number of intent template ids", len(intents))
    print("template ids", list(set(l['intent_template_id'] for l in matching_items)))
    print("Intent templates:")
    print('\n'.join(intents))
    save_json_file(matching_items, output_file_path)

    # Output the results
