<?php

namespace App\Http\Controllers\User;

use App\Models\Order;
use App\Models\Service;
use App\Models\Category;
use App\Models\Services;
use App\Models\Transaction;
use App\Models\BrandPackage;
use Illuminate\Http\Request;
use App\Models\GatewayCurrency;
use App\Models\AdminNotification;
use App\Models\BrandPackageOrder;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Session;

class OrderController extends Controller
{

    public function index(){
        $pageTitle = 'Order Lists';
        $orders = Order::where('status','!=',5)->where('user_id',auth()->user()->id)->with(['service','user','category'])->paginate(getPaginate(12));
        return view($this->activeTemplate.'user.orders.index',compact('pageTitle','orders'));
    }

    public function create(){
        $pageTitle = 'New Order';
        $categories = Category::where('status',1)->get();
        return view($this->activeTemplate.'user.orders.create',compact('pageTitle','categories'));
    }

    public function serviceOrder($id){
        $service = Service::findOrFail($id);
        $category = $service->category;
        $pageTitle ='Order Place';
        return view($this->activeTemplate.'user.orders.direct_order',compact('pageTitle','category','service'));
    }

    public function orderPlace(Request $request){

       $service = Service::findOrFail($request->service);

       $rules = [
        'category' => 'required',
        'service' => 'required',
        'link' => 'required|url',
        'quantity' => 'required|integer|gte:' . $service->min . '|lte:' . $service->max,
        'check' => 'required',
       ];

       if ($service->drip_feed == 1 && isset($request->drip_feed)) {
            $rules['runs'] = 'required|integer|not_in:0';
            $rules['interval'] = 'required|integer|not_in:0';
        }

        $request->validate($rules);
        $quantity = $request->quantity;

        if ($service->drip_feed == 1 && isset($request->drip_feed)) {
            $quantity = $request->quantity * $request->runs;
        }

        if ($service->min <= $quantity && $service->max >= $quantity) {
            $price_per_k = round(($quantity * $service->price) / 1000, 2);

            //store into session
             Session::put('serviceSession', [
                'order_no'=>getTrx(4),
                'user_id' => auth()->user()->id,
                'category_id' => $request->category,
                'service_id' => $request->service,
                'api_service_id' => $service->api_service_id ?? 0,
                'api_provider_id' => $service->api_provider_id ?? 0,
                'api_order' =>$service->api_service_id ? 1 : 0,
                'quantity' => $quantity,
                'link' =>$request->link,
                'price' =>$price_per_k,
                'runs' => $request->runs ? $request->runs : null,
                'interval' => $request->interval ? $request->interval : null,
                'check' =>$request->check ? 1: 0,
                'drip_feed' =>$request->drip_feed == 1 ? 1: 0,
                'note' =>$request->note ? $request->note :null
            ]);

            $gatewayCurrency = GatewayCurrency::whereHas('method', function ($gate){
                $gate->where('status', 1);
            })->with('method')->orderby('method_code')->get();

            $pageTitle = 'Payment Methods';
            return view($this->activeTemplate . 'user.payment.payment', compact('gatewayCurrency', 'pageTitle'));
        }else{
            $notify[] = ['success', 'Order quantity should be minimum ' . $service->min . ' and maximum ' . $service->max];
            return back()->withNotify($notify);
        }

    }

    public function serviceOrderInsert($sessionData , $status = null)
    {
        $order = new Order();
        $order->order_no = $sessionData['order_no'];
        $order->user_id = $sessionData['user_id'];
        $order->category_id = $sessionData['category_id'];
        $order->service_id = $sessionData['service_id'];
        $order->api_service_id  = $sessionData['api_service_id'];
        $order->api_provider_id = $sessionData['api_provider_id'];;
        $order->api_order = $sessionData['api_order'];
        $order->quantity = $sessionData['quantity'];
        $order->remains = $order->quantity;
        $order->link = $sessionData['link'];
        $order->price = $sessionData['price'];
        $order->interval = $sessionData['interval'];
        $order->runs = $sessionData['runs'];
        $order->check = $sessionData['check'];
        $order->drip_feed = $sessionData['drip_feed'];
        $order->status = $status ?? 5;
        $order->note = $sessionData['note'];
        $order->save();
        return $order;
    }

    public function pendingOrder(){
        return $this->getOrder(0, 'Pending Orders');
    }

    public function processingOrder(){
        return $this->getOrder(1, 'Processing Orders');
    }

    public function completeOrder(){
        return $this->getOrder(2, 'Complete Orders');
    }

    public function refundOrder(){
        return $this->getOrder(4, 'Refund Orders');
    }

    public function cancelleOrder(){
        return $this->getOrder(3, 'Cancelled Orders');
    }

    public function getAjaxServices(Request $request){
        $category = Category::find($request->categoryId);
        $services = $category->services;
        return response()->json($services);
    }

    public function getAjaxServiceDetails(Request $request){
        $service = Service::findOrFail($request->serviceId);
        return response()->json($service);

    }

    //mass order
    public function massOrderCreate(){
        $pageTitle = 'Mass Order';
        return view($this->activeTemplate.'user.orders.massOrder',compact('pageTitle'));
    }

    public function massOrderStore(Request $request){

        $request->validate([
            'check' => 'required'
        ]);

        if (substr_count($request->mass_order, '|') < 4) {
			$notify[] = ['error', 'Service structures are not correct. Please retype!'];
			return back()->withNotify($notify);
		}

        $separateNewLine = explode(PHP_EOL, $request->mass_order);

        foreach ($separateNewLine as $item) {

			$serviceArray = explode('|', $item);
			//Start Validations
			if (count($serviceArray) != 3) {
				$notify[] = ['error', 'Service structures are not correct. Please retype!'];
				return back()->withNotify($notify)->withInput();
			}

			$service = Service::find($serviceArray[0]);

			if (!$service) {
				$notify[] = ['error', 'Service ID not found!'];
				return back()->withNotify($notify)->withInput();
			}

			if (filter_var($serviceArray[2], FILTER_VALIDATE_INT) == false) {
				$notify[] = ['error', 'Quantity should be an integer value!'];
				return back()->withNotify($notify)->withInput();
			}

			if ($serviceArray[2] < $service->min) {
				$notify[] = ['error', 'Quantity should be greater than or equal to ' . $service->min];
				return back()->withNotify($notify)->withInput();
			}

			if ($serviceArray[2] > $service->max) {
				$notify[] = ['error', 'Quantity should be less than or equal to ' . $service->max];
				return back()->withNotify($notify)->withInput();
			}
			// End validation
            $price = round(($service->price * $serviceArray[2]) / 1000, 2);
			$user  = auth()->user();

			if ($user->balance < $price) {
				$notify[] = ['error', 'Insufficient balance. Please deposit and try again!'];
				return  to_route('user.deposit')->withNotify($notify);
			}

			$user->balance -= $price;
			$user->save();

			//Make order
			$order = new Order();
			$order->order_no  = getTrx(4);
			$order->user_id  = $user->id;
			$order->category_id = $service->category->id;
			$order->service_id  = $service->id;
			$order->api_service_id  = $service->api_service_id ?? 0;
			$order->api_provider_id  = $service->api_provider_id ?? 0;
			$order->api_order  = $service->api_service_id ? 1 : 0;
			$order->link = $serviceArray[1];
			$order->quantity  = $serviceArray[2];
			$order->price = $price;
			$order->remains  = $serviceArray[2];
			$order->status = 0;
			$order->note = $request->note;
            $order->check = $request->check == 'on' ? 1:0;
			$order->save();

            //make transaction
			$transaction               = new Transaction();
			$transaction->user_id      = $user->id;
			$transaction->amount       = $price;
			$transaction->post_balance = getAmount($user->balance);
			$transaction->trx_type     = '-';
			$transaction->details      = 'Order for ' . $service->name;
			$transaction->trx          = getTrx();
			$transaction->remark       = "Order";
			$transaction->save();

            //make notification
            $adminNotification = new AdminNotification();
            $adminNotification->user_id = $user->id;
            $adminNotification->title = $order->order_no.' Order pending from '.$user->username;
            $adminNotification->click_url = urlPath('admin.users.detail',$user->id);
            $adminNotification->save();

            notify($user, 'PENDING_ORDER', [
                'service_name'  =>$service->name,
                'username' => $user->username,
                'price' => $order->price,
            ]);

		}

        $notify[] = ['success', 'Successfully placed your order!'];
		return back()->withNotify($notify);
    }
    //end mass order

    //brand package
    public function getPackageOrder(){
        $pageTitle = 'Brand Package Order Lists';
        $brandPackageOrder = BrandPackageOrder::where('status','!=',5)->where('user_id',auth()->user()->id)->with('user')->orderBy('created_at','desc')->paginate(getPaginate(12));
        return view($this->activeTemplate.'user.orders.brand_package_order_index',compact('pageTitle','brandPackageOrder'));
    }

    public function brandPackage($id){
        $pageTitle = 'New Brand Package Order';
        $brandPackage = BrandPackage::findOrFail($id);
        return view($this->activeTemplate.'user.orders.brand_package',compact('pageTitle','brandPackage'));
    }

    public function brandPackagepPlace(Request $request){

        $request->validate([
            'name'=>'required',
            'links' => ['required', 'array'],
            'links.*' => 'required|url',
            'price' => 'required|numeric|min:0',
            'check'=>'required'
        ]);

        $links =  json_encode($request->links);
        $user = auth()->user();

        // Store order in session
        Session::put('brandPackageSession', [
            'user_id' => $user->id,
            'name' => $request->name,
            'price' => $request->price,
            'links' => $links,
            'note' => $request->note,
            'check' => $request->check,
        ]);

        $gatewayCurrency = GatewayCurrency::whereHas('method', function ($gate) {
            $gate->where('status', 1);
        })->with('method')->orderby('method_code')->get();
        $pageTitle = 'Payment Methods';

        return view($this->activeTemplate . 'user.payment.brand_package_payment', compact('gatewayCurrency', 'pageTitle'));
    }

    public function bPOrderInsert($orderData , $status=null){
        $brandPackageOrder = new BrandPackageOrder();
        $brandPackageOrder->user_id = $orderData['user_id'];
        $brandPackageOrder->name = $orderData['name'];
        $brandPackageOrder->price = $orderData['price'];
        $brandPackageOrder->link = $orderData['links'];
        $brandPackageOrder->note = $orderData['note'];
        $brandPackageOrder->check = $orderData['check'];
        $brandPackageOrder->status = $status ?? 5;
        $brandPackageOrder->save();
        return $brandPackageOrder;
    }
    //end brand package

    protected function getOrder($status, $pageTitle){
        $orders = Order::where('user_id', auth()->user()->id)
                       ->where('status', $status)
                       ->latest()
                       ->with(['service', 'user', 'category'])
                       ->paginate(getPaginate(12));
        return view($this->activeTemplate . 'user.orders.index', compact('pageTitle', 'orders'));
    }

}
