<?php
namespace Modules\Booking\Models;

use App\BaseModel;
use App\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Modules\Tour\Models\Tour;
use Modules\User\Emails\CreditPaymentEmail;
use Modules\User\Emails\PlanPaymentEmail;
use Modules\User\Emails\VendorRegisteredEmail;
use Modules\User\Events\UpdatePlanRequest;
use Modules\User\Models\Plan;
use Modules\User\Models\PlanPayment;
use Modules\User\Models\Wallet\Transaction;

class Payment extends BaseModel
{
    protected $table = 'bravo_booking_payments';
    protected $meta_json = null;

    public function save(array $options = [])
    {
        if (empty($this->code))
            $this->code = $this->generateCode();
        return parent::save($options); // TODO: Change the autogenerated stub
    }

    public function getStatusNameAttribute()
    {
        return booking_status_to_text($this->status);
    }

    public function getGatewayObjAttribute()
    {
        return $this->payment_gateway ? get_payment_gateway_obj($this->payment_gateway) : false;
    }

    public function generateCode()
    {
        return md5(uniqid() . rand(0, 99999));
    }

    public function notifyObject(){
        switch ($this->object_model){
            case "wallet_deposit":
                if($this->status != 'completed'){
                    $url = route('user.wallet');
                    return [false,__("Payment fail"),$url];
                }

                $wallet_transaction_id = $this->wallet_transaction_id;
                $trans = Transaction::find($wallet_transaction_id);
                if (!$trans) {
                    return [false, __("Transaction not found"), '/'];
                }
                $trans->confirm();
                $url = route('user.wallet');
                return [true, __("Payment updated"), $url];

                break;
            case "plan":
                $userRequest = $this->getMeta('user_request');
                if(!empty($userRequest)){
                    $user = User::find($userRequest);
                }else{
                    $user = $this->user;
                }
                if($this->status != 'completed' && $this->status != 'cancel'){
                    $url = route('user.plan');
                    return [false,__("Plan fail"),$url];
                }

                if(!empty($user)){
                    try {
                        $plan = Plan::find($this->object_id);
                        $is_annual = $this->getMeta('annual');
                        $price = $is_annual?$plan->annual_price:$plan->price;
                        $user->applyPlan($plan,$price,$is_annual, true, $this->status);

                    }catch (\Exception $exception){
                        $url =  route('user.plan');
                        return [false,$exception->getMessage(),$url];
                    }

                    $url = route('user.plan');
                    return [true,__("Plan updated"),$url];
                }
            break;

        }
    }

    public function markAsFailed($logs = ''){
        $this->status = 'fail';
        $this->logs = \GuzzleHttp\json_encode($logs);
        $this->save();
        $this->sendUpdatedPurchaseEmail();
        return $this->notifyObject();
    }
    public function markAsCancel($logs = ''){
        $this->status = 'cancel';
        $this->logs = \GuzzleHttp\json_encode($logs);
        $this->save();
        $this->sendUpdatedPurchaseEmail();
        return $this->notifyObject();
    }

    public function markAsCompleted($logs = ''){
        $this->status = 'completed';
        $this->logs = \GuzzleHttp\json_encode($logs);
        $this->save();
        $this->sendNewPurchaseEmail();
        return $this->notifyObject();
    }


    public function getMeta($key = '', $default = '')
    {
        if(!$key){
            return PaymentMeta::query()->get()->toArray();
        }
        $val = PaymentMeta::query()->where([
            'payment_id' => $this->id,
            'name'       => $key
        ])->first();
        if (!empty($val)) {
            return $val->val;
        }
        return $default;
    }

    public function getJsonMeta($key, $default = [])
    {
        $meta = $this->getMeta($key, $default);
        if(empty($meta)) return false;
        return json_decode($meta, true);
    }

    public function addMeta($key, $val, $multiple = false)
    {

        if (is_object($val) or is_array($val))
            $val = json_encode($val);
        if ($multiple) {
            return PaymentMeta::create([
                'name'       => $key,
                'val'        => $val,
                'payment_id' => $this->id
            ]);
        } else {
            $old = PaymentMeta::query()->where([
                'payment_id' => $this->id,
                'name'       => $key
            ])->first();
            if ($old) {
                $old->val = $val;
                return $old->save();

            } else {
                return PaymentMeta::create([
                    'name'       => $key,
                    'val'        => $val,
                    'payment_id' => $this->id
                ]);
            }
        }
    }



    public function sendUpdatedPurchaseEmail(){

        switch ($this->object_model){
            case "wallet_deposit":
                Mail::to(setting_item('admin_email'))->send(new CreditPaymentEmail(false, $this, 'admin'));
                if($this->user)
                    Mail::to($this->user->email)->send(new CreditPaymentEmail(false, $this, 'customer'));
            break;
            case "plan":
                if (!empty(setting_item("plan_update_payment_admin_enable")) and !empty(setting_item("plan_update_payment_admin_subject")) and !empty(setting_item("plan_update_payment_admin_content"))) {
                    Mail::to(setting_item('admin_email'))->send(new PlanPaymentEmail(false, $this, 'admin'));
                }

                if ($this->user) {
                    if (!empty(setting_item("plan_update_payment_user_enable")) and !empty(setting_item("plan_update_payment_user_subject")) and !empty(setting_item("plan_update_payment_user_content"))) {
                        Mail::to($this->user->email)->send(new PlanPaymentEmail(false, $this, 'customer'));
                    }
                }
            break;
        }

    }

    public function sendNewPurchaseEmail(){

        switch ($this->object_model) {
            case "wallet_deposit":
                Mail::to(setting_item('admin_email'))->send(new CreditPaymentEmail(true, $this, 'admin'));

                if ($this->user)
                    Mail::to($this->user->email)->send(new CreditPaymentEmail(true, $this, 'customer'));
            break;

            case "plan":
                $userRequest = $this->getMeta('user_request');

                if(!empty($userRequest)){
                    $user = User::find($userRequest);
                }else{
                    $user = $this->user;
                }

                if (!empty(setting_item("plan_new_payment_admin_enable")) and !empty(setting_item("plan_new_payment_admin_subject")) and !empty(setting_item("plan_new_payment_admin_content"))) {
                    Mail::to(setting_item('admin_email'))->send(new PlanPaymentEmail(true, $this, 'admin'));
                }


                if ($user) {

                    if (!empty(setting_item("plan_new_payment_user_enable")) and !empty(setting_item("plan_new_payment_user_subject")) and !empty(setting_item("plan_new_payment_user_content"))) {
                        Mail::to($user->email)->send(new PlanPaymentEmail(true, $this, 'customer'));
                    }
                }
            break;
        }
    }

}
