<?php

namespace App\Http\Controllers;

use App\Models\part;
use Illuminate\Http\Request;
use App\Traits\FileUploader;
use App\Http\Resources\partResource;
use Illuminate\Validation\Rule;


class PartController extends Controller
{
    use FileUploader;
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        return partResource::collection(part::all());
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        try{
            $request->validate([
        'pic' => 'nullable|image|mimes:jpeg,png,jpg,gif',
        'part_code' => 'required|string|max:40|unique:parts,part_code',
        'part_name' => 'required|string|max:40',
        'manufacture' => 'nullable|string|max:40',
        'mfg_code' => 'nullable|string|max:255',
        'unit' => 'nullable|string|max:50',
        'parent' => 'integer|required',
        'min_qty' => 'nullable|min:0',
        'Order_point' => 'nullable|integer|min:0',
        'Order_qty' => 'nullable|integer|min:0',
        'Qty' => 'nullable|integer|min:0',
        'Dimention' => 'nullable|string|max:255',
        'Weight' => 'nullable|numeric|min:0',
        'Loc' => 'nullable|string|max:255',
        'Row' => 'nullable|string|max:50',
        'Col' => 'nullable|string|max:50',
        'Pos' => 'nullable|string|max:50',
        'Description' => 'nullable|string|max:1000',
    ], [
        'pic.image' => 'Uploaded file must be an image.',
        'pic.mimes' => 'Image must be a file of type: jpeg, png, jpg, gif.',
        'part_code.required' => 'Part code is required.',
        'part_code.string' => 'Part code must be a string.',
        'part_code.max' => 'Part code may not be greater than 255 characters.',
        'part_code.unique' => 'Part code must be unique.',
        'part_name.required' => 'Part name is required.',
        'part_name.string' => 'Part name must be a string.',
        'part_name.max' => 'Part name may not be greater than 255 characters.',
        'manufacture.required' => 'Manufacture is required.',
        'manufacture.string' => 'Manufacture must be a string.',
        'manufacture.max' => 'Manufacture may not be greater than 255 characters.',
        'mfg_code.string' => 'Manufacture code must be a string.',
        'mfg_code.max' => 'Manufacture code may not be greater than 255 characters.',
        'unit.string' => 'Unit must be a string.',
        'unit.max' => 'Unit may not be greater than 50 characters.',
        'parent.integer' => 'Parent ID must be an integer.',
        'parent.exists' => 'The selected parent is invalid.',
        'min_qty.min' => 'Minimum quantity must be at least 0.',
        'Order_point.integer' => 'Order point must be an integer.',
        'Order_point.min' => 'Order point must be at least 0.',
        'Order_qty.integer' => 'Order quantity must be an integer.',
        'Order_qty.min' => 'Order quantity must be at least 0.',
        'Qty.integer' => 'Quantity must be an integer.',
        'Qty.min' => 'Quantity must be at least 0.',
        'Dimention.string' => 'Dimension must be a string.',
        'Dimention.max' => 'Dimension may not be greater than 255 characters.',
        'Weight.numeric' => 'Weight must be a number.',
        'Weight.min' => 'Weight must be at least 0.',
        'Loc.string' => 'Location must be a string.',
        'Loc.max' => 'Location may not be greater than 255 characters.',
        'Row.string' => 'Row must be a string.',
        'Row.max' => 'Row may not be greater than 50 characters.',
        'Col.string' => 'Column must be a string.',
        'Col.max' => 'Column may not be greater than 50 characters.',
        'Pos.string' => 'Position must be a string.',
        'Pos.max' => 'Position may not be greater than 50 characters.',
        'Description.string' => 'Description must be a string.',
        'Description.max' => 'Description may not be greater than 1000 characters.',
    ]);
        
        $part = new part();
         if (!empty($request->pic) ) {
            $part->Picture=$this->UploadFile("pic", $request ,"parts", "assets/uploaded/parts/")["path"];
        }
        $part->part_code = $request->part_code;
        $part->part_name = $request->part_name;
        $part->manufacture = $request->manufacture;
        $part->mfg_code = $request->mfg_code;
        $part->unit = $request->unit;
        $part->parent = $request->parent;
        $part->min_qty = $request->min_qty;
        $part->Order_point = $request->Order_point;
        $part->Order_qty = $request->Order_qty;
        $part->Qty = $request->Qty;
        $part->Dimention = $request->Dimention;
        $part->Weight = $request->Weight;
        $part->Loc = $request->Loc;
        $part->Row = $request->Row;
        $part->Col = $request->Col;
        $part->Pos = $request->Pos;
        $part->Description = $request->Description;
        $part->save();
        return response()->json(// todo : see macro vidoes
            [
                "data"=> $part,
                "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);
            }
    }

    /**
     * Display the specified resource.
     */
    public function show($id)
    {
        // return part::find($id);
       try {
            return response()->json(// todo : see macro vidoes
                [
                    "data" => new partResource(part::findOrFail($id)),
                    "message" => "success",
                    "status" => true,
                ]
            );
        } catch (\Throwable $th) {
            return response()->json(// todo : see macro vidoes
                [
                    "data" => [],
                    "message" => "No Record Found !",
                    "status" => false,
                ]
            );
        }
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(part $part)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, $id)
    {try{
        
        // $part = $request->part_code;
        // return $part;
            $request->validate([
        'pic' => 'nullable|image|mimes:jpeg,png,jpg,gif',
        'part_code' => ["required","string","max:40", Rule::unique("parts")->ignore($request->part_code,"part_code")],
        'part_name' => 'required|string|max:40',
        'manufacture' => 'nullable|string|max:40',
        'mfg_code' => 'nullable|string|max:255',
        'unit' => 'nullable|string|max:50',
        'parent' => 'integer|required',
        'min_qty' => 'nullable|min:0',
        'Order_point' => 'nullable|integer|min:0',
        'Order_qty' => 'nullable|integer|min:0',
        'Qty' => 'nullable|integer|min:0',
        'Dimention' => 'nullable|string|max:255',
        'Weight' => 'nullable|numeric|min:0',
        'Loc' => 'nullable|string|max:255',
        'Row' => 'nullable|string|max:50',
        'Col' => 'nullable|string|max:50',
        'Pos' => 'nullable|string|max:50',
        'Description' => 'nullable|string|max:1000',
    ], [
        'pic.image' => 'Uploaded file must be an image.',
        'pic.mimes' => 'Image must be a file of type: jpeg, png, jpg, gif.',
        'part_code.required' => 'Part code is required.',
        'part_code.string' => 'Part code must be a string.',
        'part_code.max' => 'Part code may not be greater than 255 characters.',
        'part_code.unique' => 'Part code must be unique.',
        'part_name.required' => 'Part name is required.',
        'part_name.string' => 'Part name must be a string.',
        'part_name.max' => 'Part name may not be greater than 255 characters.',
        'manufacture.required' => 'Manufacture is required.',
        'manufacture.string' => 'Manufacture must be a string.',
        'manufacture.max' => 'Manufacture may not be greater than 255 characters.',
        'mfg_code.string' => 'Manufacture code must be a string.',
        'mfg_code.max' => 'Manufacture code may not be greater than 255 characters.',
        'unit.string' => 'Unit must be a string.',
        'unit.max' => 'Unit may not be greater than 50 characters.',
        'parent.integer' => 'Parent ID must be an integer.',
        'parent.exists' => 'The selected parent is invalid.',
        'min_qty.min' => 'Minimum quantity must be at least 0.',
        'Order_point.integer' => 'Order point must be an integer.',
        'Order_point.min' => 'Order point must be at least 0.',
        'Order_qty.integer' => 'Order quantity must be an integer.',
        'Order_qty.min' => 'Order quantity must be at least 0.',
        'Qty.integer' => 'Quantity must be an integer.',
        'Qty.min' => 'Quantity must be at least 0.',
        'Dimention.string' => 'Dimension must be a string.',
        'Dimention.max' => 'Dimension may not be greater than 255 characters.',
        'Weight.numeric' => 'Weight must be a number.',
        'Weight.min' => 'Weight must be at least 0.',
        'Loc.string' => 'Location must be a string.',
        'Loc.max' => 'Location may not be greater than 255 characters.',
        'Row.string' => 'Row must be a string.',
        'Row.max' => 'Row may not be greater than 50 characters.',
        'Col.string' => 'Column must be a string.',
        'Col.max' => 'Column may not be greater than 50 characters.',
        'Pos.string' => 'Position must be a string.',
        'Pos.max' => 'Position may not be greater than 50 characters.',
        'Description.string' => 'Description must be a string.',
        'Description.max' => 'Description may not be greater than 1000 characters.',
    ]);
        $part = part::find($id);
      
            if($request->deleted_picture === "true"){
            $part->Picture = null;
        }
        if (!is_null($request->Picture) && !empty($request->Picture) ) {
            $part->Picture=$this->UploadFile("Picture", $request ,"parts", "assets/uploaded/parts/")["path"];
        }
        $part->part_code = $request->part_code;
        $part->part_name = $request->part_name;
        $part->manufacture = $request->manufacture;
        $part->mfg_code = $request->mfg_code;
        $part->unit = $request->unit;
        $part->parent = $request->parent;
        $part->min_qty = $request->min_qty;
        $part->Order_point = $request->Order_point;
        $part->Order_qty = $request->Order_qty;
        $part->Qty = $request->Qty;
        $part->Dimention = $request->Dimention;
        $part->Weight = $request->Weight;
        $part->Loc = $request->Loc;
        $part->Row = $request->Row;
        $part->Col = $request->Col;
        $part->Pos = $request->Pos;
        $part->Description = $request->Description;
        $part->save();
        return response()->json(// todo : see macro vidoes
            [
                "data"=>$part,
                "message"=>["saved"],
                "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);
            }
    }

    /**
     * Remove the specified resource from storage.
     */
    public function delete (part $part, $id)
    {
         $part = part::where("id", $id);
         try {
            $part->delete();
            return response()->json([
                "data" => $part,
                "message" => "deleted",
                "status" => true,
            ]);
        } catch (Exception $e) {
            return response()->json([
                "message" => "An error occurred",
                "error" => $e->getMessage(),
                "status" => false,
            ], 500);
        }
    }
    public function getPartsByParents(Request $request, $parent_id = 0)
    {
        $part = part::where("parent", $parent_id)->orderby('part_code')->get();
        return response()->json(// todo : see macro vidoes
            [
                "data" => partResource::collection($part),
                "message" => "success",
                "status" => true,
            ]
        );
    }
}
