<?php

namespace App\Service\Purchase;

use App\Models\purchase_maker_masters;
use App\Models\PurchaseDetails;
use App\Models\PurchaseMaster;
use App\Models\PurchasePayment;
use App\Models\PurchaseReturnDetails;
use App\Models\PurchaseReturnMaster;
use App\Models\ShopWarehouseStocks;
use App\Models\WarehouseStock;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class PurchaseService
{
    public static function PurchaseStore(array $data)
    {

        DB::beginTransaction();

        try {

            $collect = collect($data);

            // Calculate sub_total from child detail totals
            $subTotal = 0;
            foreach ($collect['list'] as $row) {
                $subTotal += (float) ($row['total'] ?? 0);
            }

            // Compute global discount on backend to match frontend
            $discount = (float) ($collect['discount'] ?? 0);
            $discountType = $collect['discount_type'] ?? 'flat';

            $discountAmount = 0.0;
            if ($discountType === 'percentage') {
                $discountAmount = ($subTotal * $discount) / 100;
            } elseif ($discountType === 'flat') {
                $discountAmount = $discount;
            }

            // Round discount to 2 decimals, then compute rounded total (0 decimals)
            $afterDiscount = round($discountAmount, 2);
            $netAfterDiscount = $subTotal - $afterDiscount;
            if ($netAfterDiscount < 0) {
                $netAfterDiscount = 0;
            }
            $vatAmountTotal = round((float) ($collect['vat_amount_total'] ?? 0), 2);
            $total = round($netAfterDiscount + $vatAmountTotal, 0);

            // Create purchase Master
            $master_id = PurchaseMaster::create([
                'invoice_no' => $collect['invoice_no'],
                'purchase_date' => $collect['purchase_date'],
                'supplier_id' => isset($collect['supplier_id']) ? $collect['supplier_id'] : null,
                'po_ref' => isset($collect['po_ref']) ? $collect['po_ref'] : null,
                'warehouse_id' => isset($collect['warehouse_id']) ? $collect['warehouse_id'] : null,
                'shop_warehouse_id' => isset($collect['shop_warehouse_id']) ? $collect['shop_warehouse_id'] : null,
                'shop_id' => Auth::user()->shop_id,
                'created_by' => Auth::user()->id,
                'lc_module_id' => isset($collect['lc_module_id']) ? $collect['lc_module_id'] : null,
                'discount' => isset($collect['discount']) ? $collect['discount'] : null,
                'discount_type' => isset($collect['discount_type']) ? $collect['discount_type'] : null,
                'after_discount' => $afterDiscount,
                'vat_amount_total' => $vatAmountTotal,
                'sub_total' => $subTotal,
                'total' => $total,
            ]);

            foreach ($collect['list'] as $key => $value) {
                // "batch_no" => "12,122,2"
                $prepared_batch_no = explode(',', $value['batch_no'] ?? '');
                // batch no batch_wise_qty
                $batch_wise_qty = explode(',', $value['batch_wise_qty'] ?? '');
                $exp_date = $value['exp_date'] ?? [];

                if ($prepared_batch_no && count($prepared_batch_no) > 1) {

                    for ($i = 0; $i < count($prepared_batch_no); $i++) {

                        $value['batch_no'] = $prepared_batch_no[$i];
                        $value['quantity'] = isset($batch_wise_qty[$i]) ? (float) $batch_wise_qty[$i] : 1;
                        $value['exp_date'] = isset($exp_date[$i]) ? $exp_date[$i] : null;

                        PurchaseDetails::create([
                            'purchase_master_id' => $master_id->id,
                            'product_id' => $value['product_id'],
                            'attribute_id' => $value['attribute_id'],
                            'quantity' => $value['quantity'],
                            'base_quantity' => $value['quantity'],
                            'mfg_date' => (isset($value['mfg_date']) && $value['mfg_date'] != 'NaN-NaN-NaN') ? $value['mfg_date'] : null,
                            'exp_date' => (isset($value['exp_date']) && $value['exp_date'] != 'NaN-NaN-NaN') ? $value['exp_date'] : null,
                            'vat' => isset($value['vat']) ? $value['vat'] : 0,
                            'tax' => isset($value['tax']) ? $value['tax'] : 0,
                            'unit_price' => $value['unit_price'],
                            'batch_no' => isset($value['batch_no']) ? $value['batch_no'] : null,
                            'tp_price' => $value['tp_price'],
                            'mrp_price' => $value['mrp_price'],
                            'unit_price_total' => round($value['total'] / count($prepared_batch_no), 0),
                            'shop_id' => Auth::user()->shop_id,
                            'pack_qty' => isset($value['pack_qty']) ? $value['pack_qty'] : 0,
                            'pack_price' => isset($value['pack_price']) ? $value['pack_price'] : 0,
                            'gift_qty' => isset($value['gift_qty']) ? $value['gift_qty'] : 0,
                            'discount' => isset($value['discount']) ? $value['discount'] : 0,
                            'conversion_input' => isset($value['conversion_input']) ? $value['conversion_input'] : null,
                        ]);
                    }
                } else {
                    PurchaseDetails::create([
                        'purchase_master_id' => $master_id->id,
                        'product_id' => $value['product_id'],
                        'attribute_id' => $value['attribute_id'],
                        'quantity' => $value['quantity'],
                        'base_quantity' => $value['quantity'],
                        'mfg_date' => (isset($value['mfg_date']) && $value['mfg_date'] != 'NaN-NaN-NaN') ? $value['mfg_date'] : null,
                        'exp_date' => (isset($value['exp_date'][0]) && $value['exp_date'][0] != 'NaN-NaN-NaN') ? $value['exp_date'][0] : null,
                        'vat' => isset($value['vat']) ? $value['vat'] : 0,
                        'tax' => isset($value['tax']) ? $value['tax'] : 0,
                        'unit_price' => $value['unit_price'],
                        'batch_no' => isset($value['batch_no']) ? $value['batch_no'] : null,
                        'tp_price' => $value['tp_price'],
                        'mrp_price' => $value['mrp_price'],
                        'unit_price_total' => round($value['total'], 0),
                        'shop_id' => Auth::user()->shop_id,
                        'pack_qty' => isset($value['pack_qty']) ? $value['pack_qty'] : 0,
                        'pack_price' => isset($value['pack_price']) ? $value['pack_price'] : 0,
                        'gift_qty' => isset($value['gift_qty']) ? $value['gift_qty'] : 0,
                        'discount' => isset($value['discount']) ? $value['discount'] : 0,
                        'conversion_input' => isset($value['conversion_input']) ? $value['conversion_input'] : null,

                    ]);
                }
            }
            //  Purchase Masert Status Change
            if (isset($collect['warehouse_id'])) {
                // self::store_warehouse($collect);
                PurchaseMaster::where('id', $master_id->id)->update([
                    'status' => 2,
                    'purchase_received_date' => Carbon::now(),
                ]);
            } elseif (isset($collect['shop_warehouse_id'])) {
                // self::store_shop_warehouse($collect);
                PurchaseMaster::where('id', $master_id->id)->update([
                    'status' => 2,
                    'purchase_received_date' => Carbon::now(),
                ]);
            } else {
                PurchaseMaster::where('id', $master_id->id)->update([
                    'status' => 1,
                ]);
                // change Purchase Maker Status
                if (isset($collect['purchase_maker_id'])) {
                    purchase_maker_masters::where('id', $collect['purchase_maker_id'])->update([
                        'status' => 1,
                    ]);
                }
            }
            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            throw $e;
        }
    }

    public static function PurchaseUpdate($data, $id)
    {

        DB::beginTransaction();

        try {

            $collect = collect($data);

            // Sum all product totals for sub_total
            $subTotal = 0;
            foreach ($collect['list'] as $row) {
                $subTotal += (float) ($row['total'] ?? 0);
            }

            // Compute global discount on backend (same rules as store)
            $discount = (float) ($collect['discount'] ?? 0);
            $discountType = $collect['discount_type'] ?? 'flat';

            $discountAmount = 0.0;
            if ($discountType === 'percentage') {
                $discountAmount = ($subTotal * $discount) / 100;
            } elseif ($discountType === 'flat') {
                $discountAmount = $discount;
            }

            $afterDiscount = round($discountAmount, 2);
            $netAfterDiscount = $subTotal - $afterDiscount;
            if ($netAfterDiscount < 0) {
                $netAfterDiscount = 0;
            }
            $vatAmountTotal = round((float) ($collect['vat_amount_total'] ?? 0), 2);
            $total = round($netAfterDiscount + $vatAmountTotal, 0);

            // Sum all product total
            $old_purchase = PurchaseDetails::where('purchase_master_id', $id)->get()->toArray();

            // Update purchase Master
            $master_id = PurchaseMaster::where('id', $id)->update([
                'purchase_maker_id' => isset($collect['purchase_maker_id']) ? $collect['purchase_maker_id'] : null,
                'purchase_date' => $collect['purchase_date'],
                'supplier_id' => isset($collect['supplier_id']) ? $collect['supplier_id'] : null,
                'po_ref' => isset($collect['po_ref']) ? $collect['po_ref'] : null,
                'warehouse_id' => isset($collect['warehouse_id']) ? $collect['warehouse_id'] : DB::raw('warehouse_id'),
                'shop_warehouse_id' => isset($collect['shop_warehouse_id']) ? $collect['shop_warehouse_id'] : DB::raw('shop_warehouse_id'),
                'updated_by' => Auth::user()->id,
                'lc_module_id' => isset($collect['lc_module_id']) ? $collect['lc_module_id'] : null,
                'discount' => isset($collect['discount']) ? $collect['discount'] : null,
                'discount_type' => isset($collect['discount_type']) ? $collect['discount_type'] : null,
                'after_discount' => $afterDiscount,
                'vat_amount_total' => $vatAmountTotal,
                'sub_total' => $subTotal,
                'total' => $total,
            ]);
            // Delete Previouse Data form Purchase Details
            PurchaseDetails::where('purchase_master_id', $id)->delete();
            // Update Purchase Details
            foreach ($collect['list'] as $key => $value) {

                // "batch_no" => "12,122,2"
                $prepared_batch_no = explode(',', $value['batch_no'] ?? '');
                // batch no batch_wise_qty
                $batch_wise_qty = explode(',', $value['batch_wise_qty'] ?? '');
                $exp_date = $value['exp_date'] ?? [];

                if ($prepared_batch_no && count($prepared_batch_no) > 1) {

                    for ($i = 0; $i < count($prepared_batch_no); $i++) {

                        $value['batch_no'] = $prepared_batch_no[$i];
                        $value['quantity'] = isset($batch_wise_qty[$i]) ? (float) $batch_wise_qty[$i] : 1;
                        $value['exp_date'] = isset($exp_date[$i]) ? $exp_date[$i] : null;

                        PurchaseDetails::create([
                            'purchase_master_id' => $id,
                            'product_id' => $value['product_id'],
                            'attribute_id' => $value['attribute_id'],
                            'quantity' => $value['quantity'],
                            'base_quantity' => $value['quantity'],
                            'unit_price' => $value['unit_price'],
                            'tp_price' => $value['tp_price'],
                            'mrp_price' => $value['mrp_price'],
                            'unit_price_total' => round($value['total'], 0),
                            'vat' => isset($value['vat']) ? $value['vat'] : 0,
                            'tax' => isset($value['tax']) ? $value['tax'] : 0,
                            'mfg_date' => (isset($value['mfg_date']) && $value['mfg_date'] != 'NaN-NaN-NaN') ? $value['mfg_date'] : null,
                            'exp_date' => (isset($value['exp_date']) && $value['exp_date'] != 'NaN-NaN-NaN') ? $value['exp_date'] : null,
                            'batch_no' => isset($value['batch_no']) ? $value['batch_no'] : null,
                            'gift_qty' => isset($value['gift_qty']) ? $value['gift_qty'] : 0,
                            'discount' => isset($value['discount']) ? $value['discount'] : 0,
                            'pack_qty' => isset($value['pack_qty']) ? $value['pack_qty'] : 0,
                            'pack_price' => isset($value['pack_price']) ? $value['pack_price'] : 0,
                            'conversion_input' => isset($value['conversion_input']) ? $value['conversion_input'] : null,
                        ]);
                    }
                } else {

                    PurchaseDetails::create([
                        'purchase_master_id' => $id,
                        'product_id' => $value['product_id'],
                        'attribute_id' => $value['attribute_id'],
                        'quantity' => $value['quantity'],
                        'base_quantity' => $value['quantity'],
                        'unit_price' => $value['unit_price'],
                        'tp_price' => $value['tp_price'],
                        'mrp_price' => $value['mrp_price'],
                        'unit_price_total' => round($value['total'], 0),
                        'vat' => isset($value['vat']) ? $value['vat'] : 0,
                        'tax' => isset($value['tax']) ? $value['tax'] : 0,
                        'mfg_date' => (isset($value['mfg_date']) && $value['mfg_date'] != 'NaN-NaN-NaN') ? $value['mfg_date'] : null,
                        'exp_date' => (isset($value['exp_date'][0]) && $value['exp_date'][0] != 'NaN-NaN-NaN') ? $value['exp_date'][0] : null,
                        'batch_no' => isset($value['batch_no']) ? $value['batch_no'] : null,
                        'gift_qty' => isset($value['gift_qty']) ? $value['gift_qty'] : 0,
                        'discount' => isset($value['discount']) ? $value['discount'] : 0,
                        'pack_qty' => isset($value['pack_qty']) ? $value['pack_qty'] : 0,
                        'pack_price' => isset($value['pack_price']) ? $value['pack_price'] : 0,
                        'conversion_input' => isset($value['conversion_input']) ? $value['conversion_input'] : null,
                    ]);
                }
            }
            //  Purchase Masert Status Change
            if (isset($collect['warehouse_id'])) {
                // self::store_warehouse($collect, $old_purchase, $id);
                PurchaseMaster::where('id', $id)->update([
                    'status' => 2,
                    'purchase_received_date' => Carbon::now(),
                ]);
            } elseif (isset($collect['shop_warehouse_id'])) {
                // self::store_shop_warehouse($collect, $old_purchase, $id);
                PurchaseMaster::where('id', $id)->update([
                    'status' => 2,
                    'purchase_received_date' => Carbon::now(),
                ]);
            } else {
                PurchaseMaster::where('id', $id)->update([
                    'status' => 1,
                ]);
            }

            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            throw $e;
        }
    }

    public static function store_warehouse($data, $old_purchase = [], $id = '')
    {

        // Old Stock Data Remove
        foreach ($old_purchase as $key => $old_value) {
            $existing = WarehouseStock::when(setting()->business_id == 3, fn ($q) => $q->where('batch_no', $old_value['batch_no']))->where('product_id', $old_value['product_id'])->where('attribute_id', $old_value['attribute_id'])->where('warehouse_id', $data['warehouse_id'])->first();
            if ($existing) {
                WarehouseStock::where('id', $existing->id)->update([
                    'product_id' => $old_value['product_id'],
                    'attribute_id' => $old_value['attribute_id'],
                    'quantity' => DB::raw('quantity-'.$old_value['quantity'] + $old_value['gift_qty'] ?? 0),
                    // 'salse' =>  $old_value['salse'],
                    // 'purchase' => ($existing->purchase_total - ($old_value['purchase'] * $old_value['quantity']) ) / ($existing->quantity + $old_value['quantity']),
                    // 'unit_price_total' =>  (float)str_replace(',', '', $existing->unit_price_total - $old_value['unit_price'] * $old_value['quantity']),
                    // 'tp_price_total' =>  (float)str_replace(',', '', $existing->tp_price_total - ($old_value['tp_price'] * $old_value['quantity'])),
                    // 'mrp_price_total' =>  (float)str_replace(',', '', $existing->mrp_price_total - ($old_value['mrp_price'] * $old_value['quantity'])),
                ]);
            }
        }

        foreach ($data['list'] as $key => $value) {
            $existing = WarehouseStock::withoutGlobalScope('typeScope')->when(setting()->business_id == 3, fn ($q) => $q->where('batch_no', $value['batch_no']))->where('product_id', $value['product_id'])->where('attribute_id', $value['attribute_id'])->where('warehouse_id', $data['warehouse_id'])->first();
            $qty = (float) $value['quantity'] + (isset($value['gift_qty']) ? (float) $value['gift_qty'] : 0);

            if ($existing) {
                $totalQty = ((float) ($existing->quantity ?? 0)) + $qty;

                // Avoid division by zero
                if ($totalQty > 0) {
                    $unitPrice = (
                        (float) $existing->unit_price_total + ((float) $value['unit_price'] * $qty)
                    ) / $totalQty;
                } else {
                    $unitPrice = 0.0;
                }

                $unitPrice = round($unitPrice, 2);
                $unitPriceTotal = round($unitPrice * $totalQty, 2);

                WarehouseStock::where('id', $existing->id)->update([
                    'product_id' => $value['product_id'],
                    'attribute_id' => $value['attribute_id'],
                    'stock_date' => $data['purchase_date'],
                    'latest_unit_price' => round((float) $value['unit_price'], 2),
                    'quantity' => DB::raw('quantity +'.$qty),
                    'unit_price' => $unitPrice,
                    'unit_price_total' => $unitPriceTotal,
                    'tp_price' => round((float) str_replace(',', '', $value['tp_price']), 2),
                    'tp_price_total' => round((float) str_replace(',', '', $value['tp_price']) * $totalQty, 2),
                    'mrp_price' => round((float) str_replace(',', '', $value['mrp_price']), 2),
                    'mrp_price_total' => round((float) str_replace(',', '', $value['mrp_price']) * $totalQty, 2),
                    'mfg_date' => null,
                    'exp_date' => null,
                    'vat' => round((float) ($value['vat'] ?? 0), 2),
                    'tax' => round((float) ($value['tax'] ?? 0), 2),
                ]);
            } else {
                WarehouseStock::create([
                    'warehouse_id' => $data['warehouse_id'],
                    'supplier_id' => null,
                    'product_id' => $value['product_id'],
                    'attribute_id' => $value['attribute_id'],
                    'stock_date' => $data['purchase_date'],
                    'quantity' => (float) $qty,
                    'latest_unit_price' => $value['unit_price'],
                    'unit_price' => (float) str_replace(',', '', $value['unit_price']),
                    'unit_price_total' => (float) str_replace(',', '', $value['unit_price'] * $qty),
                    'tp_price' => (float) str_replace(',', '', $value['tp_price']),
                    'tp_price_total' => (float) str_replace(',', '', $value['tp_price'] * $qty),
                    'mrp_price' => (float) str_replace(',', '', $value['mrp_price']),
                    'mrp_price_total' => (float) str_replace(',', '', $value['mrp_price'] * $qty),
                    'mfg_date' => null,
                    'exp_date' => null,
                    'vat' => isset($value['vat']) ? $value['vat'] : 0,
                    'tax' => isset($value['tax']) ? $value['tax'] : 0,
                    'batch_no' => isset($value['batch_no']) ? $value['batch_no'] : null,
                ]);
            }
        }
        // //  Purchase Maker Status change to complite
        if (isset($data['purchase_maker_id'])) {

            purchase_maker_masters::where('id', $data['purchase_maker_id'])->update([
                'status' => 2,
            ]);
        }
    }

    public static function store_shop_warehouse($data, $old_purchase = [], $id = '')
    {
        // Old Stock Data Remove

        foreach ($old_purchase as $key => $old_value) {
            $existing = ShopWarehouseStocks::where('product_id', $old_value['product_id'])->where('attribute_id', $old_value['attribute_id'])->where('shop_id', $data['shop_warehouse_id'])->first();
            if ($existing) {
                ShopWarehouseStocks::where('id', $existing->id)->update([
                    'product_id' => $old_value['product_id'],
                    'attribute_id' => $old_value['attribute_id'],
                    'stock_date' => $data['purchase_date'],
                    'quantity' => DB::raw('quantity-'.$old_value['quantity']),
                    // 'salse' =>  $old_value['salse'],
                    // 'purchase' => ($existing->purchase_total - ($old_value['purchase'] * $old_value['quantity']) ) / ($existing->quantity + $old_value['quantity']),
                    'salse_total' => (float) str_replace(',', '', $existing->salse_total - $old_value['salse'] * $old_value['quantity']),
                    'purchase_total' => (float) str_replace(',', '', $existing->purchase_total - ($old_value['purchase'] * $old_value['quantity'])),
                ]);
            }
        }

        //  New Stock Data insert and Update
        foreach ($data['list'] as $key => $value) {
            $existing = ShopWarehouseStocks::where('product_id', $value['product_id'])->where('attribute_id', $value['attribute_id'])->where('shop_id', $data['shop_warehouse_id'])->first();
            if ($existing) {
                $getifno = array_filter($old_purchase, function ($item) use ($value) {
                    return $item['attribute_id'] == $value['attribute_id'];
                });

                $salsePrice = (count($getifno) != 0 && $value['salse'] == ($getifno[0]['salse'] ?? null))
                    ? $existing->salse
                    : $value['salse'];
                ShopWarehouseStocks::where('id', $existing->id)->update([
                    'product_id' => $value['product_id'],
                    'attribute_id' => $value['attribute_id'],
                    'stock_date' => $data['purchase_date'],
                    'quantity' => DB::raw('quantity +'.$value['quantity']),
                    'salse' => $salsePrice,
                    'purchase' => (float) str_replace(',', '', ($existing->purchase_total + ($value['purchase'] * $value['quantity'])) / ($existing->quantity + $value['quantity'])),
                    'salse_total' => (float) str_replace(',', '', ($value['salse']) * ($existing->quantity + $value['quantity'])),
                    'purchase_total' => (float) str_replace(',', '', (($existing->purchase_total + ($value['purchase'] * $value['quantity'])) / ($existing->quantity + $value['quantity'])) * ($existing->quantity + $value['quantity'])),
                ]);
            } else {
                ShopWarehouseStocks::create([
                    'shop_id' => $data['shop_warehouse_id'],
                    'product_id' => $value['product_id'],
                    'attribute_id' => $value['attribute_id'],
                    'stock_date' => $data['purchase_date'],
                    'quantity' => (int) $value['quantity'],
                    'salse' => (float) str_replace(',', '', $value['salse']),
                    'purchase' => (float) str_replace(',', '', $value['purchase']),
                    'salse_total' => (float) str_replace(',', '', $value['salse'] * $value['quantity']),
                    'purchase_total' => (float) str_replace(',', '', $value['total']),
                ]);
            }
        }

        //  Purchase Maker Status change to complite
        // if (isset($data['purchase_maker_id'])) {

        //     purchase_maker_masters::where('id', $data['purchase_maker_id'])->update([
        //         'status' => 2
        //     ]);
        // }
    }

    public static function purchaseReturn($data)
    {

        $collection = collect($data);
        $total = array_reduce($collection['list'], function ($acc, $item) {
            return $acc + $item['total'];
        }, 0);

        $returnMaster = PurchaseReturnMaster::create([
            'reference_no' => $collection['reference_no'],
            'return_date' => $collection['return_date'],
            'supplier_id' => isset($collection['supplier_id']) ? $collection['supplier_id'] : null,
            'purchase_invoice_no' => $collection['invoice_no'],
            'type' => 'regular',
            'total' => $total,
            'shop_id' => auth()->user()->shop_id,
            'create_by' => auth()->user()->id,
        ]);

        $purchase = PurchaseMaster::where('id', $collection['invoice_no'])->first();
        foreach ($collection['list'] as $key => $value) {
            PurchaseReturnDetails::create([
                'purchase_return_master_id' => $returnMaster->id,
                'purchase_invoice_no' => $collection['invoice_no'],
                'product_id' => $value['product_id'],
                'attribute_id' => $value['attribute_id'],
                'purchase_quantity' => $value['purchase_quantity'],
                'return_qty' => $value['return_quantity'],
                'purchase_price' => $value['purchase_price'],
                'return_price' => $value['return_price'],
                'total' => $value['total'],
            ]);

            WarehouseStock::where('attribute_id', $value['attribute_id'])->where('warehouse_id', $purchase->warehouse_id)->update([
                'quantity' => DB::raw('quantity - '.$value['return_quantity']),
                // 'tp_price_total' => DB::raw('tp_price *  quantity '),
                // 'mrp_price_total' => DB::raw('mrp_price * quantity'),
                // 'unit_price_total' => DB::raw(
                //     'unit_price_total - (' . $value['return_price'] . ' * ' . $value['return_quantity'] . ')'
                // )

            ]);
        }
    }

    public static function purchaseReturnUpdate($data, $id)
    {
        $collection = collect($data);

        $total = array_reduce($collection['list'], function ($acc, $item) {
            return $acc + $item['total'];
        }, 0);

        $returnMaster = PurchaseReturnMaster::where('id', $id)->update([
            'return_date' => $collection['return_date'],
            'supplier_id' => isset($collection['supplier_id']) ? $collection['supplier_id'] : null,
            'purchase_invoice_no' => $collection['invoice_no'],
            'total' => $total,
            'create_by' => auth()->user()->id,
        ]);

        $purchase = PurchaseMaster::where('id', $collection['invoice_no'])->first();

        $parentDetails = PurchaseReturnDetails::where('purchase_return_master_id', $id)->get();
        foreach ($parentDetails as $key => $item) {

            $warehouseStock = WarehouseStock::where('attribute_id', $item->attribute_id)
                ->where('warehouse_id', $purchase->warehouse_id)
                ->first();

            if ($warehouseStock && $warehouseStock->quantity > 0) {
                // Calculate unit price before subtracting to avoid division by zero
                $currentQuantity = (float) $warehouseStock->quantity;
                $currentUnitPriceTotal = (float) $warehouseStock->unit_price_total;
                $returnQuantity = (float) $item->return_qty;

                // Calculate unit price per item
                $unitPrice = $currentQuantity > 0 ? ($currentUnitPriceTotal / $currentQuantity) : 0;

                // Calculate new values
                $newQuantity = $currentQuantity + $returnQuantity;
                $newUnitPriceTotal = $unitPrice * $newQuantity;

                WarehouseStock::where('attribute_id', $item->attribute_id)
                    ->where('warehouse_id', $purchase->warehouse_id)
                    ->update([
                        'quantity' => $newQuantity,
                        'unit_price_total' => $newUnitPriceTotal,
                    ]);
            } else {
                // If stock doesn't exist or quantity is 0, just add quantity
                WarehouseStock::where('attribute_id', $item->attribute_id)
                    ->where('warehouse_id', $purchase->warehouse_id)
                    ->update([
                        'quantity' => DB::raw('quantity + '.$item->return_qty),
                    ]);
            }

            $item->delete();
        }

        foreach ($collection['list'] as $key => $value) {
            PurchaseReturnDetails::create([
                'purchase_return_master_id' => $id,
                'purchase_invoice_no' => $collection['invoice_no'],
                'product_id' => $value['product_id'],
                'attribute_id' => $value['attribute_id'],
                'purchase_quantity' => $value['purchase_quantity'],
                'return_qty' => $value['return_quantity'],
                'purchase_price' => $value['purchase_price'],
                'return_price' => $value['return_price'],
                'total' => $value['total'],
            ]);

            $warehouseStock = WarehouseStock::where('attribute_id', $value['attribute_id'])
                ->where('warehouse_id', $purchase->warehouse_id)
                ->first();

            if ($warehouseStock && $warehouseStock->quantity > 0) {
                // Calculate unit price before subtracting to avoid division by zero
                $currentQuantity = (float) $warehouseStock->quantity;
                $currentUnitPriceTotal = (float) $warehouseStock->unit_price_total;
                $returnQuantity = (float) $value['return_quantity'];

                // Calculate unit price per item
                $unitPrice = $currentQuantity > 0 ? ($currentUnitPriceTotal / $currentQuantity) : 0;

                // Calculate new values
                $newQuantity = $currentQuantity - $returnQuantity;
                $newUnitPriceTotal = max(0, $unitPrice * $newQuantity); // Ensure non-negative

                WarehouseStock::where('attribute_id', $value['attribute_id'])
                    ->where('warehouse_id', $purchase->warehouse_id)
                    ->update([
                        'quantity' => $newQuantity,
                        'tp_price_total' => DB::raw('tp_price * '.$newQuantity),
                        'mrp_price_total' => DB::raw('mrp_price * '.$newQuantity),
                        'unit_price_total' => $newUnitPriceTotal,
                    ]);
            } else {
                // If stock doesn't exist or quantity is 0, just update quantity
                WarehouseStock::where('attribute_id', $value['attribute_id'])
                    ->where('warehouse_id', $purchase->warehouse_id)
                    ->update([
                        'quantity' => DB::raw('quantity - '.$value['return_quantity']),
                    ]);
            }
        }
    }

    public static function purchasePayment($data)
    {
        $collect = collect($data);
        if (isset($collect['supplier_payment_id'])) {
            self::purchasePaymentUpdate($data, $collect['supplier_payment_id']);

            return;
        }
        $id = str_pad((PurchasePayment::latest()->first()?->id ?? 0) + 1, 4, '0', STR_PAD_LEFT);

        $amount = $collect['list'][0]['payment'];
        PurchasePayment::create([
            'supplier_id' => $collect['supplier_id'],
            'date' => $collect['date'],
            'payment_mode' => $collect['payment_mode'] == 'future_due' ? $collect['payment_mode'] : 'current_due',
            'payment' => $collect['payment_mode'] === 'future_due'
                ? -abs($amount)
                : abs($amount),
            'payment_id' => isset($collect['list'][0]['payment_id']) ? $collect['list'][0]['payment_id'] : 'cash',
            'payment_type' => isset($collect['payment_type']) ? $collect['payment_type'] : 'cash',
            'order_no' => $collect['order_no'] ?? null,
            'note' => $collect['note'] ?? null,
            'collection_reference' => $id,
            'purchase_id' => isset($collect['purchase_id']) ? $collect['purchase_id'] : null,
        ]);
    }

    public static function purchasePaymentUpdate($data, $id)
    {
        $collect = collect($data);
        PurchasePayment::where('id', $id)->update([
            'supplier_id' => $collect['supplier_id'],
            'date' => $collect['date'],
            'payment' => $collect['list'][0]['payment'],
            'payment_id' => isset($collect['list'][0]['payment_id']) ? $collect['list'][0]['payment_id'] : 'cash',
            'payment_type' => isset($collect['payment_type']) ? $collect['payment_type'] : 'cash',
            'order_no' => $collect['order_no'] ?? null,
            'note' => $collect['note'] ?? null,

        ]);
    }

    public static function DirectPurchaseReturn($data)
    {
        DB::transaction(function () use ($data) {
            try {
                $collect = collect($data);
                $total = array_reduce($collect['list'], function ($acc, $item) {
                    return $acc + $item['total'];
                }, 0);

                $returnMaster = PurchaseReturnMaster::create([
                    'reference_no' => $collect['reference_no'],
                    'return_date' => $collect['return_date'],
                    'supplier_id' => isset($collect['supplier_id']) ? $collect['supplier_id'] : null,
                    'purchase_invoice_no' => null, // Direct return, no invoice
                    'type' => 'direct',
                    'total' => $total,
                    'shop_id' => auth()->user()->shop_id,
                    'create_by' => auth()->user()->id,
                ]);

                foreach ($collect['list'] as $key => $value) {
                    PurchaseReturnDetails::create([
                        'purchase_return_master_id' => $returnMaster->id,
                        'purchase_invoice_no' => null,
                        'product_id' => $value['product_id'],
                        'attribute_id' => $value['attribute_id'],
                        'purchase_quantity' => $value['quantity'],
                        'return_qty' => $value['quantity'],
                        'purchase_price' => $value['price'],
                        'return_price' => $value['price'],
                        'total' => $value['total'],
                    ]);

                    // Update warehouse stock - decrease quantity
                    $warehouseStock = WarehouseStock::where('attribute_id', $value['attribute_id'])
                        ->where('warehouse_id', $collect['warehouse_id'])
                        ->first();

                    if ($warehouseStock && $warehouseStock->quantity > 0) {
                        // Calculate unit price before subtracting to avoid division by zero
                        $currentQuantity = (float) $warehouseStock->quantity;
                        $currentUnitPriceTotal = (float) $warehouseStock->unit_price_total;
                        $returnQuantity = (float) $value['quantity'];

                        // Calculate unit price per item
                        $unitPrice = $currentQuantity > 0 ? ($currentUnitPriceTotal / $currentQuantity) : 0;

                        // Calculate new values
                        $newQuantity = $currentQuantity - $returnQuantity;
                        $newUnitPriceTotal = $unitPrice * $newQuantity;

                        WarehouseStock::where('attribute_id', $value['attribute_id'])
                            ->where('warehouse_id', $collect['warehouse_id'])
                            ->update([
                                'quantity' => $newQuantity,
                                'unit_price_total' => $newUnitPriceTotal,
                            ]);
                    }
                }
            } catch (\Exception $e) {
                DB::rollBack();
                throw $e;
            }
        });
    }

    public static function DirectPurchaseReturnUpdate($data, $id)
    {
        DB::transaction(function () use ($data, $id) {
            try {
                $collect = collect($data);

                $total = array_reduce($collect['list'], function ($acc, $item) {
                    return $acc + $item['total'];
                }, 0);

                // Get old details and restore stock
                $parentDetails = PurchaseReturnDetails::where('purchase_return_master_id', $id)->get();
                foreach ($parentDetails as $key => $item) {
                    // Restore stock - add back the returned quantity
                    WarehouseStock::where('attribute_id', $item->attribute_id)
                        ->where('warehouse_id', $collect['warehouse_id'])
                        ->update([
                            'quantity' => DB::raw('quantity + '.$item->return_qty),
                        ]);
                    $item->delete();
                }

                // Update return master
                PurchaseReturnMaster::where('id', $id)->update([
                    'return_date' => $collect['return_date'],
                    'supplier_id' => isset($collect['supplier_id']) ? $collect['supplier_id'] : null,
                    'total' => $total,
                    'create_by' => auth()->user()->id,
                ]);

                // Create new details and update stock
                foreach ($collect['list'] as $key => $value) {
                    PurchaseReturnDetails::create([
                        'purchase_return_master_id' => $id,
                        'purchase_invoice_no' => null,
                        'product_id' => $value['product_id'],
                        'attribute_id' => $value['attribute_id'],
                        'purchase_quantity' => $value['quantity'],
                        'return_qty' => $value['quantity'],
                        'purchase_price' => $value['price'],
                        'return_price' => $value['price'],
                        'total' => $value['total'],
                    ]);

                    // Update warehouse stock - decrease quantity
                    WarehouseStock::where('attribute_id', $value['attribute_id'])
                        ->where('warehouse_id', $collect['warehouse_id'])
                        ->update([
                            'quantity' => DB::raw('quantity - '.$value['quantity']),
                        ]);
                }
            } catch (\Exception $e) {
                DB::rollBack();
                throw $e;
            }
        });
    }
}
