<?php

namespace App\Http\Controllers;

use App\Models\ProductionRecipe;
use Illuminate\Http\Request;

class ProductionRecipeController extends Controller
{
    public function index(Request $request)
    {
        $query = ProductionRecipe::with([
            'productFinished.unit',
            'productMaterial.unit',
            'unitFinished.multi_unit',
            'unitMaterial.multi_unit',
        ]);

        if ($request->filled('product_finished_id')) {
            $query->where('product_finished_id', $request->product_finished_id);
        }

        if ($request->filled('product_material_id')) {
            $query->where('product_material_id', $request->product_material_id);
        }

        if ($request->filled('multi_unit_finished')) {
            $query->where('multi_unit_finished', $request->multi_unit_finished);
        }

        if ($request->filled('multi_unit_material')) {
            $query->where('multi_unit_material', $request->multi_unit_material);
        }

        $data = $query->get();
        $grouped = $data
            ->groupBy(function ($recipe) {
                $unitFinished = $recipe->multi_unit_finished;
                return $recipe->product_finished_id . '|' . ($unitFinished === null ? 'null' : $unitFinished);
            })
            ->values()
            ->map(function ($recipes) {
                $first = $recipes->first();
                return [
                    'id' => $first->id,
                    'product_finished_id' => $first->product_finished_id,
                    'product_finished' => $first->productFinished,
                    'qty_finished' => $first->qty_finished,
                    'multi_unit_finished' => $first->multi_unit_finished,
                    'unit_finished' => $first->unitFinished,
                    'children' => $recipes->map(function ($r) {
                        return [
                            'id' => $r->id,
                            'product_material_id' => $r->product_material_id,
                            'product_material' => $r->productMaterial,
                            'qty_material' => $r->qty_material,
                            'multi_unit_material' => $r->multi_unit_material,
                            'unit_material' => $r->unitMaterial,
                            'multiunit' => $r->multiunit,
                        ];
                    })->values(),
                ];
            })
            ->values();

        return response()->json([
            'success' => true,
            'data' => $grouped,
        ], 200);
    }

    public function show(Request $request, $id)
    {
        $query = ProductionRecipe::with([
            'productFinished.unit',
            'productMaterial.unit',
            'unitFinished.multi_unit',
            'unitMaterial.multi_unit',
        ])->where('product_finished_id', $id);

        $multiUnitFinished = $request->query('multi_unit_finished', null);

        if ($multiUnitFinished !== null) {
            if ($multiUnitFinished === '' || $multiUnitFinished === 'null') {
                $query->whereNull('multi_unit_finished');
            } else {
                $query->where('multi_unit_finished', $multiUnitFinished);
            }
        }

        $data = $query->get();

        if ($data->isEmpty()) {
            return response()->json([
                'success' => false,
                'message' => 'Production recipe not found',
            ], 404);
        }

        $first = $data->first();
        $group = [
            'id' => $first->id,
            'product_finished_id' => $first->product_finished_id,
            'product_finished' => $first->productFinished,
            'qty_finished' => $first->qty_finished,
            'multi_unit_finished' => $first->multi_unit_finished,
            'unit_finished' => $first->unitFinished,
            'children' => $data->map(function ($r) {
                return [
                    'id' => $r->id,
                    'product_material_id' => $r->product_material_id,
                    'product_material' => $r->productMaterial,
                    'qty_material' => $r->qty_material,
                    'multi_unit_material' => $r->multi_unit_material,
                    'unit_material' => $r->unitMaterial,
                    'multiunit' => $r->multiunit,
                ];
            })->values(),
        ];

        return response()->json([
            'success' => true,
            'data' => $group,
        ], 200);
    }

    public function showByFinishedAndUnit($productFinishedId, $multiUnitFinished = null)
    {
        $query = ProductionRecipe::with([
            'productFinished.unit',
            'productMaterial.unit',
            'unitFinished.multi_unit',
            'unitMaterial.multi_unit',
        ])->where('product_finished_id', $productFinishedId);

        if ($multiUnitFinished === null) {
            $query->whereNull('multi_unit_finished');
        } else {
            $query->where('multi_unit_finished', $multiUnitFinished);
        }

        $data = $query->get();

        if ($data->isEmpty()) {
            return response()->json([
                'success' => false,
                'message' => 'Production recipe not found',
            ], 404);
        }

        $first = $data->first();
        $group = [
            'id' => $first->id,
            'product_finished_id' => $first->product_finished_id,
            'product_finished' => $first->productFinished,
            'qty_finished' => $first->qty_finished,
            'multi_unit_finished' => $first->multi_unit_finished,
            'unit_finished' => $first->unitFinished,
            'children' => $data->map(function ($r) {
                return [
                    'id' => $r->id,
                    'product_material_id' => $r->product_material_id,
                    'product_material' => $r->productMaterial,
                    'qty_material' => $r->qty_material,
                    'multi_unit_material' => $r->multi_unit_material,
                    'unit_material' => $r->unitMaterial,
                    'multiunit' => $r->multiunit,
                ];
            })->values(),
        ];

        return response()->json([
            'success' => true,
            'data' => $group,
        ], 200);
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'product_finished_id' => 'required|integer|exists:products,id',
            'qty_finished' => 'required|integer',
            'product_material_id' => 'required|array',
            'product_material_id.*' => 'required|integer|exists:products,id',
            'qty_material' => 'required|array',
            'qty_material.*' => 'required|integer',
            'multi_unit_finished' => 'nullable|integer|exists:multi_units,id',
            'multi_unit_material' => 'nullable|array',
            'multi_unit_material.*' => 'nullable|integer|exists:multi_units,id',
        ]);

        $productFinishedId = $validated['product_finished_id'];
        $qtyFinished = $validated['qty_finished'];
        $materials = $validated['product_material_id'];
        $qtyMaterials = $validated['qty_material'];
        $multiUnitFinished = $validated['multi_unit_finished'] ?? null;
        $multiUnitMaterials = $validated['multi_unit_material'] ?? [];

        $recipes = [];

        foreach ($materials as $index => $materialId) {
            $multiUnitMaterial = $multiUnitMaterials[$index] ?? null;
            $qtyMaterial = $qtyMaterials[$index] ?? null;

            $recipe = new ProductionRecipe();
            $recipe->product_finished_id = $productFinishedId;
            $recipe->product_material_id = $materialId;
            $recipe->qty_finished = $qtyFinished;
            $recipe->qty_material = $qtyMaterial;
            $recipe->multi_unit_finished = $multiUnitFinished;
            $recipe->multi_unit_material = $multiUnitMaterial;
            $recipe->save();
            $recipe->load([
                'productFinished.unit',
                'productMaterial.unit',
                'unitFinished.multi_unit',
                'unitMaterial.multi_unit',
            ]);

            $recipes[] = $recipe;
        }

        $group = null;
        if (!empty($recipes)) {
            $first = $recipes[0];
            $group = [
                'id' => $first->id,
                'product_finished_id' => $first->product_finished_id,
                'product_finished' => $first->productFinished,
                'qty_finished' => $first->qty_finished,
                'multi_unit_finished' => $first->multi_unit_finished,
                'unit_finished' => $first->unitFinished,
                'children' => collect($recipes)->map(function ($r) {
                    return [
                        'id' => $r->id,
                        'product_material_id' => $r->product_material_id,
                        'product_material' => $r->productMaterial,
                        'qty_material' => $r->qty_material,
                        'multi_unit_material' => $r->multi_unit_material,
                        'unit_material' => $r->unitMaterial,
                        'multiunit' => $r->multiunit,
                    ];
                })->values(),
            ];
        }

        return response()->json([
            'success' => true,
            'data' => $group,
        ], 201);
    }

    public function update(Request $request, $id)
    {
        $validated = $request->validate([
            'qty_finished' => 'required|integer',
            'product_material_id' => 'required|array',
            'product_material_id.*' => 'required|integer|exists:products,id',
            'qty_material' => 'required|array',
            'qty_material.*' => 'required|integer',
            'multi_unit_finished' => 'nullable|integer|exists:multi_units,id',
            'multi_unit_material' => 'nullable|array',
            'multi_unit_material.*' => 'nullable|integer|exists:multi_units,id',
        ]);

        $existing = ProductionRecipe::where('product_finished_id', $id)->get();
        if ($existing->isEmpty()) {
            return response()->json([
                'success' => false,
                'message' => 'Production recipe not found',
            ], 404);
        }

        ProductionRecipe::where('product_finished_id', $id)->delete();

        $qtyFinished = $validated['qty_finished'];
        $materials = $validated['product_material_id'];
        $qtyMaterials = $validated['qty_material'];
        $multiUnitFinished = $validated['multi_unit_finished'] ?? null;
        $multiUnitMaterials = $validated['multi_unit_material'] ?? [];

        $recipes = [];

        foreach ($materials as $index => $materialId) {
            $multiUnitMaterial = $multiUnitMaterials[$index] ?? null;
            $qtyMaterial = $qtyMaterials[$index] ?? null;

            $recipe = new ProductionRecipe();
            $recipe->product_finished_id = $id;
            $recipe->product_material_id = $materialId;
            $recipe->qty_finished = $qtyFinished;
            $recipe->qty_material = $qtyMaterial;
            $recipe->multi_unit_finished = $multiUnitFinished;
            $recipe->multi_unit_material = $multiUnitMaterial;
            $recipe->save();
            $recipe->load([
                'productFinished.unit',
                'productMaterial.unit',
                'unitFinished.multi_unit',
                'unitMaterial.multi_unit',
            ]);

            $recipes[] = $recipe;
        }

        $first = $recipes[0] ?? null;
        $group = [
            'id' => $first ? $first->id : null,
            'product_finished_id' => $first ? $first->product_finished_id : $id,
            'product_finished' => $first ? $first->productFinished : null,
            'qty_finished' => $first ? $first->qty_finished : null,
            'multi_unit_finished' => $first ? $first->multi_unit_finished : null,
            'unit_finished' => $first ? $first->unitFinished : null,
            'children' => collect($recipes)->map(function ($r) {
                return [
                    'id' => $r->id,
                    'product_material_id' => $r->product_material_id,
                    'product_material' => $r->productMaterial,
                    'qty_material' => $r->qty_material,
                    'multi_unit_material' => $r->multi_unit_material,
                    'unit_material' => $r->unitMaterial,
                    'multiunit' => $r->multiunit,
                ];
            })->values(),
        ];

        return response()->json([
            'success' => true,
            'data' => $group,
        ], 200);
    }

    public function destroy($id)
    {
        $recipe = ProductionRecipe::find($id);
        if (!$recipe) {
            return response()->json([
                'success' => false,
                'message' => 'Production recipe not found',
            ], 404);
        }

        $recipe->delete();

        return response()->json([
            'success' => true,
            'message' => 'Production recipe deleted',
        ], 200);
    }
}
