<?php

namespace App\Http\Controllers;

use App\Sale;
use App\SalesItemDetail;
use App\SalesPerBoriWeight;
use App\Customer;
use App\Suppliers;
use App\GoodReceipts;
use App\GoodReceiptTruck;
use App\GoodReceiptDetail;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;

class SalesController extends Controller
{
    // protected $role_id;
    // public function __construct()
    // {
    //     $this->middleware('auth');
    //     $this->middleware(function ($request, $next) {
    //         $this->role_id = Auth::user()->role_id;
    //     //    $slug_filter = preg_replace('/[0-9]+/', '', $request->path());
    //     //    $slug_filter = preg_replace('/[0-9]+/', '', $request->path());
    //     $ex = explode('/',$request->path());
    //     if(count($ex)>=3){
    //         $sliced = array_slice($ex, 0, -1);

    //     }else{
    //         $sliced = $ex;
    //     }

    //     $string = implode("/", $sliced);
    //         if (checkConstructor($this->role_id, count($ex)>=3 ? $string.'/': $string) == 1) {
    //             return $next($request);
    //         }else if(strpos($request->path(), 'store') !== false){
    //             return $next($request);
    //         }else if(strpos($request->path(), 'update') !== false){
    //             return $next($request);
    //         } else {
    //             abort(404);
    //         }
    //     });
    // }

    public function index()
    {
        $sales = Sale::with(['salesItemsDetails', 'salesPerBoriWeight', 'customer', 'goodReceiptTruck', 'goodReceiptTruck.goodReceiptDetails'])->get();
        return view('sales.index', compact('sales'));
    }

    public function create()
    {
        $trucks = GoodReceiptTruck::with('goodReceipts.goodReceiptDetails')->get();
        $customers = Customer::all();
        return view('sales.create', compact('trucks', 'customers'));
    }

    public function store(Request $request)
    {
        // Validate the request data
        $request->validate([
            'sales_date' => 'required|date',
            's_no' => 'required|string',
            'good_receipts_truck_id' => 'required|exists:good_receipts_truck,id_truck',
            'customer_id' => 'required|exists:customers,id_customers',
            'bill_no' => 'required|string',
            'details' => 'nullable|string',
            'bori_details' => 'nullable|string',
            'total_bori' => 'nullable|numeric',
            'remaining_amount' => 'nullable|numeric',
            'cash_received' => 'nullable|numeric',
            'total_amount' => 'nullable|numeric',
            'items_name.*' => 'nullable|string',
            'marka.*' => 'nullable|string',
            'bori.*' => 'nullable|numeric',
            'weight.*' => 'nullable|numeric',
            'rate.*' => 'nullable|numeric',
            'amount.*' => 'nullable|numeric',
            'bori_number.*' => 'nullable|string',
            'per_bori_weight.*' => 'nullable|numeric',
        ]);

        // Sales
        $sale = Sale::create([
            'business_id' => auth()->user()->business_id,
            'good_receipts_truck_id' => $request->good_receipts_truck_id,
            'customer_id' => $request->customer_id,
            'date' => $request->sales_date,
            's_no' => $request->s_no,
            'bill_no' => $request->bill_no,
            'details' => $request->details,
            'bori_details' => $request->bori_details,
            'balance' => $request->remaining_amount,
            'paid' => $request->cash_received,
            'total_amount' => $request->total_amount,
            'status' => $request->sales_status,
            'created_by' => auth()->id(),
        ]);

        // Handle Item Details
        $items = $request->items_name ?? [];
        $marka = $request->marka ?? [];
        $bori = $request->bori ?? [];
        $weight = $request->weight ?? [];
        $rate = $request->rate ?? [];
        $amount = $request->amount ?? [];

        foreach ($items as $index => $item) {
            // Ensure that all related fields are set
            SalesItemDetail::create([
                'sales_id' => $sale->id_sales,
                'items_name' => $item,
                'marka' => $marka[$index] ?? null,
                'bori' => $bori[$index] ?? null,
                'weight' => $weight[$index] ?? null,
                'rate' => $rate[$index] ?? null,
                'amount' => $amount[$index] ?? 0,
                'notes' => 'N/A',
                'status' => '1',
            ]);
        }

        // Handle Additional Bori Details
        $bori_num = $request->bori_number ?? [];
        $bori_weight = $request->per_bori_weight ?? [];

        foreach ($bori_num as $index => $bori) {
            SalesPerBoriWeight::create([
                'sales_id' => $sale->id_sales,
                'bori_number' => $bori,
                'per_bori_weight' => $bori_weight[$index] ?? null,
            ]);
        }

        return redirect()->route('sales.list')->with('success', 'Sale created successfully');
    }

    public function edit($id)
    {
        $sale = Sale::with('salesItemsDetails', 'salesPerBoriWeight')->findOrFail(Crypt::decrypt($id));
        $trucks = GoodReceiptTruck::all();
        $customers = Customer::all();

        return view('sales.edit', compact('sale', 'trucks', 'customers'));
    }

    public function update(Request $request, $id)
    {
        // Validate the request data
        $request->validate([
            'sales_date' => 'required|date',
            's_no' => 'required|string',
            'good_receipts_truck_id' => 'required|exists:good_receipts_truck,id_truck',
            'customer_id' => 'required|exists:customers,id_customers',
            'bill_no' => 'required|string',
            'details' => 'nullable|string',
            'bori_details' => 'nullable|string',
            'total_bori' => 'nullable|numeric',
            'remaining_amount' => 'nullable|numeric',
            'cash_received' => 'nullable|numeric',
            'total_amount' => 'nullable|numeric',
            'items_name.*' => 'nullable|string',
            'marka.*' => 'nullable|string',
            'bori.*' => 'nullable|numeric',
            'weight.*' => 'nullable|numeric',
            'rate.*' => 'nullable|numeric',
            'amount.*' => 'nullable|numeric',
            'item_detail_ids.*' => 'nullable|integer',
            'bori_number.*' => 'nullable|string',
            'per_bori_weight.*' => 'nullable|numeric',
            'bori_detail_ids.*' => 'nullable|integer',
        ]);

        // Start transaction
        DB::beginTransaction();

        try {
            // Find the sale to update
            $sale = Sale::findOrFail(Crypt::decrypt($id));

            // Update sale details
            $sale->update([
                'date' => $request->sales_date,
                's_no' => $request->s_no,
                'good_receipts_truck_id' => $request->good_receipts_truck_id,
                'customer_id' => $request->customer_id,
                'bill_no' => $request->bill_no,
                'details' => $request->details,
                'bori_details' => $request->bori_details,
                'balance' => $request->remaining_amount,
                'paid' => $request->cash_received,
                'total_amount' => $request->total_amount,
                'status' => $request->sales_status,
            ]);

            // Handle SalesItemDetails
            $itemsNames = $request->items_name ?? [];
            $existingItemIds = $request->item_detail_ids ?? [];
            $existingItems = $sale->salesItemsDetails->pluck('id_sid')->toArray();

            foreach ($itemsNames as $index => $itemName) {
                $itemData = [
                    'items_name' => $itemName,
                    'marka' => $request->marka[$index] ?? null,
                    'bori' => $request->bori[$index] ?? null,
                    'weight' => $request->weight[$index] ?? null,
                    'rate' => $request->rate[$index] ?? null,
                    'amount' => $request->amount[$index] ?? 0,
                    'notes' => 'N/A',
                    'status' => '1',
                ];

                $itemId = $request->item_detail_ids[$index] ?? null;

                if ($itemId) {
                    // Update existing item
                    $itemDetail = SalesItemDetail::find($itemId);
                    if ($itemDetail) {
                        $itemDetail->update($itemData);
                    }
                } else {
                    // Create new item
                    $sale->salesItemsDetails()->create($itemData);
                }
            }

            // Delete removed items
            $itemsToDelete = array_diff($existingItems, $existingItemIds);
            SalesItemDetail::whereIn('id_sid', $itemsToDelete)->delete();

            // Handle SalesPerBoriWeight
            $boriNumbers = $request->bori_number ?? [];
            $existingBoriIds = $request->bori_detail_ids ?? [];
            $existingBoris = $sale->salesPerBoriWeight->pluck('id_sales_per_bw')->toArray();

            foreach ($boriNumbers as $index => $boriNumber) {
                $boriData = [
                    'bori_number' => $boriNumber,
                    'per_bori_weight' => $request->per_bori_weight[$index] ?? null,
                ];

                $boriId = $request->bori_detail_ids[$index] ?? null;

                if ($boriId) {
                    // Update existing bori detail
                    $boriDetail = SalesPerBoriWeight::find($boriId);
                    if ($boriDetail) {
                        $boriDetail->update($boriData);
                    }
                } else {
                    // Create new bori detail
                    $boriData['sales_id'] = $sale->id_sales;
                    SalesPerBoriWeight::create($boriData);
                }
            }

            // Delete removed bori details
            $borisToDelete = array_diff($existingBoris, $existingBoriIds);
            SalesPerBoriWeight::whereIn('id_sales_per_bw', $borisToDelete)->delete();

            // Commit transaction
            DB::commit();

            return redirect()->route('sales.list')->with('success', 'Sale updated successfully');
        } catch (\Exception $e) {
            // Rollback transaction
            DB::rollBack();
            return redirect()->back()->with('error', 'Error updating sale: ' . $e->getMessage());
        }
    }

    public function destroy($id)
    {
        $sale = Sale::findOrFail(Crypt::decrypt($id));
        $sale->delete();
        return redirect()->route('sales.list')->with('success', 'Sale deleted successfully');
    }

    public function getItemsByTruck($truckId)
    {
        $items = GoodReceiptDetail::where('truck_id', $truckId)->pluck('goods_name', 'id_grd')->toArray();
        $markas = GoodReceiptDetail::where('truck_id', $truckId)->pluck('marka')->unique()->toArray();

        return response()->json([
            'items' => $items,
            'markas' => $markas
        ]);
    }

    public function getItemsByMarka($truckId, $marka)
    {
        $items = GoodReceiptDetail::where('truck_id', $truckId)->where('marka', $marka)->pluck('goods_name', 'id_grd')->toArray();

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

    public function getItemDetails(Request $request)
    {
        $marka = $request->input('marka');
        $item = $request->input('item');

        // Fetch the item details based on Marka and Item
        $itemDetails = GoodReceiptDetail::where('marka', $marka)
            ->where('goods_name', $item)
            ->first();

        // echo $itemDetails->bori;

        if ($itemDetails) {
            return response()->json([
                'bori' => $itemDetails->bori,
                'weight' => $itemDetails->weight,
                'rate' => $itemDetails->rate,
            ]);
        }

        return response()->json([], 404);
    }


}
