<?php

namespace App\Http\Controllers\Api\V1\Recipe;

use App\Http\Controllers\Controller;
use App\Http\Requests\Api\V1\Recipe\StoreRecipeRequest;
use App\Http\Requests\Api\V1\Recipe\UpdateRecipeRequest;
use App\Http\Requests\Api\V1\Recipe\StoreScoopYieldRequest;
use App\Http\Requests\Api\V1\Recipe\UpdateScoopYieldRequest;
use App\Services\RecipeService;
use App\Services\ResponseService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class RecipeController extends Controller
{
    public function __construct(
        protected RecipeService $recipeService,
        protected ResponseService $responseService
    ) {}

    public function index(): JsonResponse
    {
        $recipes = $this->recipeService->getAll();
        return $this->responseService->success($recipes, 'Recipes retrieved successfully');
    }

    public function active(): JsonResponse
    {
        $recipes = $this->recipeService->getActive();
        return $this->responseService->success($recipes, 'Active recipes retrieved successfully');
    }

    public function forProduct(int $productId): JsonResponse
    {
        $recipes = $this->recipeService->getForProduct($productId);
        return $this->responseService->success($recipes, 'Recipes for product retrieved successfully');
    }

    public function store(StoreRecipeRequest $request): JsonResponse
    {
        $recipe = $this->recipeService->create($request->validated());
        return $this->responseService->success($recipe, 'Recipe created successfully', 201);
    }

    public function show(int $id): JsonResponse
    {
        $recipe = $this->recipeService->findWithIngredients($id);

        if (!$recipe) {
            return $this->responseService->error('Recipe not found', 404);
        }

        return $this->responseService->success($recipe, 'Recipe retrieved successfully');
    }

    public function update(UpdateRecipeRequest $request, int $id): JsonResponse
    {
        $recipe = $this->recipeService->find($id);

        if (!$recipe) {
            return $this->responseService->error('Recipe not found', 404);
        }

        $recipe = $this->recipeService->update($id, $request->validated());
        return $this->responseService->success($recipe, 'Recipe updated successfully');
    }

    public function destroy(int $id): JsonResponse
    {
        $recipe = $this->recipeService->find($id);

        if (!$recipe) {
            return $this->responseService->error('Recipe not found', 404);
        }

        $this->recipeService->delete($id);
        return $this->responseService->success(null, 'Recipe deleted successfully');
    }

    public function calculateCost(int $id): JsonResponse
    {
        $cost = $this->recipeService->calculateCost($id);

        if (isset($cost['error'])) {
            return $this->responseService->error($cost['error'], 404);
        }

        return $this->responseService->success($cost, 'Recipe cost calculated successfully');
    }

    // Scoop Yield Endpoints
    public function scoopYields(): JsonResponse
    {
        $scoopYields = $this->recipeService->getScoopYields();
        return $this->responseService->success($scoopYields, 'Scoop yields retrieved successfully');
    }

    public function scoopYieldsForIngredient(int $ingredientId): JsonResponse
    {
        $scoopYields = $this->recipeService->getScoopYieldsForIngredient($ingredientId);
        return $this->responseService->success($scoopYields, 'Scoop yields for ingredient retrieved successfully');
    }

    public function storeScoopYield(StoreScoopYieldRequest $request): JsonResponse
    {
        $scoopYield = $this->recipeService->createScoopYield($request->validated());
        return $this->responseService->success($scoopYield, 'Scoop yield created successfully', 201);
    }

    public function updateScoopYield(UpdateScoopYieldRequest $request, int $id): JsonResponse
    {
        $scoopYield = $this->recipeService->updateScoopYield($id, $request->validated());
        return $this->responseService->success($scoopYield, 'Scoop yield updated successfully');
    }

    public function destroyScoopYield(int $id): JsonResponse
    {
        $this->recipeService->deleteScoopYield($id);
        return $this->responseService->success(null, 'Scoop yield deleted successfully');
    }

    // -------------------------------------------------------------------------
    // Production Items endpoints
    // -------------------------------------------------------------------------

    /**
     * GET /recipes/{id}/production-items
     */
    public function productionItems(int $id): JsonResponse
    {
        $items = $this->recipeService->getProductionItems($id);
        return $this->responseService->success($items, 'Production items retrieved successfully');
    }

    /**
     * POST /recipes/{id}/production-items
     * Body: { source_product_id, grams, option_set_item_id?, notes? }
     */
    public function storeProductionItem(Request $request, int $id): JsonResponse
    {
        $request->validate([
            'source_product_id'  => 'required|exists:products,id',
            'grams'              => 'required|numeric|min:0.01',
            'option_set_item_id' => 'nullable|exists:option_set_items,id',
            'notes'              => 'nullable|string|max:500',
        ]);

        $item = $this->recipeService->addProductionItem($id, $request->validated());

        if (!$item) {
            return $this->responseService->error('Recipe not found', 404);
        }

        return $this->responseService->success($item, 'Production item added successfully', 201);
    }

    /**
     * PUT /recipes/{recipeId}/production-items/{itemId}
     */
    public function updateProductionItem(Request $request, int $recipeId, int $itemId): JsonResponse
    {
        $request->validate([
            'source_product_id'  => 'sometimes|exists:products,id',
            'grams'              => 'sometimes|numeric|min:0.01',
            'option_set_item_id' => 'nullable|exists:option_set_items,id',
            'notes'              => 'nullable|string|max:500',
        ]);

        $item = $this->recipeService->updateProductionItem($itemId, $request->validated());

        if (!$item) {
            return $this->responseService->error('Production item not found', 404);
        }

        return $this->responseService->success($item, 'Production item updated successfully');
    }

    /**
     * DELETE /recipes/{recipeId}/production-items/{itemId}
     */
    public function destroyProductionItem(int $recipeId, int $itemId): JsonResponse
    {
        $deleted = $this->recipeService->deleteProductionItem($itemId);

        if (!$deleted) {
            return $this->responseService->error('Production item not found', 404);
        }

        return $this->responseService->success(null, 'Production item deleted successfully');
    }

    /**
     * POST /recipes/{id}/production-items/sync
     * Replace all production items at once.
     * Body: { production_items: [{source_product_id, grams, option_set_item_id?, notes?}] }
     */
    public function syncProductionItems(Request $request, int $id): JsonResponse
    {
        $request->validate([
            'production_items'                     => 'required|array',
            'production_items.*.source_product_id' => 'required|exists:products,id',
            'production_items.*.grams'             => 'required|numeric|min:0.01',
            'production_items.*.option_set_item_id'=> 'nullable|exists:option_set_items,id',
            'production_items.*.notes'             => 'nullable|string|max:500',
        ]);

        $recipe = $this->recipeService->syncProductionItems($id, $request->input('production_items'));

        if (!$recipe) {
            return $this->responseService->error('Recipe not found', 404);
        }

        return $this->responseService->success($recipe, 'Production items synced successfully');
    }

    public function calculateScoopUsage(Request $request): JsonResponse
    {
        $request->validate([
            'ingredient_id' => 'required|exists:ingredients,id',
            'option_set_item_id' => 'nullable|exists:option_set_items,id',
            'scoop_count' => 'required|integer|min:1',
        ]);

        $usage = $this->recipeService->calculateScoopUsage(
            $request->ingredient_id,
            $request->option_set_item_id,
            $request->scoop_count
        );

        if (!$usage) {
            return $this->responseService->error('Scoop yield configuration not found', 404);
        }

        return $this->responseService->success($usage, 'Scoop usage calculated successfully');
    }
}
