<?php

namespace App\Modules\Production\Controllers;

use App\Http\Controllers\Controller;
use App\Modules\Production\Models\Recipe;
use App\Modules\Production\Models\RecipeItem;
use App\Modules\Inventory\Contracts\InventoryServiceInterface;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Inertia\Inertia;
use Inertia\Response;

class RecipeController extends Controller
{
    protected $inventoryService;

    public function __construct(InventoryServiceInterface $inventoryService)
    {
        $this->inventoryService = $inventoryService;
    }

    /**
     * 配方列表
     */
    public function index(Request $request): Response
    {
        $query = Recipe::query();

        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('code', 'like', "%{$search}%")
                  ->orWhere('name', 'like', "%{$search}%");
                
                $productIds = $this->inventoryService->getProductsByName($search)->pluck('id');
                $q->orWhereIn('product_id', $productIds);
            });
        }

        $query->orderBy($request->input('sort_field', 'created_at'), $request->input('sort_direction', 'desc'));

        $recipes = $query->paginate($request->input('per_page', 10))->withQueryString();

        // Manual Hydration
        $productIds = $recipes->pluck('product_id')->unique()->filter()->toArray();
        $products = $this->inventoryService->getProductsByIds($productIds)->keyBy('id');

        $recipes->getCollection()->transform(function ($recipe) use ($products) {
            $recipe->product = $products->get($recipe->product_id);
            return $recipe;
        });

        return Inertia::render('Production/Recipe/Index', [
            'recipes' => $recipes,
            'filters' => $request->only(['search', 'per_page', 'sort_field', 'sort_direction']),
        ]);
    }

    /**
     * 新增配方表單
     */
    public function create(): Response
    {
        return Inertia::render('Production/Recipe/Create', [
            'products' => $this->inventoryService->getAllProducts(),
            'units' => $this->inventoryService->getUnits(),
        ]);
    }

    /**
     * 儲存配方
     */
    public function store(Request $request)
    {
        $validated = $request->validate([
            'product_id' => 'required|exists:products,id',
            'code' => 'required|string|max:50|unique:recipes,code',
            'name' => 'required|string|max:255',
            'description' => 'nullable|string',
            'yield_quantity' => 'required|numeric|min:0.01',
            'items' => 'required|array|min:1',
            'items.*.product_id' => 'required|exists:products,id',
            'items.*.quantity' => 'required|numeric|min:0.0001',
            'items.*.unit_id' => 'nullable|exists:units,id',
            'items.*.remark' => 'nullable|string',
        ]);

        DB::transaction(function () use ($validated) {
            $recipe = Recipe::create([
                'product_id' => $validated['product_id'],
                'code' => $validated['code'],
                'name' => $validated['name'],
                'description' => $validated['description'],
                'yield_quantity' => $validated['yield_quantity'],
                'is_active' => true,
            ]);

            foreach ($validated['items'] as $item) {
                RecipeItem::create([
                    'recipe_id' => $recipe->id,
                    'product_id' => $item['product_id'],
                    'quantity' => $item['quantity'],
                    'unit_id' => $item['unit_id'],
                    'remark' => $item['remark'],
                ]);
            }
        });

        return redirect()->route('recipes.index')->with('success', '配方已建立');
    }

    /**
     * 編輯配方表單
     */
    public function edit(Recipe $recipe): Response
    {
        // Hydrate Product
        $recipe->product = $this->inventoryService->getProduct($recipe->product_id);
        
        // Load items with details
        $items = $recipe->items;
        $productIds = $items->pluck('product_id')->unique()->toArray();
        $products = $this->inventoryService->getProductsByIds($productIds)->keyBy('id');
        $units = $this->inventoryService->getUnits()->keyBy('id');

        foreach ($items as $item) {
            $item->product = $products->get($item->product_id);
            $item->unit = $units->get($item->unit_id);
        }

        return Inertia::render('Production/Recipe/Edit', [
            'recipe' => $recipe,
            'products' => $this->inventoryService->getAllProducts(),
            'units' => $this->inventoryService->getUnits(),
        ]);
    }

    /**
     * 更新配方
     */
    public function update(Request $request, Recipe $recipe)
    {
        $validated = $request->validate([
            'product_id' => 'required|exists:products,id',
            'code' => 'required|string|max:50|unique:recipes,code,' . $recipe->id,
            'name' => 'required|string|max:255',
            'description' => 'nullable|string',
            'yield_quantity' => 'required|numeric|min:0.01',
            'items' => 'required|array|min:1',
            'items.*.product_id' => 'required|exists:products,id',
            'items.*.quantity' => 'required|numeric|min:0.0001',
            'items.*.unit_id' => 'nullable|exists:units,id',
            'items.*.remark' => 'nullable|string',
        ]);

        DB::transaction(function () use ($validated, $recipe) {
            $recipe->update([
                'product_id' => $validated['product_id'],
                'code' => $validated['code'],
                'name' => $validated['name'],
                'description' => $validated['description'],
                'yield_quantity' => $validated['yield_quantity'],
            ]);

            // Sync items (Delete all and recreate)
            $recipe->items()->delete();

            foreach ($validated['items'] as $item) {
                RecipeItem::create([
                    'recipe_id' => $recipe->id,
                    'product_id' => $item['product_id'],
                    'quantity' => $item['quantity'],
                    'unit_id' => $item['unit_id'],
                    'remark' => $item['remark'],
                ]);
            }
        });

        return redirect()->route('recipes.index')->with('success', '配方已更新');
    }

    /**
     * 刪除配方
     */
    public function destroy(Recipe $recipe)
    {
        $recipe->delete();
        return redirect()->back()->with('success', '配方已刪除');
    }

    /**
     * 獲取配方詳細資料 (API)
     */
    /**
     * 獲取配方詳細資料 (API)
     */
    public function show(Recipe $recipe)
    {
        // Manual Hydration for strict modularity
        $recipe->product = $this->inventoryService->getProduct($recipe->product_id);

        $items = $recipe->items;
        $productIds = $items->pluck('product_id')->unique()->toArray();
        $products = $this->inventoryService->getProductsByIds($productIds)->keyBy('id');
        $units = $this->inventoryService->getUnits()->keyBy('id');

        foreach ($items as $item) {
            $item->product = $products->get($item->product_id);
            $item->unit = $units->get($item->unit_id);
        }

        return response()->json($recipe);
    }

    /**
     * 獲取商品最新有效配方 (API)
     */
    public function getLatestByProduct($productId)
    {
        // 放寬條件，只要 product_id 相符就抓最新的
        $recipe = Recipe::where('product_id', (int)$productId)
            ->orderBy('created_at', 'desc')
            ->first();

        if (!$recipe) {
            return response()->json(null);
        }

        // Load items with product info
        $items = $recipe->items;
        $productIds = $items->pluck('product_id')->unique()->toArray();
        $products = $this->inventoryService->getProductsByIds($productIds)->keyBy('id');

        $formattedItems = $items->map(function ($item) use ($products) {
            $product = $products->get($item->product_id);
            return [
                'product_id' => $item->product_id,
                'product_name' => $product->name ?? '未知商品',
                'product_code' => $product->code ?? '',
                'quantity' => $item->quantity,
                'unit_id' => $item->unit_id,
                'unit_name' => $product->baseUnit->name ?? '',
            ];
        });

        return response()->json([
            'id' => $recipe->id,
            'name' => $recipe->name,
            'code' => $recipe->code,
            'yield_quantity' => $recipe->yield_quantity,
            'items' => $formattedItems,
        ]);
    }
    /**
     * 獲取商品所有有效配方列表 (API)
     */
    public function getByProduct($productId)
    {
        $recipes = Recipe::where('product_id', (int)$productId)
            ->where('is_active', true)
            ->orderBy('created_at', 'desc')
            ->get();

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

        // 預先載入必要的關聯與數據
        // 為了效能，我們只在列表顯示基本資訊，詳細 Item 資料等選中後再透過 getLatestByProduct (或是重構為 getDetails) 獲取
        // 不過為了前端方便，若配方不多，直接回傳完整結構也可以。
        // 這裡選擇回傳完整結構，因為配方通常不會太多
        
        $recipes->load('items');

        // 收集所有 recipe items 中的 product ids
        $allProductIds = $recipes->pluck('items')->flatten()->pluck('product_id')->unique()->toArray();
        $products = $this->inventoryService->getProductsByIds($allProductIds)->keyBy('id');

        $result = $recipes->map(function ($recipe) use ($products) {
            $formattedItems = $recipe->items->map(function ($item) use ($products) {
                $product = $products->get($item->product_id);
                return [
                    'product_id' => $item->product_id,
                    'product_name' => $product->name ?? '未知商品',
                    'product_code' => $product->code ?? '',
                    'quantity' => $item->quantity,
                    'unit_id' => $item->unit_id,
                    'unit_name' => $product->baseUnit->name ?? '',
                ];
            });

            return [
                'id' => $recipe->id,
                'name' => $recipe->name,
                'code' => $recipe->code,
                'yield_quantity' => $recipe->yield_quantity,
                'items' => $formattedItems,
                'created_at' => $recipe->created_at->toIso8601String(),
            ];
        });

        return response()->json($result);
    }
}
