<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Recipe;
use App\Dish;
use App\UsersQuestion;
use Illuminate\Validation\ValidationException;

class RecipeController extends Controller
{
    // Store a new recipe
    public function store(Request $request)
    {

        try {
            // Validate the request data
            $validated = $request->validate([
                'title' => 'required|string|max:255',
                'description' => 'required|string',
                'ingredients' => 'required|json',
            ]);

            // Create a new recipe instance
            $recipe = new Recipe();
            $recipe->title = $validated['title'];
            $recipe->description = $validated['description'];
            $recipe->ingredients = $validated['ingredients'];

            // Save the recipe to the database
            $recipe->save();

            // Return a success response with the created recipe
            return response()->json([
                'message' => 'Recipe created successfully',
                'recipe' => $recipe
            ], 201);

        } catch (ValidationException $e) {
            // Return a JSON response with the validation errors
            return response()->json([
                'message' => 'Validation failed',
                'errors' => $e->errors(),
            ], 422);
        }  }

    // Get all recipes
    public function index()
    {
        $recipes = Recipe::all();

        if ($recipes->isEmpty()) {
            return response()->json([], 204);
        }

        return response()->json($recipes, 200);
    }

    // Get a single recipe by title
    public function show($title)
    {
        $recipe = Recipe::where('title', $title)->first();

    if (!$recipe) {
        return response()->json([
            'message' => 'Recipe not found'
        ], 404);
    }

    return response()->json($recipe, 200);
    }
    
     // ===================== DISHES FUNCTIONS =====================

    // Store a new dish in the dishes table
    public function storeDish(Request $request)
    {
        try {
             // Validate request data
        $validatedData = $request->validate([
            'name' => 'required|string|max:255',
            'image_url' => 'nullable|url',
            'cuisine' => 'nullable|string|max:100',
            'diets' => 'nullable|array',
            'flavour_profile' => 'nullable|array',
            'dish_type' => 'nullable|array',
            'dish_complexity' => 'nullable|string',
            'cooking_time' => 'nullable|integer|min:0',
            'cooking_style' => 'nullable|array',
            'mood' => 'nullable|array',
            'cooking_equipment' => 'nullable|array',
            'cultural' => 'nullable|array',
            'ingredients' => 'nullable|array',
            'scanned_ingredients' => 'nullable|array',
            'min_calories' => 'nullable|integer|min:0',
            'max_calories' => 'nullable|integer|min:0',
            'calories' => 'nullable|integer|min:0',
            'instructions' => 'nullable|string',
        ]);
        


        // Create a new recipe
        $dish = Dish::create([
            'name' => $validatedData['name'],
            'image_url' => $validatedData['image_url'] ?? null,
            'cuisine' => $validatedData['cuisine'] ?? null,
            'diets' => json_encode($validatedData['diets'] ?? []),
            'flavour_profile' => json_encode($validatedData['flavour_profile'] ?? []),
            'dish_type' => json_encode($validatedData['dish_type'] ?? []),
            'dish_complexity' => $validatedData['dish_complexity'] ?? null,
            'cooking_time' => $validatedData['cooking_time'] ?? null,
            'cooking_style' => json_encode($validatedData['cooking_style'] ?? []),
            'mood' => json_encode($validatedData['mood'] ?? []),
            'cooking_equipment' => json_encode($validatedData['cooking_equipment'] ?? []),
            'cultural' => json_encode($validatedData['cultural'] ?? []),
            'ingredients' => json_encode($validatedData['ingredients'] ?? []),
            'scanned_ingredients' => json_encode($validatedData['scanned_ingredients'] ?? []),
            'min_calories' => $validatedData['min_calories'] ?? null,
            'max_calories' => $validatedData['max_calories'] ?? null,
            'calories' => $validatedData['calories'] ?? null,
            'instructions' => $validatedData['instructions'] ?? null,
        ]);

            return response()->json([
                'message' => 'Dish created successfully',
                'dish' => $dish
            ], 201);
        } catch (ValidationException $e) {
            return response()->json([
                'message' => 'Validation failed',
                'errors' => $e->errors(),
            ], 422);
        }
    }

    public function getDishes(Request $request)
    {
        $query = Dish::query();

        // 1. Filter by Cuisine
        if ($request->has('cuisine')) {
            $query->where('cuisine', $request->cuisine);
        }

        // 2. Filter by Diets
        if ($request->has('diets')) {
            $query->whereJsonContains('diets', $request->diets);
        }

        // 3. Filter by Flavour Profile
        if ($request->has('flavourProfile')) {
            $query->whereJsonContains('flavour_profile', $request->flavourProfile);
        }

        // 4. Filter by Dish Type
        if ($request->has('dishType')) {
            $query->whereJsonContains('dish_type', $request->dishType);
        }

        // 5. Filter by Dish Complexity
        if ($request->has('dishComplexity')) {
            $query->where('dish_complexity', $request->dishComplexity);
        }

        // 6. Filter by Cooking Time
        if ($request->has('cookingTime')) {
            $query->where('cooking_time', '<=', $request->cookingTime);
        }

        // 7. Filter by Cooking Style
        if ($request->has('cookingStyle')) {
            $query->whereJsonContains('cooking_style', $request->cookingStyle);
        }

        // 8. Filter by Mood
        if ($request->has('mood')) {
            $query->whereJsonContains('mood', $request->mood);
        }

        // 9. Filter by Cooking Equipment
        if ($request->has('cookingEquipment')) {
            $query->whereJsonContains('cooking_equipment', $request->cookingEquipment);
        }

        // 10. Filter by Cultural Association
        if ($request->has('cultural')) {
            $query->whereJsonContains('cultural', $request->cultural);
        }

        // 11. *Filter by Ingredients*
        if ($request->has('ingredients')) {
            $query->whereJsonContains('ingredients', $request->ingredients);
        }

        // 12. *Filter by Scanned Ingredients*
        // if ($request->has('scanned_ingredients')) {
        //     $query->whereJsonContains('scanned_ingredients', $request->scanned_ingredients);
        // }
        
        // if ($request->has('scanned_ingredients')) {
        //     // $query->whereJsonContains('scanned_ingredients', $request->scanned_ingredients);
        
        // // Convert the request input to a JSON string
        // $ingredientsJson = json_encode($request->scanned_ingredients);
    
        // // Check for exact match on the JSON column
        // $query->where('scanned_ingredients', $ingredientsJson);
        // }
        
        if ($request->has('scanned_ingredients')) {
    $inputIngredients = $request->scanned_ingredients;

    // Sort the input ingredients array
    sort($inputIngredients);

    // Convert sorted array to JSON string
    $sortedInputIngredientsJson = json_encode($inputIngredients);

    // Filter results
    $query->whereRaw('JSON_LENGTH(scanned_ingredients) = ?', [count($inputIngredients)])
          ->whereRaw('JSON_CONTAINS(scanned_ingredients, ?)', [$sortedInputIngredientsJson]);
}

        // 13. Filter by Calories Range
        // If 'calories' is provided, filter based on that
        if ($request->has('calories')) {
            $query->where('calories', '=', $request->calories);
        }

        // Alternatively, use min_calories and max_calories for range filtering
        if ($request->has('minCalories') && $request->has('maxCalories')) {
            $query->whereBetween('calories', [$request->minCalories, $request->maxCalories]);
        } elseif ($request->has('minCalories')) {
            $query->where('calories', '>=', $request->minCalories);
        } elseif ($request->has('maxCalories')) {
            $query->where('calories', '<=', $request->maxCalories);
        }

        // *Additional Filters* (if any)
        // Add more filters here as needed

        // Paginate the results
        $dishes = $query->paginate(10); // 10 dishes per page
        
        // $dishes = $query->simplePaginate(10); // 10 dishes per page

        
        

        if ($dishes->isEmpty()) {
            return response()->json([
                'message' => 'No dishes found'
            ], 204);
        }

        return response()->json([
            'data' => $dishes->items(),
            'pagination' => [
                'current_page' => $dishes->currentPage(),
                'total_pages' => $dishes->lastPage(),
                'total_items' => $dishes->total(),
            ]
        ], 200);
    }
    
    public function searchDishes(Request $request)
{
    $query = Dish::query();

    // ✅ 1. Try to find by Name (partial match, contains)
    if ($request->filled('keyword')) {
        $nameQuery = clone $query;
        $nameQuery->where('name', 'LIKE', '%' . $request->keyword . '%');

        $nameResults = $nameQuery->paginate($request->get('per_page', 10));

        if ($nameResults->total() > 0) {
            return response()->json([
                'data' => $nameResults->items(),
                'pagination' => [
                    'current_page' => $nameResults->currentPage(),
                    'total_pages' => $nameResults->lastPage(),
                    'total_items' => $nameResults->total(),
                    'per_page' => $nameResults->perPage(),
                ]
            ], 200);
        }

        // ✅ 2. If no name match → search in Ingredients JSON
        $query->whereJsonContains('ingredients', $request->keyword);
    }

    // 🌍 Apply Filters (cuisine, diets, etc.)
    if ($request->filled('cuisine')) {
        $query->where('cuisine', $request->cuisine);
    }
    if ($request->filled('diets')) {
        $query->whereJsonContains('diets', $request->diets);
    }
    if ($request->filled('dishType')) {
        $query->whereJsonContains('dish_type', $request->dishType);
    }
    if ($request->filled('cultural')) {
        $query->whereJsonContains('cultural', $request->cultural);
    }
    if ($request->filled('flavourProfile')) {
        $query->whereJsonContains('flavour_profile', $request->flavourProfile);
    }
    if ($request->filled('dishComplexity')) {
        $query->where('dish_complexity', $request->dishComplexity);
    }
    if ($request->filled('cookingTime')) {
        $query->where('cooking_time', '<=', $request->cookingTime);
    }
    if ($request->filled('cookingStyle')) {
        $query->whereJsonContains('cooking_style', $request->cookingStyle);
    }
    if ($request->filled('mood')) {
        $query->whereJsonContains('mood', $request->mood);
    }
    if ($request->filled('cookingEquipment')) {
        $query->whereJsonContains('cooking_equipment', $request->cookingEquipment);
    }

    // 🔥 Calories Filter
    if ($request->filled('calories')) {
        $query->where('calories', $request->calories);
    }
    if ($request->filled('minCalories') && $request->filled('maxCalories')) {
        $query->whereBetween('calories', [$request->minCalories, $request->maxCalories]);
    } elseif ($request->filled('minCalories')) {
        $query->where('calories', '>=', $request->minCalories);
    } elseif ($request->filled('maxCalories')) {
        $query->where('calories', '<=', $request->maxCalories);
    }

    // 📄 Pagination (default 10)
    $dishes = $query->paginate($request->get('per_page', 10));

    if ($dishes->isEmpty()) {
        return response()->json([
            'message' => 'No dishes found'
        ], 204);
    }

    return response()->json([
        'data' => $dishes->items(),
        'pagination' => [
            'current_page' => $dishes->currentPage(),
            'total_pages' => $dishes->lastPage(),
            'total_items' => $dishes->total(),
            'per_page' => $dishes->perPage(),
        ]
    ], 200);
}


    // Get a single dish by name
    public function getDish($name)
    {
        $dish = Dish::where('name', $name)->first();

        if (!$dish) {
            return response()->json([
                'message' => 'Dish not found'
            ], 404);
        }

        return response()->json($dish, 200);
    }
    
    public function getRecommendedDishes(Request $request)
{
    $request->validate([
        'user_id' => 'required'
    ]);

    $userQuestions = UsersQuestion::where('user', $request->user_id)
        ->latest()
        ->first();

    if (!$userQuestions) {
        return response()->json([
            'data' => Dish::paginate(10)
        ]);
    }

    // Decode stored JSON
    $raw = json_decode($userQuestions->questions, true);
    $answers = [];

    foreach ($raw as $row) {
        $decode = json_decode($row, true);
        if ($decode && isset($decode['id']) && isset($decode['answer'])) {
            $answers[$decode['id']] = $decode['answer'];
        }
    }

    $query = Dish::query();

    /***********************
     *  DIET FILTER (Q2)
     ***********************/
    $dietMap = [
        "Vegan" => "Vegan",
        "Vegetarian" => "Vegetarian",
        "Pescatarian" => "Pescatarian",
        "Flexitarian" => "Flexitarian",
        "Omnivore (eat everything)" => null, // No filter
        "Gluten-free" => "Gluten-Free",
        "Dairy-free/Lactose intolerant" => "Dairy-Free",
        "Nut allergies" => "Nut-Free",
        "Low-carb/Keto" => "Keto",
    ];

    if (!empty($answers['q2']) && isset($dietMap[$answers['q2']])) {
        $dietTag = $dietMap[$answers['q2']];

        if ($dietTag !== null) {
            $query->whereJsonContains('diets', $dietTag);
        }
    }

    /***********************
     *  COOKING SKILL (Q6)
     ***********************/
    if (!empty($answers['q6'])) {
        $skill = $answers['q6'];

        if (str_contains($skill, 'Beginner')) {
            $query->where(function ($q) {
                $q->where('dish_complexity', 'easy')
                  ->orWhereNull('dish_complexity');
            });
        } elseif (str_contains($skill, 'Intermediate')) {
            $query->where(function ($q) {
                $q->where('dish_complexity', '!=', 'expert')
                  ->orWhereNull('dish_complexity');
            });
        }
    }

    /***********************
     *  TIME AVAILABLE (Q8)
     ***********************/
    if (!empty($answers['q8'])) {
        $time = $answers['q8'];

        if (str_contains($time, 'Less than 15')) {
            $query->where('cooking_time', '<=', 15);
        } elseif (str_contains($time, '15-30')) {
            $query->where('cooking_time', '<=', 30);
        } elseif (str_contains($time, '30-60')) {
            $query->where('cooking_time', '<=', 60);
        }
    }

    /***********************
     *  ALLERGIES (Q7)
     ***********************/
    if (!empty($answers['q7']) && $answers['q7'] !== 'No allergies or restrictions') {
        $allergy = strtolower($answers['q7']);

        if (str_contains($allergy, 'gluten')) {
            $query->whereJsonDoesntContain('ingredients', 'gluten');
        }
        if (str_contains($allergy, 'dairy')) {
            $query->whereJsonDoesntContain('ingredients', 'dairy');
        }
        if (str_contains($allergy, 'nut')) {
            $query->whereJsonDoesntContain('ingredients', 'nuts');
        }
        if (str_contains($allergy, 'keto')) {
            $query->where('carbs', '<=', 15);
        }
    }

    /***********************
     *  CHALLENGE (Q5)
     ***********************/
    if (!empty($answers['q5'])) {
        $challenge = strtolower($answers['q5']);

        if (str_contains($challenge, 'time')) {
            $query->where('cooking_time', '<=', 20);
        }
        if (str_contains($challenge, 'complex')) {
            $query->where(function ($q) {
                $q->where('dish_complexity', 'easy')
                  ->orWhereNull('dish_complexity');
            });
        }
    }

    /***********************
     *  COOKING FREQUENCY (Q1)
     ***********************/
    if (!empty($answers['q1']) && $answers['q1'] === 'Rarely') {
        $query->where('cooking_time', '<=', 20);
    }

    /***********************
     *  FOOD WASTE (Q4)
     ***********************/
    if (!empty($answers['q4']) && str_contains($answers['q4'], 'Multiple')) {
        $query->where('cooking_time', '<=', 20);
    }

    /***********************
     *  MEAL PLANNING (Q9)
     ***********************/
    if (!empty($answers['q9'])) {
        $pref = strtolower($answers['q9']);

        if (str_contains($pref, 'easy')) {
            $query->where(function ($q) {
                $q->where('dish_complexity', 'easy')
                  ->orWhereNull('dish_complexity');
            });
        }
        if (str_contains($pref, 'quick')) {
            $query->where('cooking_time', '<=', 20);
        }
    }

    $filtered = $query->paginate(10);

    if ($filtered->total() === 0) {
        return response()->json([
            'message' => 'No matches found. Showing full list.',
            'data' => Dish::paginate(10)
        ]);
    }

    return response()->json([
        'message' => 'Recommended dishes based on your answers.',
        'data' => $filtered
    ]);
}
}
