<?php

namespace App\Http\Controllers\User;


use App\Http\Controllers\Controller;
use App\Http\Controllers\Pay\PayController;
use App\Http\Controllers\Pay\PayoneController;
use App\Models\Homeparty;
use App\Models\PaymentMethod;
use App\Models\PaymentTransaction;
use App\Models\ShippingCountry;
use App\Models\ShoppingOrder;
use App\Models\ShoppingOrderItem;
use App\Models\ShoppingOrderMargin;
use App\Models\ShoppingPayment;
use App\Models\ShoppingUser;
use App\Services\CustomerPriority;
use App\Services\Payment;
use App\Services\Shop;
use App\User;
use Illuminate\Session\SessionManager;
use Illuminate\Support\Collection;
use Validator;
use App\Services\Util;
use Yard;
use Request;

class CheckoutController extends Controller
{
    private $session;
    private $instance;
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct(SessionManager $session)
    {
        $this->session = $session;
        $this->instance = sprintf('%s.%s', 'cart', 'payments');
    }


    public function checkout($identifier){

       // dump(Request::all());
//        $user_shop = Util::getUserShop();

        //user shop
        /*
        $user_shop = $shopping_instance->user_shop;
        if($user_shop &&  $user_shop->active == 1 && $user_shop->user->isActiveShop()){
            Util::setPostRoute('user/');
            \Session::put('user_shop', $user_shop);
            \Session::put('user_shop_domain', $shopping_instance->subdomain);
            \Session::put('user_shop_payment', $shopping_instance->payment);
            \Session::put('user_shop_identifier', $shopping_instance->identifier);
            \Session::put('isCheckout', true);

            if($shopping_instance->auth_user_id){
                \Session::put('auth_user', $shopping_instance->auth_user);
            }
        }
        if($shopping_instance->back){
            \Session::put('back_link', $shopping_instance->back);
        }
        \Session::put('new_session', true);
        Yard::instance('shopping')->destroy();
        //restore yard
        Yard::instance('shopping')->restore($request->route('identifier'));

        Yard::instance('shopping')->putYardExtra('user_shop_payment', $shopping_instance->payment);

        Yard::instance('shopping')->putYardExtra('shopping_data', $shopping_instance->shopping_data);
        $is_for = isset($shopping_instance->shopping_data['is_for']) ? $shopping_instance->shopping_data['is_for'] : 'ot';
        Yard::instance('shopping')->setShippingCountryWithPrice($shopping_instance->country_id, $is_for);
        */

        if($this->getPayments('identifier') !== $identifier){
            $this->destroy();
            $this->putPayments('identifier', $identifier);
        }

         $shopping_data = Yard::instance('shopping')->getYardExtra('shopping_data');
         $is_from =  isset($shopping_data['is_from']) ? $shopping_data['is_from'] : 'shopping';
         $is_for = isset($shopping_data['is_for']) ? $shopping_data['is_for'] : false;
         $shopping_user = null;


        if(!$this->getPayments('shopping_user_id')){
              if($shopping_data && $is_from !== 'shopping'){
                  //can  wizard membership user_order
                  //$shopping_user_id = isset($shopping_data['shopping_user_id']) ? $shopping_data['shopping_user_id'] : false;
                  $shopping_user = $this->shoppingUserAuthData($is_from, $is_for, $shopping_data);
                  $shopping_user->save();
                  $this->putPayments('shopping_user_id', $shopping_user->id);
              }elseif($is_from === 'shopping') {
                  $shopping_user = new ShoppingUser();
                  $shopping_user->is_for = $is_for;
                  $shopping_user->is_from = $is_from;
                  $shopping_user->mode = 'prev';
              }
        }else{
            $shopping_user = ShoppingUser::findOrFail($this->getPayments('shopping_user_id'));
            $shopping_user->billing_state = Shop::getCountryShippingCountryId($shopping_user->billing_country_id);
            $shopping_user->shipping_state = Shop::getCountryShippingCountryId($shopping_user->shipping_country_id);
        }
        if($shopping_user->same_as_billing === NULL){
            $shopping_user->same_as_billing = false;
        }

        if(old('selected_country') && old('selected_country') === 'change'){
            \Session::forget('_old_input.selected_country');
            $shopping_user->billing_state = old('billing_state');
            $shopping_user->shipping_state = old('shipping_state');
        }else{
            $shopping_user->billing_state = Yard::instance('shopping')->getShippingCountryId();
            $shopping_user->shipping_state = Yard::instance('shopping')->getShippingCountryId();
        }

        /*if(Util::getAuthUser()){
            $shopping_user->abo_options = Util::getUserHistoryValue('abo_options');
            //$shopping_user->save();
        }*/

        if($is_from !== 'shopping' && Util::getAuthUser()){
            $user = Util::getAuthUser();
            $user_payment_methods = $user->payment_methods;
            $payment_data = $user->account->payment_data;
        }else{
            $user_payment_methods = PaymentMethod::getDefaultAsArray()->toArray();
            $payment_data = false;
        }

        $data = [
            'is_from' => $is_from,
            'is_for' => $is_for,
            'shopping_data' => $shopping_data,
            'user_shop' => Util::getUserShop(),
            'shopping_user' => $shopping_user,
            'shopping_mode' => Util::getUserShoppingMode(),
            'user_payment_methods' => $user_payment_methods,
            'identifier' => $identifier,
            'payment_data' => $payment_data,
            'back' => url()->previous(),
        ];
        return view('user.checkout.checkout', $data);
    }

    private function shoppingUserAuthData($is_from, $is_for, $data = []){

        $user = Util::getAuthUser();
        $shopping_user = new ShoppingUser();
        $shopping_user->auth_user_id = $user->id;
        $shopping_user->mode = 'prev';

        $shopping_user->billing_salutation = $user->account->salutation;
        $shopping_user->billing_company = $user->account->company;
        $shopping_user->billing_firstname = $user->account->first_name;
        $shopping_user->billing_lastname = $user->account->last_name;
        $shopping_user->billing_address = $user->account->address;
        $shopping_user->billing_address_2 = $user->account->address_2;
        $shopping_user->billing_zipcode = $user->account->zipcode;
        $shopping_user->billing_city = $user->account->city;
        $shopping_user->billing_country_id = $user->account->country_id;
        $shopping_user->billing_phone = $user->account->phone;
        $shopping_user->billing_email = $user->email;
        $shopping_user->faker_mail = false;
        $shopping_user->shipping_email = $user->email;

        $shopping_user->accepted_data_checkbox = 1;
        $shopping_user->is_for = $is_for;
        $shopping_user->is_from = $is_from;

        //Lieferadresse
        if($is_from === 'user_order'){
            if(isset($data['shopping_user_id']) && $data['is_for'] === 'ot'){
                $s_user = ShoppingUser::findOrFail($data['shopping_user_id']);
              /*  $shopping_user->billing_salutation = $s_user->billing_salutation;
                $shopping_user->billing_company = $s_user->billing_company;
                $shopping_user->billing_firstname = $s_user->billing_firstname;
                $shopping_user->billing_lastname = $s_user->billing_lastname;
                $shopping_user->billing_address = $s_user->billing_address;
                $shopping_user->billing_address_2 = $s_user->billing_address_2;
                $shopping_user->billing_zipcode = $s_user->billing_zipcode;
                $shopping_user->billing_city = $s_user->billing_city;
                $shopping_user->billing_country_id = $s_user->billing_country_id;
                $shopping_user->billing_phone = $s_user->billing_phone;
                $shopping_user->billing_email = $s_user->billing_email;
                ;*/
                $shopping_user->faker_mail = $s_user->faker_mail;
                if(!$s_user->faker_mail){
                    $shopping_user->shipping_email = $s_user->billing_email;
                }
                $shopping_user->shopping_user_id = $data['shopping_user_id'];
                $shopping_user->member_id = $s_user->member_id;
            }
            $shopping_user->same_as_billing = true;
            $shopping_user->shipping_salutation = isset($data['shipping_salutation']) ? $data['shipping_salutation'] : '';
            $shopping_user->shipping_company = isset($data['shipping_company']) ? $data['shipping_company'] : '';
            $shopping_user->shipping_firstname = isset($data['shipping_firstname']) ? $data['shipping_firstname'] : '';
            $shopping_user->shipping_lastname = isset($data['shipping_lastname']) ? $data['shipping_lastname'] : '';
            $shopping_user->shipping_address = isset($data['shipping_address']) ? $data['shipping_address'] : '';
            $shopping_user->shipping_address_2 = isset($data['shipping_address_2']) ? $data['shipping_address_2'] : '';
            $shopping_user->shipping_zipcode = isset($data['shipping_zipcode']) ? $data['shipping_zipcode'] : '';
            $shopping_user->shipping_city = isset($data['shipping_city']) ? $data['shipping_city'] : '';
            $shopping_user->shipping_country_id = Yard::instance('shopping')->getShippingCountryCountryId();
            $shopping_user->shipping_phone = isset($data['shipping_phone']) ? $data['shipping_phone'] : '';

        }else{
            $shopping_user->same_as_billing = $user->account->same_as_billing ? false : true;
            $shopping_user->shipping_salutation = $user->account->shipping_salutation;
            $shopping_user->shipping_company = $user->account->shipping_company;
            $shopping_user->shipping_firstname = $user->account->shipping_firstname;
            $shopping_user->shipping_lastname = $user->account->shipping_lastname;
            $shopping_user->shipping_address = $user->account->shipping_address;
            $shopping_user->shipping_address_2 = $user->account->shipping_address_2;
            $shopping_user->shipping_zipcode = $user->account->shipping_zipcode;
            $shopping_user->shipping_city = $user->account->shipping_city;
            $shopping_user->shipping_country_id = $user->account->shipping_country_id;
            $shopping_user->shipping_phone = $user->account->shipping_phone;
        }

        return $shopping_user;
    }

    public function store($identifier){


        $data = Request::all();
        //change selected Country
        /*if(isset($data['selected_country']) && $data['selected_country'] === 'change'){
            if(!Request::get('same_as_billing')){
                Yard::instance('shopping')->setShippingCountryWithPrice($data['billing_state'], $data['is_for']);
            }else{
                Yard::instance('shopping')->setShippingCountryWithPrice($data['shipping_state'], $data['is_for']);
            }
            return back()->withInput(Request::all());
        }*/

        $rules = array(
            'billing_salutation' => 'required',
            'billing_firstname'=>'required',
            'billing_lastname'=>'required',
            'billing_email'=>'required|email',
            'billing_address'=>'required',
            'billing_zipcode'=>'required',
            'billing_city' => 'required',
            'accepted_data_checkbox' => 'accepted',
        );

        if(Request::get('same_as_billing')){
            $rules = array_merge($rules, [
                'shipping_firstname'=>'required',
                'shipping_lastname'=>'required',
                'shipping_address'=>'required',
                'shipping_zipcode'=>'required',
                'shipping_city' => 'required',
                'shipping_salutation' => 'required'

            ]);
        }
        $validator = Validator::make(Request::all(), $rules);
        if ($validator->fails()) {
            return back()->withErrors($validator)->withInput(Request::all());
        }

        $data = Request::all();
        //make User
        $shopping_user = $this->makeShoppingUser($data);

        //make Order and Items
        $shopping_order =  $this->makeShoppingOrder($shopping_user);
        //CustomerPriority
        if($shopping_user->is_from === 'shopping'){
            CustomerPriority::checkOne(ShoppingUser::find($shopping_user->id), true);
        }
        Util::setUserHistoryValue(['status'=>2, 'shopping_order_id'=>$shopping_order->id], $identifier);

        //check credit Card
        if(Request::get('payment_method')){

            $ret = [];
            //Rechnungskauf ohne PAYONE
            if(Request::get('payment_method') === 'fnc#MIV'){

            }
            //other
            $pay = new PayController();
            $pay->init($shopping_user, $shopping_order);
            $amount = Yard::instance('shopping')->totalWithShipping(2, '.', '') * 100;
            $reference = $pay->setPrePayment(Request::get('payment_method'), $amount, 'EUR', $ret);
            $this->putPayments('payment_reference', $reference);
            $pay->setPersonalData();
            return $pay->ResponseData($identifier);
        }

        return redirect()->back();
    }




    public function final($transactionId, $reference, $identifier)  {

        $payt = PaymentTransaction::findOrFail($transactionId);
        if($payt->shopping_payment->reference != $reference){
            abort(404);
        }
        Yard::instance('shopping')->destroy();
        $this->destroy();

        if($payt->status === 'fnc' || $payt->status === 'vor'){
            $this->directPaymentStatus($payt, $identifier);
        }

        $data = [
            'order_reference' => $payt->shopping_payment->reference,
            'pay_trans' => $payt,
        ];
        return view('user.checkout.final', $data);
    }

    /*private function storeUserPaymentsData($shopping_user, $ret){
        if($shopping_user->auth_user_id){
            $user = User::find($shopping_user->auth_user_id);
            if($user && $user->account){
                if(isset($ret['elv']) && is_array($ret['elv'])){
                    $user->account->payment_data = $ret['elv'];
                    $user->account->save();
                }
            }
        }
    }*/
    public function transactionStatus($status, $reference){
        die("not defined");
        $shopping_order_id = $this->getPayments('shopping_order_id');

        $ShoppingPayment = ShoppingPayment::where('shopping_order_id', $shopping_order_id)->where('reference', $reference)->first();
        if(!$ShoppingPayment){
            //TODO log this
            Util::setUserHistoryValue(['status'=>21]);

            \Session::flash('checkout-error', 'Der Zahlungsvorgang konnte nicht abgeschlossen werden, die Zahlung wurde nicht gefunden: '.$reference);
            return redirect(route('checkout.checkout_card'));
        }
        $ShoppingPayment->status = $status;
        $ShoppingPayment->save();

        if($status === "success"){

            Yard::instance('shopping')->destroy();
            $this->destroy();

            $payt = $ShoppingPayment->payment_transactions->last();

            $data = [
                'user_shop' => Util::getUserShop(),
                'order_reference' => $reference,
                'pay_trans' => $payt,
            ];
            return view('web.templates.checkout-final', $data);
        }
        if($status === "cancel"){
            Util::setUserHistoryValue(['status'=>22]);
            \Session::flash('checkout-error', 'Der Zahlungsvorgang wurde abgebrochen, die Bestellung konnte nicht ausgeführt werden.');
            return redirect(route('checkout.checkout_card'));

        }
        if($status === "error"){
            Util::setUserHistoryValue(['status'=>23]);
            \Session::flash('checkout-error', 'Der Zahlungsvorgang wurde abgebrochen, die Bestellung konnte nicht ausgeführt werden.');
            return redirect(route('checkout.checkout_card'));

        }
    }

    private function makeShoppingUser($data){

        $data['same_as_billing'] = isset($data['same_as_billing']) ? false : true; //reinvert
        $data['accepted_data_checkbox'] = isset($data['accepted_data_checkbox']) ? true : false;

        $shopping_user = false;
        if($this->getPayments('shopping_user_id')){
            $shopping_user = ShoppingUser::find($this->getPayments('shopping_user_id'));
            if($shopping_user){
                $shopping_user->fill($data);
                $shopping_user->mode = null;
                $shopping_user->save();
            }
        }
        if(!$shopping_user){
            $shopping_user = ShoppingUser::create($data);
        }
        $this->putPayments('shopping_user_id', $shopping_user->id);

        return $shopping_user;
    }

    private function makeShoppingOrder($shopping_user){

        $user_shop = Util::getUserShop();
        $discount = 0;
        if(Yard::instance('shopping')->getYardMargin()){
            $discount = Yard::instance('shopping')->getYardMargin()->net_discount;
        }
        $data = [
            'shopping_user_id' => $shopping_user->id,
            'auth_user_id' => $shopping_user->auth_user_id,
            'country_id' => Yard::instance('shopping')->getShippingCountryId(),
            'payment_for' => Util::getUserPaymentFor(),
            'total' => Yard::instance('shopping')->total(2, '.', ''),
            'subtotal_full' => Yard::instance('shopping')->subtotal(2, '.', '', false),
            'discount' => $discount,
            'subtotal' => Yard::instance('shopping')->subtotal(2, '.', ''),
            'shipping' => Yard::instance('shopping')->shipping(2, '.', ','),
            'shipping_net' => Yard::instance('shopping')->shippingNet(2, '.', ''),
            'subtotal_shipping' => Yard::instance('shopping')->subtotalWithShipping(2, '.', ''),
            'tax' => Yard::instance('shopping')->taxWithShipping(2, '.', ''),
            'total_without_credit' => Yard::instance('shopping')->totalWithShippingWithoutCredit(2, '.', ''),
            'payment_credit' => Yard::instance('shopping')->totalfromCredit(2, '.', ''),
            'total_shipping' => Yard::instance('shopping')->totalWithShipping(2, '.', ''),
            'points' => Yard::instance('shopping')->points(),
            'weight' => Yard::instance('shopping')->weight(),
            'txaction' => 'prev',
            'mode' => Util::getUserShoppingMode(),
        ];


        $shopping_order= false;
        if($this->getPayments('shopping_order_id')){
            $shopping_order = ShoppingOrder::find($this->getPayments('shopping_order_id'));
            if($shopping_order){
                $shopping_order->fill($data);
                $shopping_order->save();
            }
        }
        if(!$shopping_order){
            $shopping_order = ShoppingOrder::create($data);
        }
        $this->makeOrderMargin($shopping_order);

        $this->putPayments('shopping_order_id', $shopping_order->id);
         $items = Yard::instance('shopping')->getContentByOrder();
         $shopping_order->shopping_order_items()->each(function($model) use ($items, $shopping_order, $shopping_user) {
             foreach ($items as $item) {
                    if ($model->row_id === $item->rowId) {
                        $data = [
                            'shopping_order_id' => $shopping_order->id,
                            'row_id' =>  $item->rowId,
                            'product_id' => $item->id,
                            'comp' => $item->options->comp,
                            'qty' => $item->qty,
                            'price' => $item->price,
                            'price_net' => Yard::instance('shopping')->rowPriceNet($item, 3, '.', ''),
                            'tax_rate' => $item->taxRate,
                            'slug' => $item->options->slug,
                        ];
                        $model->fill($data)->save();
                        return false;
                    }
                }
                return $model->delete();
        });


        foreach ($items as $item) {
            if (!ShoppingOrderItem::where('shopping_order_id', $shopping_order->id)->where('row_id', $item->rowId)->count()){
                $data = [
                    'shopping_order_id' => $shopping_order->id,
                    'row_id' =>  $item->rowId,
                    'product_id' => $item->id,
                    'comp' => $item->options->comp,
                    'qty' => $item->qty,
                    'price' => $item->price,
                    'price_net' => Yard::instance('shopping')->rowPriceNet($item, 3, '.', ''),
                    'tax_rate' => $item->taxRate,
                    'slug' => $item->options->slug
                ];
                $shopping_order_item = ShoppingOrderItem::create($data);
            }
        }
        return $shopping_order;
    }

    private function makeOrderMargin(ShoppingOrder $shopping_order)
    {

        if (Yard::instance('shopping')->getYardMargin()) {

            $data = [
                'shopping_order_id' => $shopping_order->id,
                'user_id' => $shopping_order->auth_user_id,
                'net_price' => Yard::instance('shopping')->getYardMargin()->net_price,
                'net_discount' => Yard::instance('shopping')->getYardMargin()->net_discount,
                'net_amount' => Yard::instance('shopping')->getYardMargin()->net_amount,
                'from_payment_credit' => Yard::instance('shopping')->totalfromCredit(2, '.', ''),
                'from' => now(),
                'content' => serialize(Yard::instance('shopping')->getYardMargin()->toArray())
            ];
            if(Yard::instance('shopping')->getYardMargin()->net_partner_commission > 0){
                $data['m_sponsor_id'] = $shopping_order->auth_user->m_sponsor;
                $data['net_partner_commission'] = Yard::instance('shopping')->getYardMargin()->net_partner_commission;
            }
            $shopping_order_margin = false;
            if ($this->getPayments('shopping_order_margin_id')) {
                $shopping_order_margin = ShoppingOrderMargin::find($this->getPayments('shopping_order_margin_id'));
                if ($shopping_order_margin) {
                    $shopping_order_margin->fill($data);
                    $shopping_order_margin->save();}
            }
            if (!$shopping_order_margin) {
                $shopping_order_margin = ShoppingOrderMargin::create($data);
            }
            $this->putPayments('shopping_order_margin_id', $shopping_order_margin->id);
        }
    }
    private function putPayments($key, $value){
        $content = $this->getContent();
        $content->put($key, $value);
        $this->session->put($this->instance, $content);

    }

    private function getPayments($key){
        $content = $this->getContent();
        if ($content->has($key)){
            return $content->get($key);
        }
        return false;
    }

    private function getContent()
    {
        if (is_null($this->session->get($this->instance))) {
            return new Collection([]);
        }
        return $this->session->get($this->instance);
    }

    public function destroy()
    {
        $this->session->remove($this->instance);
    }

    private function directPaymentStatus(PaymentTransaction $payt, $identifier){

        if(isset($payt->transmitted_data['param'])){
            $shopping_order = ShoppingOrder::find($payt->transmitted_data['param']);
            $shopping_payment = ShoppingPayment::where('reference', $payt->transmitted_data['reference'])->first();

            $shopping_order->txaction = 'open';
            $shopping_order->save();

            if($shopping_payment){
                if($payt->status === 'vor'){
                    $shopping_payment->txaction = 'open';
                    $shopping_order->txaction = 'open';


                }
                if($payt->status === 'fnc'){
                    $send_link = Payment::paymentStatusPaidAction($shopping_order, false);
                    $shopping_payment->txaction = 'open';
                    $shopping_order->txaction = 'open';


                }
                $shopping_payment->save();
            }

            //$payt->request = "approved";
            //$payt->save();
            $data = [
               'mode' => $payt->transmitted_data['mode'],
                'txaction' => $payt->txaction,
                'send_link' => false,
            ];
            Payment::paymentStatusSendMail($shopping_order, $shopping_payment, $data);
        }

    }

}