<?php

namespace App\Http\Controllers\Api\Manufacturing;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Auth;
use App\Models\Bom;
use App\Models\BomRm;
use App\Models\BomCharge;
use App\Models\BomPackaging;
use App\Models\BomOperation;
use App\Models\BomScrap;
use App\Models\BomOutcome;
use App\Service\SequenceService;
use Log;

class BomController extends Controller
{
    public function index(Request $request)
    {
        $bom = Bom::where('rolledback',0)->with('item:id,name','entry_by');

        // Apply filters based on request parameters
        if ($request->has('search')) {
            $search = $request->input('search');
            $bom =$bom->where(function ($q) use ($search) {
                $q->where('bom_id', 'LIKE', "%$search%")
                    ->orWhere('bom_type','LIKE',"%$search%")
                    ->orWhere('qty', 'LIKE', "%$search%")
                    ->orWhereHas('item', function ($query) use ($search) {
                        $query->where('name', 'LIKE', '%' . $search . '%');
                    });
            });
        }

        if($request['item_id']!=0 && isset($request['item_id'])){
            $bom =$bom->where('item_id', $request['item_id']);
        }


        if ($request->has('bom_type')) {
            $type = $request->input('bom_type');
            $bom =$bom->where('bom_type', $type);
        }

        if ($request->has('is_active')) {
            $is_active = $request->input('is_active');
            $bom =$bom->where('is_active', $is_active);
        }

        if ($request->has('status')) {
            $status = $request->input('status');
            $bom =$bom->where('status', $status);
        }

        $count=$bom->count();

        if(isset($request['sort_by']) && $request['sort_by']!='' && $request['sort_by']!=null){
                
            $sort_order=$request['sort_order']==1?'asc':'desc';

            $bom = $bom->orderby($request['sort_by'],$sort_order);

        }else{
            $bom = $bom->orderby('id','desc');
        }
        
        $bom=$bom->skip($request['noofrec']*($request['currentpage']-1))->take($request['noofrec']??50)
                // ->orderBy('id','desc')
                ->get();

        return $response=[
            'success'=>true,
            'total'=>$count,
            'boms'=>$bom,
            'message'=>'All Bills of Material Listed Successfully'
        ];
        return response()->json($response);
        
    }

    // Store a newly created requisition
    public function store(Request $request)
    {
        
        $validator=validator($request->all(),[
            'bom_id'=>'required',
            'item_id'=>'required|integer',
            'unit_id'=>'required|integer',
            'qty'=>'required|integer',
            'bom_type'=>'required|integer',    //1 :Single Product  2: by product
            
        ]);

        if ($validator->fails()) {                                                                                              

            return [
                'success' => false, 
                'message' => $validator->errors()->first(),
                'items_details' => null
            ];

        } else {

            try {

                //check item_id already exists
                $existingBom = Bom::where('item_id', $request->item_id)
                    ->first();
                if ($existingBom) {
                    return ['success' => false, 'message' => 'Item already exists in BOM'];
                }

                $bom = Bom::create([
                    'bom_id' => $request->bom_id,
                    'bom_type'=>$request->bom_type,
                    'item_id'=>$request->item_id,
                    'qty' => $request->qty,
                    'unit_id' => $request->unit_id,
                    
                    "rm_cost"=>$request->rm_cost??0,         //Raw material costs
                    "packaging_cost"=>$request->packaging_cost??0, 
                    "charges_cost"=>$request->charges_cost??0, 
                    "outcome_cost"=>$request->outcome_cost??0, 
                    "taxes_amount"=>$request->taxes_amount??0, 
                    "subtotal"=>$request->subtotal??0, 
                    "total_cost"=>$request->total_cost??0, 
                    "notes"=>$request->notes,
                    "attachment"=>$request->attachment, 
                    'status' => $request->status??0,
                    
                ]);

                $module='bill_of_material';

                // Update Sequence
                $sequence=new SequenceService;
                $sequence->updateSequence($module);

                // Outcome Products
                Log::info($request);
                if(isset($request['bom_outcomes'])){
                    Log::info("bom_outcomes inserting");
                    foreach ($request['bom_outcomes'] as $outcome) {

                        BomOutcome::create([
                            'bom_id' => $bom['id'],
                            'item_id' => $outcome['item_id'],
                            'item_name' => $outcome['item_name'],
                            'unit_price' => $outcome['unit_price'],
                            'qty' => $outcome['qty'],
                            'unit_id' => $outcome['unit_id']??0,
                            'tax_amount'=>$outcome['tax_amount']??0,
                            'total_price' => $outcome['total_price']??0,
                            
                        ]);
                    }
                }
                // Raw Materials
                if(isset($request['raw_materials'])){
                    foreach ($request['raw_materials'] as $raw) {

                        BomRm::create([
                            'bom_id' => $bom['id'],
                            'item_id' => $raw['item_id'],
                            'item_name' => $raw['item_name'],
                            'unit_price' => $raw['unit_price'],
                            'qty' => $raw['qty'],
                            'unit_id' => $raw['unit_id']??0,
                            'tax_amount'=>$raw['tax_amount']??0,
                            'total_price' => $raw['total_price']??0,
                            
                        ]);
                    }
                }
                
                // Charges
                if(isset($request['charges'])){
                    foreach ($request->charges as $charge) {

                        BomCharge::create([
                            'bom_id' => $bom['id'],
                            'charges_id' => $charge['charges_id'],
                            'charges_name' => $charge['charges_name'],
                            'charge_amount' => $charge['charge_amount']??0,
                            'notes' => $charge['notes'],
                            'tax_amount' => $charge['tax_amount']??0,
                            'tax_id' => $charge['tax_id']??0,
                            'amount' => $charge['amount']??0,
                        ]);
                    }
                }

                // Packaging
                if(isset($request['packagings'])){
                    foreach ($request['packagings'] as $package) {

                        BomPackaging::create([
                            'bom_id' => $bom['id'],
                            'item_id' => $package['item_id']??0,
                            'item_name' => $package['item_name'],
                            'unit_price' => $package['unit_price']??0,
                            'qty' => $package['qty']??0,
                            'unit_id' => $package['unit_id']??0,
                            'tax_amount'=>$package['tax_amount']??0,
                            'total_price' => $package['total_price']??0,
                        ]);
                    }
                }
                
                // Routings
                if(isset($request['routings'])){

                    foreach ($request['routings'] as $routing) {
                        BomOperation::create([
                            'bom_id' => $bom['id'],
                            'operation_id' => $routing['operation_id']??0,
                            'operation_name' => $routing['operation_name'],
                            'estimate_time' => $routing['estimate_time'],
                        ]);
                    }
                }
                
                // Scraps
                if(isset($request['scraps'])){

                    foreach ($request['scraps'] as $scrap) {
                        BomScrap::create([
                            'bom_id' => $bom['id'],
                            'item_id' => $scrap['item_id']??0,
                            'item_name' => $scrap['item_name'],
                            'qty' => $scrap['qty']??0,
                            'unit_id' => $scrap['unit_id']??0,
                            'notes' => $scrap['notes'],
                        ]);
                    }
                }

                return response()->json(['success' => true, 'message' => 'Bom created successfully','bom'=>$bom], 201);
            } catch (\Exception $e) {
                DB::rollBack();
                return response()->json(['success' => false, 'message' => 'Failed to create bom', 'error' => $e->getMessage()], 500);
            }
        }
            
        
    }
    
    
    // Retrieve BOM details by BOM ID
    public function show(Request $request)
    {
        $validator=validator($request->all(),[
            'bom_id'=>'required|integer'
        ]);

        if ($validator->fails()) { 

            return [
                'success' => false, 
                'message' => $validator->errors()->first(),
                'bom_details' => null
            ];

        } else {

            $bom_id = $request->bom_id;

            $bom = Bom::where('id', $bom_id)
                ->with('bom_outcomes','bom_outcomes.item:id,name,manufacturing_store',
                        'raw_materials','raw_materials.item:id,name,manufacturing_store',
                        'charges',
                        'packagings','packagings.item:id,name,manufacturing_store',
                        'operations',
                        'scraps','item:id,name,manufacturing_store','entry_by',
                        
                )
                ->first();

            if (!$bom) {
                return response()->json(['message' => 'BOM not found'], 404);
            }

            $bomDetails = [
                'bom_details' => $bom,
                'success'=>true,
                'message'=>'BOM details retrieved successfully',
            ];

            return response()->json($bomDetails, 200);
        }
    }

    public function update(Request $request){
        $validator=validator($request->all(),[
            'id'=>'required|integer'
        ]);

        if ($validator->fails()) { 

            return [
                'success' => false, 
                'message' => $validator->errors()->first(),
                'bom_details' => null
            ];

        } else {
             // 1. Retrieve BOM
            $bom = Bom::findOrFail($request->id);

            // 2. Update BOM attributes
            $bom->update([
                'bom_id'=>$request->bom_id,
                'bom_type' => $request->bom_type,
                'item_id' => $request->item_id,
                'qty' => $request->qty,
                'unit_id' => $request->unit_id,
                "rm_cost" => $request->rm_cost ?? 0,
                "packaging_cost" => $request->packaging_cost ?? 0,
                "charges_cost" => $request->charges_cost ?? 0,
                "outcome_cost" => $request->outcome_cost ?? 0,
                "taxes_amount" => $request->taxes_amount ?? 0,
                "subtotal" => $request->subtotal ?? 0,
                "total_cost" => $request->total_cost ?? 0,
                "notes" => $request->notes,
                "attachment" => $request->attachment,
                'status' => $request->status ?? 0,
            ]);

            // Outcome Products
            if(isset($request['bom_outcomes'])){

                BomOutcome::where('bom_id', $bom->id)->delete();
                foreach ($request['bom_outcomes'] as $raw) {

                    BomOutcome::create([
                        'bom_id' => $bom['id'],
                        'item_id' => $raw['item_id'],
                        'item_name' => $raw['item_name'],
                        'unit_price' => $raw['unit_price'],
                        'qty' => $raw['qty'],
                        'unit_id' => $raw['unit_id']??0,
                        'tax_amount'=>$raw['tax_amount']??0,
                        'total_price' => $raw['total_price']??0,
                        
                    ]);
                }
            }

            if(isset($request['raw_materials'])){
                // Delete existing raw materials
                BomRm::where('bom_id', $bom->id)->delete();
            
                // Create new ones
                foreach ($request['raw_materials'] as $raw) {
                    BomRm::create([
                        'bom_id' => $bom->id,
                        'item_id' => $raw['item_id'],
                        'item_name' => $raw['item_name'],
                        'unit_price' => $raw['unit_price'],
                        'qty' => $raw['qty'],
                        'unit_id' => $raw['unit_id'] ?? 0,
                        'tax_amount' => $raw['tax_amount'] ?? 0,
                        'total_price' => $raw['total_price'] ?? 0,
                    ]);
                }
            }

            if(isset($request['charges'])){
                // Delete existing charges
                BomCharge::where('bom_id', $bom->id)->delete();
            
                // Create new ones
                foreach ($request['charges'] as $charge) {
                    BomCharge::create([
                        'bom_id' => $bom->id,
                        'charges_id' => $charge['charges_id'],
                        'charges_name' => $charge['charges_name'],
                        'charge_amount' => $charge['charge_amount'] ?? 0,
                        'notes' => $charge['notes'],
                        'tax_id' => $charge['tax_id'] ?? 0,
                        'tax_amount' => $charge['tax_amount'] ?? 0,
                        'amount' => $charge['amount'] ?? 0,
                    ]);
                }
            }

            if(isset($request['packagings'])){
                // Delete existing packaging
                BomPackaging::where('bom_id', $bom->id)->delete();
            
                // Create new ones
                foreach ($request['packagings'] as $package) {
                    BomPackaging::create([
                        'bom_id' => $bom->id,
                        'item_id' => $package['item_id'] ?? 0,
                        'item_name' => $package['item_name'],
                        'unit_price' => $package['unit_price'] ?? 0,
                        'qty' => $package['qty'] ?? 0,
                        'unit_id' => $package['unit_id'] ?? 0,
                        'tax_amount' => $package['tax_amount'] ?? 0,
                        'total_price' => $package['total_price'] ?? 0,
                    ]);
                }
            }

            if(isset($request['routings'])){
                // Delete existing routings
                BomOperation::where('bom_id', $bom->id)->delete();
            
                // Create new ones
                foreach ($request['routings'] as $routing) {
                    BomOperation::create([
                        'bom_id' => $bom->id,
                        'operation_id' => $routing['operation_id'] ?? 0,
                        'operation_name' => $routing['operation_name'],
                        'estimate_time' => $routing['estimate_time'],
                    ]);
                }
            }

            if(isset($request['scraps'])){
                // Delete existing scraps
                BomScrap::where('bom_id', $bom->id)->delete();
            
                // Create new ones
                foreach ($request['scraps'] as $scrap) {
                    BomScrap::create([
                        'bom_id' => $bom->id,
                        'item_id' => $scrap['item_id'] ?? 0,
                        'item_name' => $scrap['item_name'],
                        'qty' => $scrap['qty'] ?? 0,
                        'unit_id' => $scrap['unit_id'] ?? 0,
                        'notes' => $scrap['notes'],
                    ]);
                }
            }

            return response()->json(['message' => 'BOM updated successfully!','success'=>true,'bom'=>$bom]);
        }

    }

    public function bom_status(Request $request){
        $validator=validator($request->all(),[
            'bom_id'=>'required|integer'
            // 'status'=>'required
        ]);

        if ($validator->fails()) { 

            return [
                'success' => false, 
                'message' => $validator->errors()->first(),
                'bom_details' => null
            ];

        } else {
            try{

                $bom =  Bom::findOrFail($request->input('bom_id'));
 
                if(isset($request['is_active'])){
                    $bom['is_active']=$request['is_active'];
                }

                if(isset($request['status'])){
                    $bom['status']=$request['status'];
                }
               
                $bom->update();
 
                $response=[
                    'success'=>true,
                    'message'=>'Bom Status Updated successfully.'
                ];
 
            } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
 
                // Return error message in JSON if ID not found
                return response()->json(['success'=>false,'message' => 'Invalid Id found'], 404);
            }
 
            return response()->json($response);
        }
    }
    
}   
        