import json
import os
from typing import List, Dict
from config import get_config

config = get_config()

class RecipeSearchService:
    
    def __init__(self):
        self.recipes = self._load_sample_recipes()
    
    def _load_sample_recipes(self) -> List[Dict]:

        return [
            {
                "id": 1,
                "title": "Classic Tomato Pasta",
                "ingredients": ["pasta", "tomato", "garlic", "olive oil", "basil"],
                "instructions": "Boil pasta. Sauté garlic in olive oil. Add tomatoes. Combine with pasta. Top with basil.",
                "meal_type": "lunch",
                "cooking_time": 25,
                "servings": 4,
                "difficulty": "easy"
            },
            {
                "id": 2,
                "title": "Grilled Chicken Salad",
                "ingredients": ["chicken", "lettuce", "tomato", "cucumber", "olive oil", "lemon"],
                "instructions": "Grill chicken. Chop vegetables. Mix with olive oil and lemon. Serve.",
                "meal_type": "lunch",
                "cooking_time": 30,
                "servings": 2,
                "difficulty": "easy"
            },
            {
                "id": 3,
                "title": "Mushroom Risotto",
                "ingredients": ["rice", "mushroom", "onion", "garlic", "broth", "parmesan"],
                "instructions": "Sauté onion and garlic. Add rice. Gradually add broth. Stir in mushrooms and parmesan.",
                "meal_type": "dinner",
                "cooking_time": 40,
                "servings": 3,
                "difficulty": "medium"
            },
            {
                "id": 4,
                "title": "Vegetable Stir Fry",
                "ingredients": ["broccoli", "carrot", "bell pepper", "soy sauce", "garlic", "ginger"],
                "instructions": "Heat oil. Stir fry vegetables. Add soy sauce and ginger. Serve hot.",
                "meal_type": "dinner",
                "cooking_time": 20,
                "servings": 2,
                "difficulty": "easy"
            },
            {
                "id": 5,
                "title": "Pancakes",
                "ingredients": ["flour", "egg", "milk", "baking powder", "butter", "maple syrup"],
                "instructions": "Mix dry ingredients. Add wet ingredients. Cook on griddle. Serve with syrup.",
                "meal_type": "breakfast",
                "cooking_time": 20,
                "servings": 4,
                "difficulty": "easy"
            }
        ]
    
    def search_by_ingredients(self, ingredients: List[str], limit: int = None) -> List[Dict]:
        """
        Search recipes by ingredients
        
        Args:
            ingredients (list): List of ingredients to search
            limit (int): Maximum number of results
        
        Returns:
            list: Matching recipes sorted by relevance
        """
        if limit is None:
            limit = config.MAX_SEARCH_RESULTS
        
        # Convert search ingredients to lowercase
        search_ingredients = [ing.lower() for ing in ingredients]
        
        # Score recipes based on ingredient matches
        scored_recipes = []
        for recipe in self.recipes:
            recipe_ingredients = [ing.lower() for ing in recipe['ingredients']]
            matches = sum(1 for ing in search_ingredients if any(ing in r_ing for r_ing in recipe_ingredients))
            
            if matches > 0:
                scored_recipes.append({
                    'recipe': recipe,
                    'score': matches
                })
        
        # Sort by score (descending) and return top results
        scored_recipes.sort(key=lambda x: x['score'], reverse=True)
        return [item['recipe'] for item in scored_recipes[:limit]]
    
    def search_by_meal_type(self, meal_type: str, limit: int = None) -> List[Dict]:

        if limit is None:
            limit = config.MAX_SEARCH_RESULTS
        
        results = [r for r in self.recipes if r['meal_type'].lower() == meal_type.lower()]
        return results[:limit]
    
    def search_by_cooking_time(self, max_time: int, limit: int = None) -> List[Dict]:
  
        if limit is None:
            limit = config.MAX_SEARCH_RESULTS
        
        results = [r for r in self.recipes if r['cooking_time'] <= max_time]
        return results[:limit]
    
    def search_by_difficulty(self, difficulty: str, limit: int = None) -> List[Dict]:
    
        if limit is None:
            limit = config.MAX_SEARCH_RESULTS
        
        results = [r for r in self.recipes if r['difficulty'].lower() == difficulty.lower()]
        return results[:limit]
    
    def advanced_search(self, ingredients: List[str] = None, meal_type: str = None,
                       max_cooking_time: int = None, difficulty: str = None,
                       limit: int = None) -> List[Dict]:

        if limit is None:
            limit = config.MAX_SEARCH_RESULTS
        
        results = self.recipes.copy()

        if ingredients:
            search_ingredients = [ing.lower() for ing in ingredients]
            results = [r for r in results if any(
                any(ing in r_ing.lower() for r_ing in r['ingredients'])
                for ing in search_ingredients
            )]
        if meal_type:
            results = [r for r in results if r['meal_type'].lower() == meal_type.lower()]
        if max_cooking_time:
            results = [r for r in results if r['cooking_time'] <= max_cooking_time]
    
        if difficulty:
            results = [r for r in results if r['difficulty'].lower() == difficulty.lower()]
        
        return results[:limit]
    
    def get_recipe_by_id(self, recipe_id: int) -> Dict:
        for recipe in self.recipes:
            if recipe['id'] == recipe_id:
                return recipe
        return None


search_service = None

def get_search_service() -> RecipeSearchService:
    global search_service
    if search_service is None:
        search_service = RecipeSearchService()
    return search_service