<?php

namespace App\Http\Controllers;

use App\Http\Resources\Inventory_codingResource;
use App\Models\inventory_coding;
use Illuminate\Http\Request;

class Inventory_codingController extends Controller
{
    public function index()
    {
        return Inventory_codingResource::collection(inventory_coding::all());
    }

    public function store(Request $request)
    {
            try{
                $request->validate([
            'inventory_code' => 'required|string|max:255|unique:inventory_codings,inventory_code',
            'parent' => 'required',
            'code_name' => 'required|string|max:40',
            'description' => 'nullable|string|max:1000',
        ], [
            'inventory_code.required' => 'Inventory code is required.',
            'inventory_code.string' => 'Inventory code must be a string.',
            'inventory_code.max' => 'Inventory code may not be greater than 255 characters.',
            'inventory_code.unique' => 'Inventory code must be unique.',
            'parent.integer' => 'Parent ID must be an integer.',
            'parent.exists' => 'The selected parent is invalid.',
            'code_name.required' => 'Inventory name is required.',
            'code_name.string' => 'Inventory name must be a string.',
            'code_name.max' => 'Inventory name may not be greater than 255 characters.',
            'description.string' => 'Description must be a string.',
            'description.max' => 'Description may not be greater than 1000 characters.',
        ]);
            $data = new inventory_coding();
            $data->inventory_code = $request->inventory_code;
            $data->parent = $request->parent;
            $data->code_name = $request->code_name;
            $data->description = $request->description;
            $data->save();
            return response()->json(// todo : see macro vidoes
                [
                    "data" => $data,
                    "message" => "success",
                    "status" => true,
                ], 201);
            }  catch (IlluminateValidationValidationException $e) {
            return response()->json([
                "d" => "Validation Error",
                "errors" => $e->validator->errors(),
                "status" => false,
            ], 422);
    
        } catch (Exception $e) {
                return response()->json([
                    "message" => "An error occurred",
                    "error" => $e->getMessage(),
                    "status" => false,
                ], 500);
            }
    }

    public function show(inventory_coding $inventory_coding, $id)
    {
        return response()->json(// todo : see macro vidoes
            [
                "data"=> new Inventory_codingResource(inventory_coding::find($id)),
                "message"=>"success",
                "status"=>true,
            ]);
    }

    public function update(Request $request, $id)
    {
        $data = inventory_coding::find($id);
        $data->inventory_code = $request->inventory_code;
        $data->parent = $request->parent;
        $data->code_name = $request->code_name;
        $data->description = $request->description;
        $data->save();
        return response()->json(// todo : see macro vidoes
            [
                "data" => $data,
                "message" => "success",
                "status" => true,
            ]
        );
    }
    public function checkChildren($id)
    {
        if (auth()->user()->accesability < 300) {
            return response()->json([
                "message" => "Unauthorized. Only super admins can delete inventory groups.",
                "status"  => false,
            ], 403);
        }

        $childCount = inventory_coding::where('parent', $id)->count();
        $partCount  = \App\Models\part::where('parent', $id)->count();
        // count parts in all nested sub-items too
        $totalParts = $this->countAllParts($id);
        $hasChildren = ($childCount + $partCount) > 0;

        return response()->json([
            "has_children"  => $hasChildren,
            "child_count"   => $childCount,
            "part_count"    => $totalParts,
            "other_items"   => Inventory_codingResource::collection(
                inventory_coding::where('id', '!=', $id)->get()
            ),
            "status" => true,
        ]);
    }

    private function countAllParts($inventoryId)
    {
        $count = \App\Models\part::where('parent', $inventoryId)->count();
        $children = inventory_coding::where('parent', $inventoryId)->get();
        foreach ($children as $child) {
            $count += $this->countAllParts($child->id);
        }
        return $count;
    }

    public function destroy(Request $request, $id)
    {
        if (auth()->user()->accesability < 300) {
            return response()->json([
                "message" => "Unauthorized. Only super admins can delete inventory groups.",
                "status"  => false,
            ], 403);
        }

        $item        = inventory_coding::findOrFail($id);
        $childCount  = inventory_coding::where('parent', $id)->count();
        $partCount   = \App\Models\part::where('parent', $id)->count();
        $hasChildren = ($childCount + $partCount) > 0;

        if ($hasChildren) {
            $mode = $request->input('mode', 'cascade');

            if ($mode === 'cascade') {
                // حذف کامل: همه sub-items و همه parts (بازگشتی)
                $this->deleteInventoryCascade($id);

            } elseif ($mode === 'reassign') {
                $newParent = $request->input('new_parent_id');
                if (!$newParent) {
                    return response()->json([
                        "message" => "new_parent_id is required for reassign mode.",
                        "status"  => false,
                    ], 422);
                }
                // parts مستقیم این آیتم حذف می‌شن (part بدون inventory_coding معنی نداره)
                \App\Models\part::where('parent', $id)->delete();
                // sub-items به والد جدید منتقل می‌شن (همراه parts خودشون)
                inventory_coding::where('parent', $id)->update(['parent' => $newParent]);
                $item->delete();

            } else {
                // fallback: cascade
                $this->deleteInventoryCascade($id);
            }
        } else {
            // بدون زیرمجموعه: مستقیم حذف
            $item->delete();
        }

        return response()->json([
            "message" => "Inventory coding deleted successfully.",
            "status"  => true,
        ]);
    }

    private function deleteInventoryCascade($id)
    {
        $children = inventory_coding::where('parent', $id)->get();
        foreach ($children as $child) {
            $this->deleteInventoryCascade($child->id);
        }
        // حذف همه parts این آیتم
        \App\Models\part::where('parent', $id)->delete();
        // حذف خود آیتم
        inventory_coding::find($id)->delete();
    }

    public function getInventoryByParents(Request $request, $parent_id)
    {
        $inventory = inventory_coding::where("parent", $parent_id)->orderby('inventory_code')->get();
        return response()->json(
            [
                "data" => Inventory_codingResource::collection($inventory),
                "message" => "success",
                "status" => true,
            ]
        );
    }
}
