<?php

namespace App\Http\Controllers\Reseller;

use App\DataTables\SocialPricePerBalanceDataTable;
use App\DataTables\USSDPaymentRequestDataTable;
use App\DataTables\USSDPricePerBalanceDataTable;
use App\Http\Controllers\Controller;
use App\ResellerUssdPayment;
use App\Traits\Server6UssdDatabase;
use App\User;
use App\UssdPayment;
use App\UssdPrice;
use App\UssdService;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;

class ResellerUssdPricingController extends Controller
{

    use Server6UssdDatabase;

    public function subscription_request(USSDPaymentRequestDataTable $social)
    {
        return $social->user(Auth::user()->id)->render('reseller.pricing.ussd_index',compact('package'));
    }


    public function subscription_request_assign(Request $request)
    {
        $packages = Auth::user()->ussd_price;
        return view('reseller.pricing.ussd_assign',compact('packages'));
    }


    public function subscription_request_post(Request $request,UssdService $service,UssdPrice $package)
    {

        DB::beginTransaction();
        UssdPayment::query()->updateOrCreate(['ussd_service_id' => $service->id],
            [
                'amount' => $package->cost,
                'ussd_price_id' => $package->id,
                'transaction_id' => strtoupper(Str::random(12)),
                'status' => 'success',
                'payment_date' => date('Y-m-d H:i:s'),
                'has_expired' => 0,
                'expiry_date' => Carbon::parse(now())->addDays(30),
                'response_message' => 'Credited by reseller for client'
            ]
        );

        $service->update(['purchase_status'=>'paid','sessions'=>$package->sessions]);
//        $service->update(['purchase_status'=>'paid','sessions'=>$service->ussd_payment->ussd_price->sessions]);


        $connection = $this->ussdLiveDBConnection();
        //insert data into the db
        $extension = $this->extractExtensionFromServiceCode($service->code);
        //purchase status
        $purchaseStatus = UssdService::USSD_SERVICE_PURCHASE_STATUS_PAID;
        $sql =  "UPDATE services SET purchase_status = '$purchaseStatus'
                and session_used = 0 and package_session = '{$package->sessions}'
                WHERE extension = '$extension'";

        mysqli_query($connection,$sql);

        DB::commit();
        return redirect()->route('reseller.ussd.subscription.request')->with('success','Package Successfully assigned');
    }



    public function ussd_price_index(Request $request, USSDPricePerBalanceDataTable $ussd)
    {
        $user = auth()->user();
        $id = $user->id;
        $package = $user->ussd_balance;
        return $ussd->user($id)->render('reseller.pricing.ussd_index',compact('package'));
    }

    public function ussd_price_create(Request $request)
    {
        $user = auth()->user();
        $limit = $user->ussdSubscriptionLimits();// check for subscription limits and redirect accordingly

        if(!isset($limit)):
            $route = $user->under_reseller() ? url()->previous():  route('reseller.ussd.subscription.index');
            $flash = $user->under_reseller() ? 'Contact your account administrator to sign up on a mail package': 'kindly choose a package here !!';
            return redirect($route)->withErrors($flash);
        endif;

        $package = $user->ussd_balance;
        return $request->isMethod('post') ? $this->ussd_price_post($request) : view('reseller.pricing.ussd_create',compact('package'));
    }

    public function ussd_price_edit(Request $request,UssdPrice $package)
    {

        return $request->isMethod('post') ? $this->ussd_price_update($request,$package) : view('reseller.pricing.ussd_edit',['package'=>$package]);
    }


    public function ussd_price_post($request)
    {
        $user = auth()->user();
        $package = $user->ussd_balance;;  //get package limits

        $data = $request->validate(
            [
                'name'        => 'required|unique:ussd_prices',
                'cost'        => 'required',
                'sessions' => "required",
                'apply_to'    => 'required',
                'is_active'   => 'required',
            ]
        );


        $balance_data['sessions'] = $this->contacts($package,$request);

        $validator = Validator::make($request->all(), [
            'sessions' => "lte:$package->sessions",
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                ->withErrors('session count cannot be greater than '.$package->sessions)->withInput();
        }

        $balance = ['sessions'   =>    $package->sessions - $data['sessions']];


        DB::beginTransaction();

            $package->update($balance);
            $user->ussd_price()->create($data);
            auth()->user()->trail("CREATED USSD Pricing {$data['name']}");

        DB::commit();

        return redirect()->route('reseller.ussd.price.setup.index')->with('success', 'Pricing Successfully Created !!');
    }


    public function ussd_price_update($request,$package)
    {
        $user = auth()->user();

        $balance = $user->ussd_balance;

        $data = $request->validate(
            [
                'name'        => 'required|unique:ussd_prices,id,'.$package->id,
                'cost'        => 'required',
                'sessions'    => 'required|min:1|max:'.$package->sessions,
                'apply_to'    => 'required',
                'is_active'   => 'required',
            ]
        );



        /**
         ** for balance updates when the values increases or decreases;
         **/

        $balance_data['sessions'] = $this->contacts($package,$request);

        $validator = Validator::make($balance_data, [
            'sessions' => "lte:$package->sessions",
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                ->withErrors('session count cannot be greater than '.$package->sessions)->withInput();
        }




        $balance_data = ['sessions' => $balance->sessions + $balance_data['sessions']];

        DB::beginTransaction();
        $balance->update($balance_data);
        $package->update($data);
        \auth()->user()->trail("UPDATED USSD Package {$data['name']}");
        DB::commit();

        return redirect()->route('reseller.ussd.price.setup.index')->with('success', 'Pricing Successfully UPDATED !!');

    }


    public function contacts($package,$request)
    {
        if($package->sessions > $request->sessions)
            $balance_data =  $package->sessions - $request->sessions ;
        elseif($package->sessions < $request->sessions)  //if incoming value is greater than existing
            $balance_data = -(-$package->sessions + $request->sessions);
        else
            $balance_data = 0;
//            $balance_data = (int)$request->sessions;

        return $balance_data;
    }

    public function email_price_destroy(EmailPricing $package)
    {
        DB::beginTransaction();
        \auth()->user()->trail("DELETED Email Package {$package->package}");
        $package->delete();
        DB::commit();

        return redirect()->back()->with('success',"Package Successfully Deleted");

    }

    public function email_payment_history(MailPaymentHistoryDataTable $history)
    {
        return $history->render('reseller.pricing.history');
    }

    public function subscription_index()
    {

        $packages = UssdPrice::query()->where([['is_active',true],['user_id',null],['apply_to','resellers']])->get();
        $subscription = auth()->user()->ussd_subscription;
        $subscriptionIsValid = auth()->user()->ussdSubscriptionIsValid();

        return view('reseller.subscription.ussd.index',compact('packages','subscription','subscriptionIsValid'));
    }


    public function subscription_signup(Request $request,UssdPrice $package)
    {
//        dd($package);
        return $request->isMethod('post') ? $this->subscription_post($request,$package) :view('reseller.subscription.ussd.payment',compact('package'));
    }

    public function subscription_post($request,$package)
    {

        $data = $request->validate(
            [
                'operator'    => 'required',
                'momo_number' => 'required',
                'amount'      => 'required',
                'voucher'     => 'required_if:operator,==,vodafone',
            ]
        );

        $data['user_id']          = auth()->user()->id;
        $data['username']         = auth()->user()->username;
        $data['ussd_price_id']    = $package->id;
        $data['callback']         = route('ussd.payment.callback');
        $data['transaction_id']   = $data['user_id'].'_'.Str::random('20');
        $data['request_body']     = json_encode($data);

        $data = (object)$data;

        $payment = $this->ussdPayCurl($data);

        return $payment->status ?? 'failed' == 'success' ? redirect()->route('reseller.ussd.subscription.index')
                ->with('success','Payment successfully initiated Kindly check your momo wallet to approve the transaction.') :
                redirect()->back()->withInput()->withErrors('Error Payment could not be initiated Kindly try again !!');

    }

    public function ussdPayCurl($params)
    {

        ResellerUssdPayment::query()->create((array)$params);

        $paymentEndpoint = "https://pay.npontu.com/api/pay";

        $request = array(
            'number' => $params->momo_number,
            'vendor' => $params->operator,
            'uid'    => 'npdeywuro',
            'pass'   => 'hdgt2314',
            'tp'     => $params->transaction_id,
            'cbk'    => $params->callback,
            'amt'    => $params->amount,
            'msg'    => 'DEYWURO ussd PAYMENT',
            'vou'    => $params->voucher,
            'trans_type' => 'Debit'
        );
        $ch = curl_init($paymentEndpoint);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        return json_decode($output);
    }

    public function payment_history(UserMailPaymentHistoryDataTable $history)
    {
        return $history->render('reseller.subscription.history');
    }
}
