<?php

namespace App\Http\Controllers\Reseller;
use Exception;
use Throwable;
use Carbon\Carbon;
use App\Models\City;
use App\Models\Order;
use App\Models\Comment;
use App\Models\Courier;
use App\Models\Product;
use App\Models\Variant;
use App\Models\Customer;
use App\Models\Reseller;
use App\Models\OrderItem;
use App\Services\LogTracker;
use App\Services\SmsService;
use Illuminate\Http\Request;
use App\Models\GeneralSetting;
use App\Services\HelperService;
use App\Models\OrderItemVariant;
use App\Models\ResellerCashbook;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use App\Models\ResellerPaymentMethod;
use App\Models\ResellerPaymentTransaction;
use App\Models\ResellerPaymentTransactionDetail;
use App\Models\ResellerCashbookPaymentTransactionDetail;

class OrderController extends Controller
{


    public function get_reseller_order(Request $request)
    {
        $item = $request->item ?? 30;

        // Fetch reseller ID once to avoid multiple session calls
        $reseller_id = session()->get('reseller')['id'];

        // Start building the query
        $query = Order::select('id','invoice_no','total','discount','paid','shipping_cost','profit','status','comment','created_at','customer_id','courier_id', 'customer_phone', 'memo_no')->where('reseller_id', $reseller_id)
            ->with([
                'customer:id,name,address',
                'courier:id,name',
                'orderItem' => function ($query) {
                    $query->select('id', 'order_id', 'product_id', 'quantity')->with([
                        'product:id,name,product_code,thumbnail_img'
                    ]);
                }
            ])
            ->orderBy('id', 'desc');

        // Filter based on status_code
        if (!empty($request->start_date) && !empty($request->end_date)) {
            $query->whereBetween('created_at', [$request->start_date, $request->end_date]);
        
            if ($request->status_code !== 'all') {
                $query->where('status', $request->status_code);
            }
        } elseif ($request->status_code !== 'all') {
            $query->where('status', $request->status_code);
        }

        // Paginate results
        $orders = $query->paginate($item);

        $comments = Comment::all(['id', 'name']); 

        return response()->json([
            "status" => "OK",
            "orders" => $orders,
            'comments' => $comments,
            'order_count' => Order::resellerOrderCount(),
        ]);
    }




    public function reseller_order_details($id)
    {

        $order = Order::where('id', $id)->where('reseller_id', session()->get('reseller')['id'])->with(['customer', 'courier', 'city', 'sub_city', 'approvedBy'])->first();
        $order_items = OrderItem::where('order_id', $order->id)->with(['product.productVariant.variant.attribute', 'attribute', 'variant', 'variants',])->get();

        return response()->json([
            "status" => "SUCCESS",
            "order"  => $order,
            "items"  => $order_items,
        ]);
    }

    /* ================= Order View =================  */
    public function reseller_order_edit($id)
    {
        $order = Order::where('id', $id)->with(['customer:id,name,address', 'courier:id,name', 'city:id,name', 'sub_city:id,name', 'approvedBy:id,name', 'orderPayment', 'createAdmin:id,name', 'pendingBy:id,name', 'shipmentBy:id,name', 'deliveredBy:id,name', 'returnBy:id,name', 'cancelBy:id,name',])->first();
        $order_items = OrderItem::where('order_id', $order->id)->with(['product.productVariant.variant.attribute', 'product:id,merchant_id,name,price,reselling_price,sale_price,discount,product_code,stock,thumbnail_img', 'product.productVariant.variant.attribute', 'attribute:id,name', 'variant:id,name','variants'])->get();
        
        if($order->status == 4 || $order->status == 8 ||  $order->status == 6){
            return response()->json('Sorry, unable to edit');
        }
        return response()->json([
            'status' => 'SUCCESS',
            'order' => $order,
            'items' => $order_items,
        ]);
        
    }




    public function resellerCashbook(Request $request)
    {

        if(!empty($request->start_date) && !empty($request->end_date)){
            $cashbooks = ResellerCashbook::where('reseller_id', session()->get('reseller')['id'])->where('is_income', $request->is_income)
                                            ->whereDate('created_at', '>=', $request->start_date)
                                            ->whereDate('created_at', '<=', $request->end_date)->orderBy('id', 'desc')->with('order', 'order.city')->paginate($request->item);


            $total_balance = ResellerCashbook::where('reseller_id', session()->get('reseller')['id'])->where('is_income', $request->is_income)
                                            ->whereDate('created_at', '>=', $request->start_date)
                                            ->whereDate('created_at', '<=', $request->end_date)->sum('amount');
        }else if(!empty($request->start_date) && empty($request->end_date)){
            $cashbooks = ResellerCashbook::where('reseller_id', session()->get('reseller')['id'])->where('is_income', $request->is_income)
                                            ->whereDate('created_at', '>=', $request->start_date)->orderBy('id', 'desc')->with('order', 'order.city')->paginate($request->item);

            $total_balance = ResellerCashbook::where('reseller_id', session()->get('reseller')['id'])->where('is_income', $request->is_income)
                                            ->whereDate('created_at', '>=', $request->start_date)->sum('amount');
        }else{
            $cashbooks = ResellerCashbook::where('reseller_id', session()->get('reseller')['id'])->where('is_income', $request->is_income)->orderBy('id', 'desc')->with('order', 'order.city')->paginate($request->item);
            $total_balance = ResellerCashbook::where('reseller_id', session()->get('reseller')['id'])->where('is_income', $request->is_income)->sum('amount');

        }
        return response()->json([
            'status' => 'OK',
            'cashbooks' => $cashbooks,
            'total_balance' => $total_balance,
        ]);
    }





    public function ResellerOrderStore(Request $request)
    {
        // return $request->all();
        $data = $request->validate([
            'customer_phone' => 'required|digits:11 ',
            'name' => 'required',
            'address' => 'required',
            'city_id' => 'required|integer|min:1',
            'shipping_cost' => 'required|integer',
            // 'order_type' => 'required|integer|min:1',
            'sub_city_id' => 'required|integer|min:1',
            'status' => 'required|integer|min:1',
            'total' => 'required|integer|min:1',
            'note' => 'nullable',
            'payable_shipping_charge' => 'required|min:0|numeric',
            'discount' => 'nullable|integer|min:0',
            'paid' => 'required|integer|min:0',
            'due' => 'required|integer|min:0',
            'actual_price_total' => 'required',
            'profit' => 'required',
            'courier_id' => 'nullable',
        ]);

        DB::beginTransaction();
        try {
            //first find find the customer
            $reseller = Reseller::findOrFail(session()->get('reseller')['id']);
            $customer = Customer::where('phone', $data['customer_phone'])->first();
            $city = City::findOrFail($data['city_id']);
            !empty($customer) ? $customer->update($data) :  Customer::storeCustomer($data);
            $customer = Customer::where('phone', $data['customer_phone'])->first();
            $customer->reseller_id = $reseller->id;
            $customer->save();

            $order = new Order();
            $order->invoice_no = 1234;
            $order->reseller_id = session()->get('reseller')['id'];
            $order->status = 1;
            $order->shipping_cost = $data['payable_shipping_charge'];
            $order->profit = $data['profit'];
            $order->regular_shipping_cost = $data['shipping_cost'];
            $order->city_id = $data['city_id'];
            $order->sub_city_id = $data['sub_city_id'];
            $order->total = $data['total'];
            $order->customer_id = $customer->id;
            $order->customer_phone = $customer->phone;
            $order->note = $data['note'];
            $order->discount = $data['discount'];
            $order->paid = $data['paid'];
            $order->advance_paid = $data['paid'];
            $order->courier_id = $data['courier_id'];
            $order->order_type = 4;
            $order->save();


            $sale_price = 0;
            $custom_reselling_price = 0;
            $sale_price_with_profit_price = 0;
            foreach ($request->products as $product) {
                $details = new OrderItem();
                $item_product = Product::findOrFail($product['id']);
                $details->order_id = $order->id;
                $details->product_id = $product['id'];
                $details->quantity = $product['quantity'];
                $details->admin_sale_price = $item_product->reselling_price;
                $details->purchase_price = $item_product->purchase_price;



                //checking ten percent profit
                $ten_percent_profit = $item_product->reselling_price / 10;
                if(intval($item_product->reselling_price) + intval($ten_percent_profit) > $product['custom_reselling_price']){
                    $details->price = $item_product->reselling_price + $ten_percent_profit;
                    $details->total = ($item_product->reselling_price + $ten_percent_profit) * $product['quantity'];
                }else{
                    $details->price = $product['custom_reselling_price'];
                    $details->total = $product['custom_reselling_price'] * $product['quantity'];
                }
                $details->save();

                $sale_price += intval($details->admin_sale_price) * intval($product['quantity']);
                $custom_reselling_price += intval($details->price) * intval($product['quantity']);
                $sale_price_with_profit_price += ($item_product->reselling_price + $ten_percent_profit) * $product['quantity'];




                if (!empty($product['variant_id'])) {
                    $variant = Variant::with('attribute')->find($product['variant_id']);
                    // return $variantName;
                    OrderItemVariant::create([
                        'order_item_id' => $details->id,
                        'variant_atribute' => $variant->attribute->name ?? null,
                        'variant_name' => $variant->name ?? null,
                        'variant_id' => $variant->id ?? null,
                    ]);
                }

            }
            //checking order profit
            $profit_calculate = intval($custom_reselling_price) - intval($sale_price);
            $ten_percent_profit_calculate = intval($sale_price_with_profit_price) - intval($sale_price);
            $profit = (intval($profit_calculate) - intval($data['discount'])) + (intval($data['payable_shipping_charge']) - intval($data['shipping_cost']));
            
            if($ten_percent_profit_calculate > $profit){
                $order->discount = 0;
                $order->shipping_cost = $city->delivery_charge;
                $order->profit = $profit_calculate;
            }else{
                $order->profit = $profit;
            }

            /**** making 6 digit unique invoice no ****/
            if (strlen($order->id) > 3) {
                $order->invoice_no = rand(1, 9) . $order->id . rand(1, 9);
            } else if (strlen($order->id) > 2) {
                $order->invoice_no = rand(11, 99) . $order->id . rand(1, 9);
            } else if (strlen($order->id) > 1) {
                $order->invoice_no = rand(11, 99) . $order->id . rand(11, 99);
            } else {
                $order->invoice_no = rand(111, 999) . $order->id . rand(11, 99);
            }
            // $order->total_sale_price = $sale_price;
            $order->save();

            //expense from reseller wallet
            if ($order->paid > 0) {
                HelperService::resellerCashbookStore($order->id, $reseller->id, $order->paid, 0,  $order->paid . ' paid at the time of order creation. ');
            }
            //create a barcode for order
            HelperService::orderBarcodeStore($order->id, $order->invoice_no);
            //send message to customer
            if($reseller->sms_status == 1){
                $reseller->total_sms = $reseller->total_sms + 1;
                $reseller->save();
                (new SmsService())->SendMessageToCustomerFromResellerOrder($order->customer_phone, $customer->name, $order->invoice_no, $reseller);
            }
            DB::commit();
            return \response()->json([
                'status' => 'SUCCESS',
                'message' => 'Order created successfully'
            ]);
        } catch (Exception $e) {
            return response()->json([
                "status" => 0,
                'message' => $e->getMessage(),
            ]);
        }
    }

    

    /* Reseller Order Update */
    public function ResellerOrderUpdate(Request $request, $id)
    {
        $order = Order::findOrFail($id);
        $data = $request->validate([
            'customer_phone' => 'required|digits:11 ',
            'name' => 'required ',
            'address' => 'required ',
            'city_id' => 'required|integer|min:1',
            'shipping_cost' => 'required|integer',
            'order_type' => 'required|integer|min:1',
            'sub_city_id' => 'required|integer|min:1',
            'status' => 'required|integer|min:1',
            'total' => 'required|integer|min:1',
            'product_total_price' => 'required',
            'note' => 'nullable',
            'payable_shipping_charge' => 'required|min:0|numeric',
            'discount' => 'nullable|integer|min:0',
            'paid' => 'required|integer|min:0',
            'due' => 'required|integer|min:0',
            'actual_price_total' => 'required',
            'profit' => 'required',
            'courier_id' => 'nullable',
        ]);

        DB::beginTransaction();
        try {
            //first find find the customer
            $reseller = Reseller::findOrFail(session()->get('reseller')['id']);
            $customer = Customer::where('phone', $data['customer_phone'])->first();
            $city = City::findOrFail($data['city_id']);
            !empty($customer) ? $customer->update($data) :  Customer::storeCustomer($data);
            $customer = Customer::where('phone', $data['customer_phone'])->first();

            //expense from reseller wallet
            if ($order->paid > 0) {
                $reseller_cashbook = ResellerCashbook::where('order_id', $order->id)->first();
                if (!empty($reseller_cashbook)) {
                    $reseller_cashbook->amount = $order->paid;
                    $reseller_cashbook->save();
                } else {
                    HelperService::resellerCashbookStore($order->id, $reseller->id, $order->paid, 0, $order->paid . ' paid amount at the time of order create ');
                }
            }

            
            //restore wallet if the order paid amount  is less than previous paid
            if( intval($data['paid']) != intval($order->paid) ){
                $reseller_cashbook = ResellerCashbook::where('order_id', $order->id)->where('reseller_id', $order->reseller_id)->first();
                if($reseller_cashbook){
                    $reseller_cashbook->delete();
                }
                HelperService::resellerCashbookStore($order->id, $order->reseller_id,$data['paid'], 0, $data['paid'] . ' paid amount at the time of order updated, previous record deleted.');
            }
            $order->reseller_id = session()->get('reseller')['id'];
            $order->total_sale_price = $data['actual_price_total'];
            $order->shipping_cost = $data['payable_shipping_charge'];
            $order->regular_shipping_cost = $data['shipping_cost'];
            $order->profit = $data['profit'];
            $order->city_id = $data['city_id'];
            $order->sub_city_id = $data['sub_city_id'];
            $order->total = $data['total'];
            $order->customer_id = $customer->id;
            $order->customer_phone = $customer->phone;
            $order->note = $data['note'];
            $order->discount = $data['discount'];
            $order->paid = $data['paid'];
            $order->advance_paid = $data['paid'];
            $order->courier_id = $data['courier_id'];
            $order->save();

            //delete previous items
            OrderItem::where('order_id', $order->id)->orderBy('id', 'desc')->delete();
            //re-insert items

            //if order save then save the order details
            $sale_price = 0;
            $custom_reselling_price = 0;
            $sale_price_with_profit_price = 0;
            foreach ($request->products as $product) {
                $details = new OrderItem();
                $item_product = Product::findOrFail($product['id']);
                $details->order_id = $order->id;
                $details->product_id = $product['id'];
                $details->quantity = $product['quantity'];
                $details->admin_sale_price = $item_product->reselling_price;
                $details->purchase_price = $item_product->purchase_price;
                //checking ten percent profit
                $ten_percent_profit = $item_product->reselling_price / 10;
                if(intval($item_product->reselling_price) + intval($ten_percent_profit) > $product['custom_reselling_price']){
                    $details->price = $item_product->reselling_price + $ten_percent_profit;
                    $details->total = ($item_product->reselling_price + $ten_percent_profit) * $product['quantity'];
                }else{
                    $details->price = $product['custom_reselling_price'];
                    $details->total = $product['custom_reselling_price'] * $product['quantity'];
                }
                $details->save();

                $sale_price += intval($details->admin_sale_price) * intval($product['quantity']);
                $custom_reselling_price += intval($details->price) * intval($product['quantity']);
                $sale_price_with_profit_price += ($item_product->reselling_price + $ten_percent_profit) * $product['quantity'];
                if (!empty($product['variant_id'])) {
                    $variant = Variant::with('attribute')->find($product['variant_id']);
                    // return $variantName;
                    OrderItemVariant::create([
                        'order_item_id' => $details->id,
                        'variant_atribute' => $variant->attribute->name ?? null,
                        'variant_name' => $variant->name ?? null,
                        'variant_id' => $variant->id ?? null,
                    ]);
                }



            }
            $profit_calculate = intval($custom_reselling_price) - intval($sale_price);
            $ten_percent_profit_calculate = intval($sale_price_with_profit_price) - intval($sale_price);
            $profit = (intval($profit_calculate) - intval($data['discount'])) + (intval($data['payable_shipping_charge']) - intval($data['shipping_cost']));
            
            if($ten_percent_profit_calculate > $profit){
                $order->discount = 0;
                $order->shipping_cost = $city->delivery_charge;
                $order->profit = $profit_calculate;
            }else{
                $order->profit = $profit;
            }

            //create a barcode for order
            HelperService::orderBarcodeStore($order->id, $order->invoice_no);
            DB::commit();
            return \response()->json([
                'status' => 'SUCCESS',
                'message' => 'Order created successfully'
            ]);
        } catch (Exception $e) {
            return response()->json([
                "status" => 0,
                'message' => $e->getMessage(),
            ]);
        }
    }



    



    public function approved($id)
    {
        $order = Order::findOrFail($id);
        try {
            $order->status = 3;
            if(empty($order->approved_admin_id)){
                $order->approved_admin_id=session()->get('reseller')['id'];
                $order->approved_date=Carbon::now();
            }
            $order->save();
            return response()->json([
                'status' => 'SUCCESS',
                'message' => 'Order  approved  successfully',
            ]);
        }catch (Exception $e) {
            return $e->getMessage();
        }
    }



    public function pending($id)
    {
        $order = Order::findOrFail($id);
        $order->status = 2;
        $order->pending_admin_id = session()->get('reseller')['id'];
        $order->pending_date = Carbon::now();
        $order->save();
        return response()->json([
            'status' => 'SUCCESS',
            'message' => 'Order  pending  successfully',
        ]);
    }



    public function cancel($id)
    {
        $order = Order::findOrFail($id);
        DB::beginTransaction();
        try {
            if ($order->status != 1 && $order->status != 2 && $order->status != 3) {
                $details = OrderItem::where('order_id', $order->id)->get();
                foreach ($details as $detail) {
                    $product = Product::where('id', $detail->product_id)->first();
                    $product->stock = $product->stock + $detail->quantity;
                    $product->save();
                }
            }

            $order->status = 6;
            $order->total_item = intval($order->total_item) - intval(OrderItem::where('order_id',$order->id)->count());
            $order->cancel_admin_id = session()->get('reseller')['id'];
            $order->cancel_date = Carbon::now();
            //if order is reseller order. and order has paid amount then restore reseller cashbook
            if ($order->paid > 0 && !empty($order->reseller_id) && $order->order_type == 4) {
                $reseller_cashbook = ResellerCashbook::where('order_id', $order->id)->where('reseller_id', $order->reseller_id)->get();
                foreach($reseller_cashbook as $item){
                    $item->delete();
                }
                $order->advance_paid = 0;
                $order->paid = 0;
            }
            $order->save();

            DB::commit();
            return response()->json([
                'status' => 'SUCCESS',
                'message' => 'Order canceled successfully',
            ]);
        } catch (Throwable $e) {
            DB::rollBack();
            LogTracker::failLog($e, session()->get('reseller')['id']);
            return response()->json([
                'status' => 'FAILED',
                'message' => $e->getMessage(),
            ]);
        }
    }


    public function comment(Request $request)
    {
        $order = Order::where('id', $request->order_id)->first();
        $order->comment = $request->comment;
        $order->save();
        return response()->json([
            'status' => 'OK',
            'message' => $order->comment . '  is added as comment ',
        ]);
    }


    public function orderSearch($search)
    {
        $reseller_id = session()->get('reseller')['id'];
        if(strlen($search) < 6){
            $orders = Order::where('invoice_no', 'like', '%' . $search . '%')->where('reseller_id', $reseller_id)
                            ->orderBy('id', 'DESC')
                            ->with([
                                'customer:id,name,address',
                                'createAdmin:id,name',
                                'courier',
                                'reseller:id,phone,name',
                                'orderItem.product.productImage',
                            ])
                            ->paginate(20);

        }else{
            $orders = Order::where('customer_phone', 'like', '%' . $search . '%')->where('reseller_id', $reseller_id)
                            ->orderBy('id', 'DESC')
                            ->with([
                                'customer:id,name,address',
                                'createAdmin:id,name',
                                'courier',
                                'reseller:id,phone,name',
                                'orderItem.product.productImage',
                            ])
                            ->paginate(20);
        }

        return response()->json([
            'success' => true,
            'orders' => $orders,
            'order_count' => Order::orderStatusCount(),
            'couriers' => Courier::where('status', 1)->get(),
            'comments' => Comment::all(),
        ]);
        
        
        

       
    }





    public function orderSummary($id)
    {
        $transaction            = ResellerPaymentTransaction::with('bank.resellerPaymentMethod','reseller')->findOrFail($id);
    
        $transaction_details    = ResellerPaymentTransactionDetail::with('order','paymentTransaction')->where('reseller_payment_transaction_id', $transaction->id)->get();

        $cashbook_transaction_details = ResellerCashbookPaymentTransactionDetail::with('reseller_cashbook')->where('reseller_payment_transaction_id', $transaction->id)->get();

        $general_setting         = GeneralSetting::latest()->first();
        $reseller                = Reseller::findOrFail(session()->get('reseller')['id']);
        $reseller_payment_method = ResellerPaymentMethod::with('bank')->where('reseller_id', $reseller->id)->first();
        
        return response()->json([
            "success"                      => true,
            "transaction_details"          => $transaction_details,
            'transaction'                  => $transaction,
            'general_setting'              => $general_setting,
            'reseller_payment_method'      => $reseller_payment_method,
            'cashbook_transaction_details' => $cashbook_transaction_details,
        
        ]);
    }



    public function downloadOrderSummary($id)
    {
        $transaction = ResellerPaymentTransaction::with('bank.resellerPaymentMethod')->findOrFail($id);
        $transaction_details = ResellerPaymentTransactionDetail::with('order','paymentTransaction')->where('reseller_payment_transaction_id', $transaction->id)->get();
        $company_info = GeneralSetting::latest()->first();
        return view('reseller.pdf.transaction_details', compact('transaction_details','company_info'));
    }


    public function printOrderSummary($id)
    {
        $transaction = ResellerPaymentTransaction::with('bank.resellerPaymentMethod')->findOrFail($id);
        $transaction_details = ResellerPaymentTransactionDetail::with('order','paymentTransaction')->where('reseller_payment_transaction_id', $transaction->id)->get();
        $company_info = GeneralSetting::latest()->first();
        return view('reseller.pdf.transaction_details_print', compact('transaction_details','company_info'));
    }

    
}
