<?php

namespace App\Http\Controllers;

use App\Customer;
use App\GoodReceiptDetail;
use App\GoodReceiptTruck;
use App\Sale;
use App\Suppliers;
use App\SupplierAccount;
use App\BCheque;
use App\BChequeItem;
use App\BChequeDetail;
use App\GeneralPreferrences;
use App\GeneralPrefrence;
use App\ProductsCategoryMain;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;

class BchequeController extends Controller
{


    protected string $module = 'B-Cheque';

    public function __construct()
    {
        $module = $this->module;

        $this->middleware("permission:$module list")->only(['index']);
        $this->middleware("permission:$module view")->only(['show']);
        $this->middleware("permission:$module add")->only(['create', 'store']);
        $this->middleware("permission:$module edit")->only(['edit', 'update']);
        $this->middleware("permission:$module delete")->only(['destroy']);
    }
    public function index()
    {
        // Fetch all B-Cheques with related data
        $b_cheques = BCheque::with([
            'details',
            'items',
            'supplier',
            'goodReceiptTruck',
            'goodReceiptTruck.goodReceiptDetails'
        ])->latest()->get();


        // Initialize an array to store merged items for each B-Cheque
        $mergedBCheques = [];

        // Loop through each B-Cheque
        foreach ($b_cheques as $bCheque) {
            $mergedItems = [];

            // Loop through each item of the current B-Cheque
            foreach ($bCheque->items as $item) {
                // Generate a unique key based on the criteria you're matching
                $key = $item->main_cate . '_' . $item->parent_cate . '_' . $item->child_cate . '_' . $item->marka . '_' . $item->rate;
                // dd($bCheque->items );
                // Check if the combination already exists in the mergedItems array
                if (isset($mergedItems[$key])) {
                    // Add the bori, weight, and amount to the existing values
                    $mergedItems[$key]['bori'] += $item->bori;
                    $mergedItems[$key]['weight'] += $item->weight;
                    $mergedItems[$key]['amount'] += $item->amount;
                } else {
                    // If it's a new combination, add it to the mergedItems array
                    $mergedItems[$key] = [
                        'main_cate' => $item->productMainCate?->products_category_name,
                        'parent_cate' => $item->productParentCate?->name,
                        'child_cate' => $item->productChildCate?->name,
                        'marka' => $item->marka,
                        'rate' => $item->rate,
                        'bori' => $item->bori,
                        'weight' => $item->weight,
                        'amount' => $item->amount,
                    ];
                }
            }

            // Store the merged items back into the B-Cheque object
            $bCheque->mergedItems = $mergedItems;

            // Add the modified B-Cheque with merged items to the final array
            $mergedBCheques[] = $bCheque;
        }

        return view('b_cheque.index', compact('mergedBCheques', 'b_cheques'));
    }


    public function create()
    {
        // Fetch unique trucks that have associated sales items details
        $soldTrucks = Sale::whereHas('salesItemsDetails')
            ->with('goodReceiptTruck')
            ->get()
            ->pluck('goodReceiptTruck')
            ->whereNotNull()
            ->unique('id_truck'); // Ensure unique trucks by truck ID
        // dd($soldTrucks);

        // Fetch sales with related data (eager load relationships to optimize queries)
        $sales = Sale::with([
            'salesItemsDetails',
            'salesPerBoriWeight',
            'productMainCate',
            'productParentCate',
            'productChildCate',
            'customer',
            'goodReceiptTruck',
            'goodReceiptTruck.goodReceiptDetails',
            'goodReceiptTruck.goodReceiptDetails.goodReceipt.supplier' // Get supplier details through good receipts
        ])->latest()->get();

        $gen_pref = GeneralPrefrence::all();
        $productCateMain = ProductsCategoryMain::all();

        // Fetch suppliers directly for dropdown or other form usage
        $suppliers = Suppliers::all();

        // Return the data to the view
        return view('b_cheque.create', compact('soldTrucks', 'suppliers', 'productCateMain', 'sales', 'gen_pref'));
    }

    public function store(Request $request)
    {

        // Validate the request data
        $validatedData = $request->validate([
            'bCheck_date' => 'required|date',
            'pb_no' => 'nullable|string|max:255',
            'good_receipts_truck_id' => 'required|integer|exists:good_receipts_truck,id_truck',
            'suppliers' => 'required|integer|exists:suppliers,id_supplier',
            'get_supplier_name' => 'nullable|string',
            'bilty_no' => 'nullable|string|max:255',
            'details' => 'nullable|string|max:255',
            'bCheck_status' => 'required|boolean',
            'total_amount' => 'nullable|string',
            'total_expanse_amount' => 'nullable|string',
            'save_amount' => 'nullable|string',
            'total_bori' => 'nullable|string',
            'total_weight' => 'nullable|string',
            'commission_rate' => 'nullable|string|max:100',
            'commission' => 'nullable|string',
            'extra_pay' => 'nullable|string',
            'payment_details' => 'nullable|string',
            'rent_received' => 'nullable|string',
            'labour' => 'nullable|string',
            'total_katta' => 'nullable|string',
            'labour_katta' => 'nullable|string',
            'market_fees' => 'nullable|string',
            'post_expense' => 'nullable|string',
            'miscellaneous_expense' => 'nullable|string',
            'cash' => 'nullable|string',
            'salesDeId.*' => 'required|integer',
            'mainCate.*' => 'nullable|string|max:255',
            'parentCate.*' => 'nullable|string|max:255',
            'childCate.*' => 'nullable|string|max:255',
            'marka.*' => 'nullable|string|max:255',
            'bori.*' => 'nullable|string',
            'weight.*' => 'nullable|string',
            'rate.*' => 'nullable|string',
            'amount.*' => 'nullable|string',
        ]);
        // dd($validatedData['commission']);
        // Store the BCheque data
        $bCheque = BCheque::create([
            'business_id' => auth()->user()->business_id,
            'good_receipts_truck_id' => $validatedData['good_receipts_truck_id'],
            'customer_id' => null,
            'supplier_id' => $validatedData['suppliers'],
            'supplier_name' => $validatedData['get_supplier_name'],
            'date' => $validatedData['bCheck_date'],
            'pb_no' => $validatedData['pb_no'],
            'bilty_no' => $validatedData['bilty_no'],
            'detail' => $validatedData['details'],
            'status' => $validatedData['bCheck_status'],
            'created_by' => auth()->user()->id,
        ]);

        // Store BCheque Items data
        if (!empty($validatedData['mainCate'])) {
            foreach ($validatedData['mainCate'] as $index => $mainCate) {
                if ($mainCate && isset($validatedData['parentCate'][$index])) {
                    BChequeItem::create([
                        'b_cheque_id' => $bCheque->id_b_cheque,
                        'sales_d_id' => $validatedData['salesDeId'][$index],
                        'main_cate' => $mainCate,
                        'parent_cate' => $validatedData['parentCate'][$index],
                        'child_cate' => $validatedData['childCate'][$index],
                        'marka' => $validatedData['marka'][$index],
                        'bori' => $validatedData['bori'][$index],
                        'weight' => $validatedData['weight'][$index],
                        'rate' => $validatedData['rate'][$index],
                        'amount' => $validatedData['amount'][$index],
                        'created_by' => auth()->user()->id,
                    ]);
                }
            }
        }

        // Store BCheque Details data
        $bChequeDetail = BChequeDetail::create([
            'b_cheque_id' => $bCheque->id_b_cheque,
            'rent_recieve_amount' => $validatedData['rent_received'],
            'labour_amount' => $validatedData['labour'],
            'total_katta' => $validatedData['total_katta'],
            'labour_katta_amount' => $validatedData['labour_katta'],
            'market_fees_amount' => $validatedData['market_fees'],
            'post_expense_amount' => $validatedData['post_expense'],
            'miscellaneous_expense_amount' => $validatedData['miscellaneous_expense'],
            'cash_amount' => $validatedData['cash'],
            'commission_rate' => $validatedData['commission_rate'],
            'commission_amount' => $validatedData['commission'],
            'else_more_amount' => $validatedData['extra_pay'],
            'payment_details' => $validatedData['payment_details'],
            'total_bori' => $validatedData['total_bori'],
            'total_weight' => $validatedData['total_weight'],
            'total_amount' => $validatedData['total_amount'],
            'total_expanse_amount' => $validatedData['total_expanse_amount'],
            'save_amount' => $validatedData['save_amount'],
            'created_by' => auth()->user()->id,
        ]);

        // Update or Create SupplierAccount
        $supplierAccount = SupplierAccount::where('suppliers_id', $validatedData['suppliers'])->first();

        if ($supplierAccount) {
            // If the supplier account exists, update the debit amount
            $supplierAccount->debit += $validatedData['save_amount'];
            $supplierAccount->save();
        } else {
            // If no supplier account exists, create a new one
            SupplierAccount::create([
                'suppliers_id' => $validatedData['suppliers'],
                'debit' => $validatedData['save_amount'],
                'credit' => '0',
                'balance' => '0',
            ]);
        }

        // Redirect with success message
        return redirect()->route('b_cheque.list')->with('success', 'B-Cheque has been created successfully.');
    }

    public function edit($id)
    {
        $id = Crypt::decrypt($id);
        $productCateMain = ProductsCategoryMain::all();
        $b_cheque = BCheque::with(['details', 'items', 'supplier', 'goodReceiptTruck', 'goodReceiptTruck.goodReceiptDetails'])->findOrFail($id);
        // $b_cheque = BCheque::with(['items', 'details'])->findOrFail($id);
        $trucks = GoodReceiptTruck::with('goodReceipts.goodReceiptDetails')->get();

        // Fetch unique trucks that have associated sales items details
        $soldTrucks = Sale::whereHas('salesItemsDetails')
            ->with('goodReceiptTruck')
            ->get()
            ->pluck('goodReceiptTruck')
            ->whereNotNull()
            ->unique('id_truck'); // Ensure unique trucks by truck ID

        // Fetch sales with related data (eager load relationships to optimize queries)
        $sales = Sale::with([
            'salesItemsDetails',
            'salesPerBoriWeight',
            'customer',
            'goodReceiptTruck',
            'goodReceiptTruck.goodReceiptDetails',
            'goodReceiptTruck.goodReceiptDetails.goodReceipt.supplier'
        ])->get();

        $gen_pref = GeneralPrefrence::all();

        $suppliers = Suppliers::all();

        $mergedItems = [];

        foreach ($b_cheque->items as $item) {
            // Generate a unique key based on the criteria you're matching
            $key = $item->main_cate . '_' . $item->parent_cate . '_' . $item->child_cate . '_' . $item->marka . '_' . $item->rate;

            // Check if the combination already exists in the mergedItems array
            if (isset($mergedItems[$key])) {
                // Add the bori, weight, and amount to the existing values
                $mergedItems[$key]['bori'] += $item->bori;
                $mergedItems[$key]['weight'] += $item->weight;
                $mergedItems[$key]['amount'] += $item->amount;
            } else {
                // If it's a new combination, add it to the mergedItems array
                $mergedItems[$key] = [
                    'main_cate' => $item->main_cate,
                    'parent_cate' => $item->parent_cate,
                    'child_cate' => $item->child_cate,
                    'marka' => $item->marka,
                    'rate' => $item->rate,
                    'bori' => $item->bori,
                    'weight' => $item->weight,
                    'amount' => $item->amount,
                    'sales_d_id' => $item->sales_d_id,
                ];
            }
        }

        return view('b_cheque.edit', compact('b_cheque', 'productCateMain', 'trucks', 'suppliers', 'soldTrucks', 'sales', 'gen_pref', 'mergedItems'));
    }

    public function update(Request $request, $id)
    {
        // Decrypt the ID
        $b_cheque_id = Crypt::decrypt($id);

        // Validate the request data

        $validatedData = $request->validate([
            'bCheck_date' => 'required|date',
            'pb_no' => 'nullable|string|max:255',
            'good_receipts_truck_id' => 'required|integer|exists:good_receipts_truck,id_truck',
            'suppliers' => 'required|integer|exists:suppliers,id_supplier',
            'get_supplier_name' => 'nullable|string',
            'bilty_no' => 'nullable|string|max:255',
            'details' => 'nullable|string|max:255',
            'bCheck_status' => 'required|boolean',
            'total_amount' => 'nullable|string',
            'total_expanse_amount' => 'nullable|string',
            'save_amount' => 'nullable|string',
            'total_bori' => 'nullable|string',
            'total_weight' => 'nullable|string',
            'commission_rate' => 'nullable|string|max:100',
            'commission' => 'nullable|string',
            'extra_pay' => 'nullable|string',
            'payment_details' => 'nullable|string',
            'rent_received' => 'nullable|string',
            'labour' => 'nullable|string',
            'total_katta' => 'nullable|string',
            'labour_katta' => 'nullable|string',
            'market_fees' => 'nullable|string',
            'post_expense' => 'nullable|string',
            'miscellaneous_expense' => 'nullable|string',
            'cash' => 'nullable|string',
            'salesDeId.*' => 'required|integer',
            'mainCate.*' => 'nullable|string|max:255',
            'parentCate.*' => 'nullable|string|max:255',
            'childCate.*' => 'nullable|string|max:255',
            'marka.*' => 'nullable|string|max:255',
            'bori.*' => 'nullable|string',
            'weight.*' => 'nullable|string',
            'rate.*' => 'nullable|string',
            'amount.*' => 'nullable|string',
        ]);

        try {
            // Start Transaction
            DB::beginTransaction();

            // Find the b_cheque record
            $b_cheque = BCheque::findOrFail($b_cheque_id);

            // Update the main b_cheque details
            $b_cheque->update([
                'business_id' => auth()->user()->business_id,
                'good_receipts_truck_id' => $validatedData['good_receipts_truck_id'],
                'supplier_id' => $validatedData['suppliers'],
                'supplier_name' => $validatedData['get_supplier_name'],
                'date' => $validatedData['bCheck_date'],
                'pb_no' => $validatedData['pb_no'],
                'bilty_no' => $validatedData['bilty_no'],
                'detail' => $validatedData['details'],
                'status' => $validatedData['bCheck_status'],

            ]);

            // Delete existing items
            $b_cheque->items()->delete();

            // Store BCheque Items data
            if (!empty($validatedData['mainCate'])) {
                foreach ($validatedData['mainCate'] as $index => $mainCate) {
                    if ($mainCate && isset($validatedData['parentCate'][$index])) {
                        BChequeItem::create([
                            'b_cheque_id' => $b_cheque->id_b_cheque,
                            'sales_d_id' => $validatedData['salesDeId'][$index],
                            'main_cate' => $mainCate,
                            'parent_cate' => $validatedData['parentCate'][$index],
                            'child_cate' => $validatedData['childCate'][$index],
                            'marka' => $validatedData['marka'][$index],
                            'bori' => $validatedData['bori'][$index],
                            'weight' => $validatedData['weight'][$index],
                            'rate' => $validatedData['rate'][$index],
                            'amount' => $validatedData['amount'][$index],
                            'created_by' => auth()->user()->id,

                        ]);
                    }
                }
            }

            // Update or Create BChequeDetail
            $b_cheque_detail = $b_cheque->details()->first();

            if ($b_cheque_detail) {
                $b_cheque_detail->update([
                    'rent_recieve_amount' => $validatedData['rent_received'],
                    'labour_amount' => $validatedData['labour'],
                    'total_katta' => $validatedData['total_katta'],
                    'labour_katta_amount' => $validatedData['labour_katta'],
                    'market_fees_amount' => $validatedData['market_fees'],
                    'post_expense_amount' => $validatedData['post_expense'],
                    'miscellaneous_expense_amount' => $validatedData['miscellaneous_expense'],
                    'cash_amount' => $validatedData['cash'],
                    'commission_rate' => $validatedData['commission_rate'],
                    'commission_amount' => $validatedData['commission'],
                    'else_more_amount' => $validatedData['extra_pay'],
                    'payment_details' => $validatedData['payment_details'],
                    'total_bori' => $validatedData['total_bori'],
                    'total_weight' => $validatedData['total_weight'],
                    'total_amount' => $validatedData['total_amount'],
                    'total_expanse_amount' => $validatedData['total_expanse_amount'],
                    'save_amount' => $validatedData['save_amount'],


                ]);
            } else {
                BChequeDetail::create([
                    'b_cheque_id' => $b_cheque->id_b_cheque,
                    'rent_recieve_amount' => $validatedData['rent_received'],
                    'labour_amount' => $validatedData['labour'],
                    'market_fees_amount' => $validatedData['market_fees'],
                    'post_expense_amount' => $validatedData['post_expense'],
                    'miscellaneous_expense_amount' => $validatedData['miscellaneous_expense'],
                    'cash_amount' => $validatedData['cash'],
                    'commission_rate' => $validatedData['commission_rate'],
                    'commission_amount' => $validatedData['commission'],
                    'else_more_amount' => $validatedData['extra_pay'],
                    'payment_details' => $validatedData['payment_details'],
                    'total_bori' => $validatedData['total_bori'],
                    'total_weight' => $validatedData['total_weight'],
                    'total_amount' => $validatedData['total_amount'],
                    'total_expanse_amount' => $validatedData['total_expanse_amount'],
                    'save_amount' => $validatedData['save_amount'],
                    'created_by' => auth()->user()->id,

                ]);
            }

            // Commit Transaction
            DB::commit();

            // Redirect with success message
            return redirect()->route('b_cheque.list')->with('success', 'B-Cheque has been updated successfully.');
        } catch (\Exception $e) {
            // Rollback Transaction
            DB::rollBack();

            // Redirect back with error message
            return redirect()->back()->with('error', 'An error occurred while updating the B-Cheque. Please try again.');
        }
    }

    public function destroy($id)
    {
        try {
            // Decrypt the ID
            $b_cheque_id = Crypt::decrypt($id);

            // Find the B-Cheque record
            $b_cheque = BCheque::findOrFail($b_cheque_id);

            // Delete associated items and details
            $b_cheque->items()->delete();
            $b_cheque->details()->delete();

            // Delete the main B-Cheque record
            $b_cheque->delete();

            // Redirect with success message
            return redirect()->route('b_cheque.list')->with('success', 'B-Cheque has been deleted successfully.');
        } catch (\Exception $e) {
            // Redirect back with error message
            return redirect()->back()->with('error', 'An error occurred while deleting the B-Cheque. Please try again.');
        }
    }

    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 bChequeInvoicePrintView($id)
    {
        $dec_id = Crypt::decrypt($id);
        $b_cheque = BCheque::with('goodReceiptTruck', 'supplier', 'customer', 'items', 'details', 'items.sales')->where('id_b_cheque', $dec_id)->first();
        return view('b_cheque.invoice_print_view', compact('b_cheque'));
    }
}
