<?php

defined('BASEPATH') OR exit('No direct script access allowed');

class Myaccount extends Online_Template {

    private $customer = null;

    function __construct() {
        parent::__construct();
        if (!$this->isTheCustomerLoggedIn) {
            redirect(site_url());
        }
        $this->load->model('Myaccount_Model');
        $this->load->model('Cart_Model');
        $this->customer = $this->Myaccount_Model->get_single('customer', array('id' => $this->session->userdata('customerId')))->row_array();
        $this->cartTotal = $this->Cart_Model->total();
    }

    public function index() {
        $this->session->set_userdata('lastAccessUrl', base_url(uri_string()));
        $this->page_title = "Customer Dashboard";
        $this->current_section = "Customer Dashboard";
        $data['url'] = base_url(uri_string());
        $data['customer'] = $this->customer;
        $data['customerAddresses'] = $this->Myaccount_Model->get_list('customer_address')->result();
        $this->render('myaccount/index', $data);
    }

    public function profile() {
        $data['url'] = base_url(uri_string());
        $data['customer'] = $this->customer;
        $data['primaryAddress'] = $this->Myaccount_Model->get_single('customer_address', array('type' => 'primary', 'id' => $this->session->userdata('customerId')))->row_array();
        $data['cityList'] = $this->Myaccount_Model->get_list('lcity')->result();
        if ($this->input->post()) {
            $data = $this->preparePostedData();
            $dataCustomer = array(
                'name' => $data['name'],
            );
            $s1 = $this->Myaccount_Model->saveCustomer($dataCustomer, $this->customer['id']);
            $s2 = false;
            $dataAddress = array(
                'building' => $data['building'],
                'sector' => $data['sector'],
                'street' => $data['street'],
                'postcode' => postcodeFormat($data['postcode']),
                'city' => $data['city'],
                'type' => 'primary',
                'cid' => $this->customer['id'],
                'branch' => $this->customer['branch']
            );
            $doesCustomerAddressExist = $this->Myaccount_Model->get_single('customer_address', array('type' => 'primary', 'cid' => $this->customer['id']))->row();
            if (!empty($doesCustomerAddressExist)) {
                $s2 = $this->Myaccount_Model->saveCustomerAddress($dataAddress, $doesCustomerAddressExist->id);
            } else {
                $s2 = $this->Myaccount_Model->saveCustomerAddress($dataAddress);
            }
            $status = $s1 && $s2;
            $message = $status ? "You account information udpated successfully" : "update failed, please try again";
            echo json_encode(array('status' => $s1 && $s2, 'message' => $message));
        } else {
            $this->page_title = "My Profile";
            $this->current_section = "My Profile";
            $this->render('myaccount/profile', $data);
        }
    }

    public function password() {
        $data['url'] = base_url(uri_string());
        $data['customer'] = $this->customer;
        if ($this->input->post()) {
            $customerInfo = array(
                'password' => md5($this->input->post('password'))
            );
            $s1 = $this->Myaccount_Model->saveCustomer($customerInfo, $this->customer['id']);
            echo json_encode(array('status' => $s1, 'message' => $s1 ? 'Your password changed successfully' : 'Your password change failed'));
        } else {
            $this->page_title = "My Password";
            $this->current_section = "My Password";
            $this->render('myaccount/password', $data);
        }
    }

    public function address($id = null) {
        $data['url'] = base_url(uri_string());
        $data['customer'] = $this->customer;
        $data['address'] = $this->Myaccount_Model->get_list('customer_address', array('cid' => $this->customer['id']))->result();
        $data['cityList'] = $this->Myaccount_Model->get_list('lcity')->result();
        if ($id && (int) $id > 0) {
            $data['thisAddress'] = $this->Myaccount_Model->get_single('customer_address', array('id' => $id))->row_array();
        }
        if ($this->input->post()) {
            $status = false;
            $data = $this->preparePostedData();
            $data['postcode'] = postcodeFormat($data['postcode']);
            if (isset($data['id'])) {
                $status = $this->Myaccount_Model->saveCustomerAddress($data, $data['id']);
            } else {
                $data['cid'] = $this->customer['id'];
                $data['branch'] = $this->customer['branch'];
                $status = $this->Myaccount_Model->saveCustomerAddress($data);
            }
            echo json_encode(array('success' => $status, 'message' => $status ? 'Added/updated successfully' : 'Adding/update failed'));
        } else {
            $this->page_title = "My Address Book";
            $this->current_section = "My Address Book";
            $this->render('myaccount/address', $data);
        }
    }

    public function checkAddressType() {
        $column = $this->input->post('column');
        $value = $this->input->post('value');
        $update = $this->input->post('update');
        $result = $this->Myaccount_Model->checkAddressType($column, $value, $update);
        if ($result) {
            echo json_encode($value . " Already taken, please try with another label");
        } else {
            echo json_encode(true);
        }
    }

    public function checkout() {
        $this->page_title = "Checkout";
        $this->current_section = "Checkout";
        $data['customer'] = $this->customer;
        $data['branch'] = $this->Myaccount_Model->get_single('branch', array('id' => $this->customer['branch']), array('title', 'general_phone', 'address_street', 'address_city', 'address_postcode'))->row_array();
        $data['url'] = base_url(uri_string());
        $data['timeSlot'] = $this->getManagedTime();
        if ($this->session->userdata('onlineOrderType') === 'delivery') {
            $data['address'] = $this->Myaccount_Model->get_list('customer_address', array('cid' => $this->customer['id']))->result();
            $data['activeAddress'] = $this->Myaccount_Model->get_single('customer_address', array('cid' => $this->customer['id'], 'postcode' => $this->session->userdata('deliveryPostcode')))->row_array();
            if (empty($data['activeAddress'])) {
                $data['activeAddress'] = array('type' => 'addnew', 'building' => '', 'sector' => '', 'street' => '', 'postcode' => $this->session->userdata('deliveryPostcode'), 'city' => '',);
            }
        }
        $data['stripe'] = $this->Myaccount_Model->get_single('paymentstripe', array('branch' => $this->session->userdata('branch'), 'status' => '3'))->row_array();
        $this->render('myaccount/checkout', $data);
    }

    public function applypromocode() {
        $orderType = $this->session->userdata('onlineOrderType');
        $obj = $this->Myaccount_Model->get_single('discountpromo', array('branch' => $this->customer['branch'], 'status' => '3', 'promocode' => $this->input->post('promocode'), 'start_date<=' => date('Y-m-d'), 'end_date>=' => date('Y-m-d')))->row();
        $status = false;
        $message = null;
        if (!empty($obj)) {
            $nowTime = strtotime(date('h:i a'));
            $startTime = strtotime(date('h:i a', strtotime($obj->start_time)));
            $endTime = strtotime(date('h:i a', strtotime($obj->end_time)));
            $daysArray = array('Sun' => '1', 'Mon' => '2', 'Tue' => '3', 'Wed' => '4', 'Thu' => '5', 'Fri' => '6', 'Sat' => '7');
            if ($orderType === 'delivery') {
                $orderTypeNumber = 4;
            }
            if ($orderType === 'collection') {
                $orderTypeNumber = 5;
            }
            if ((in_array(6, unserialize($obj->onapp)) && in_array($orderTypeNumber, unserialize($obj->onapp))) && $nowTime >= $startTime && $nowTime <= $endTime && in_array($daysArray[date('D')], unserialize($obj->onday))) {
                $status = true;
            } else {
                $message = "It is not applicable for " . $orderType . "  order or in this time";
                $status = false;
                $obj = null;
            }
            if ($obj && !empty($obj) && $status) {
                if ($obj->used_as === '3') {
                    $isUsedObj = $this->Myaccount_Model->get_single('order', array('cid' => $this->customer['id'], 'promocode' => $obj->promocode))->row();
                    if (!empty($isUsedObj)) {
                        $message = "You have already used this promocode";
                        $status = false;
                        $obj = null;
                    }
                }
            }
        } else {
            $status = false;
            $message = "Wrong code or already dissolved";
        }
        if (!empty($obj)) {
            $setupData = array(
                'min_order' => $obj->min_order,
                'discount' => $obj->discount,
                'onfunc' => $obj->onfunc,
                'rel' => $obj->rel,
                'onitem' => unserialize($obj->onitem),
                'promocode' => $obj->promocode
            );
            if ($this->Cart_Model->subtotal() >= $obj->min_order) {
                $this->Cart_Model->setPromoDiscountPlan($setupData);
            } else {
                $status = false;
                $message = "Minimum " . to_currency($obj->min_order) . ' is required to process this promo code';
            }
        } else {
            $this->Cart_Model->emptyPromoDiscountPlan();
        }

        if ($this->Cart_Model->getPromoDiscountPlan()) {
            echo json_encode(array('status' => true, 'message' => 'Ok'));
        } else {
            echo json_encode(array('status' => $status, 'message' => $message));
        }
    }

    public function removepromocode() {
        $this->Cart_Model->emptyPromoDiscountPlan();
        echo json_encode(array('status' => $this->Cart_Model->getPromoDiscountPlan() ? false : true));
    }

    public function processingCheckout() {
        $data['type'] = $this->Cart_Model->getOrderType();
        $data['cid'] = $this->customer['id'];
        $data['owner'] = $this->customer['id'];
        $data['team'] = 1;
        $data['branch'] = $this->customer['branch'];
        $data['branch'] = $this->customer['branch'];
        $data['status'] = 1;
        $data['source'] = 'online';
        $data['orderInfo']['note'] = $this->input->post('note');
        if ($data['type'] == 'collection') {
            $data['orderInfo']['name'] = $this->input->post('name');
            $data['orderInfo']['phone'] = $this->input->post('phone');
            $data['orderInfo']['collectionTime'] = $this->input->post('collectionTime');
        }
        if ($data['type'] == 'delivery') {
            $data['orderInfo']['name'] = $this->input->post('name');
            $data['orderInfo']['phone'] = $this->input->post('phone');
            $data['orderInfo']['deliveryTime'] = $this->input->post('deliveryTime');
            $data['orderInfo']['building'] = $this->input->post('building');
            $data['orderInfo']['floor'] = '';
            $data['orderInfo']['apartment'] = '';
            $data['orderInfo']['sector'] = $this->input->post('sector');
            $data['orderInfo']['street'] = $this->input->post('street');
            $data['orderInfo']['postcode'] = $this->input->post('postcode');
            $data['orderInfo']['area'] = '';
            $data['orderInfo']['city'] = $this->input->post('city');
            $data['orderInfo']['region'] = '';
            $data['orderInfo']['country'] = '';
            $data['orderInfo']['deliveryCharge'] = $this->Cart_Model->getDeliveryCharge();
            $data['orderInfo']['minOrderAmount'] = $this->Cart_Model->getDeliveryMinOrder();
        }
        $data['orderInfo'] = serialize($data['orderInfo']);
        $data['cart'] = serialize($this->Cart_Model->getCart());
        $data['subTotal'] = $this->Cart_Model->subtotal();
        $data['tax'] = $this->Cart_Model->tax();
        $data['deliveryCharge'] = $this->Cart_Model->getDeliveryCharge();
        $data['promo'] = $this->Cart_Model->promoDisocunt();
        $data['discount'] = $this->Cart_Model->discount();
        $data['multiDiscount'] = $this->Cart_Model->multiDiscount();
        $data['grandTotal'] = $this->Cart_Model->total();
        $data['taxIsIncluded '] = $this->restaurantInfo['taxIsIncluded'];
        $data['taxIncludedPercent  '] = $this->restaurantInfo['default_tax'];
        $data['isPaid'] = 2;
        $data['orderId'] = date_timestamp_get(date_create());
        $data['closingData'] = date('Y-m-d');
        $redirectUrl = null;
        $status = false;
        if ($this->input->post('payment') === 'card') {
            $this->Cart_Model->setOrderDetail($data);
            $status = $this->Cart_Model->getOrderDetail() ? true : false;
            $redirectUrl = 'my-account/payment-online';
        } else {
            $data['payment'] = array(
                array(
                    'id' => 1,
                    'type' => 'Cash',
                    'amount' => $data['grandTotal'],
                    'code' => '',
                )
            );
            $data['payment'] = serialize($data['payment']);
            $id = $this->Myaccount_Model->saveOrder($data);
            $status = $id ? true : false;
            $redirectUrl = 'my-account/order-confirmation/' . $id;
        }
        echo json_encode(array('status' => $status, 'urlToRedirect' => $redirectUrl));
    }

    public function payment_online() {
        $stripe = $this->Myaccount_Model->get_single('paymentstripe', array('branch' => $this->session->userdata('branch'), 'status' => '3'))->row();
        if (!empty($stripe)) {
            $data['pk'] = $stripe->mode == 3 ? $stripe->pk_live : $stripe->pk_test;
        } else {
            $data['pk'] = '';
        }
        $data['grandTotal'] = $this->Cart_Model->total();
        $this->page_title = "Payment Online";
        $this->current_section = "Payment Online";
        $data['url'] = base_url(uri_string());
        $this->render('myaccount/payment_online', $data);
    }

    public function charge() {
        $data = $this->Cart_Model->getOrderDetail();
        if ($this->Cart_Model->getOrderDetail() && $data['grandTotal'] > 0) {
            $stripe = $this->Myaccount_Model->get_single('paymentstripe', array('branch' => $this->session->userdata('branch'), 'status' => '3'))->row();
            $stripeSecretKey = null;
            if (!empty($stripe)) {
                $stripeSecretKey = $stripe->mode == 3 ? $stripe->sk_live : $stripe->sk_test;
            }
            require APPPATH . '/libraries/stripe/init.php';
            \Stripe\Stripe::setApiKey($stripeSecretKey);
            $errorArray = array();
            $charge = array();
            try {
                $infoArray = array(
                    'amount' => to_currency_no_money(trim($data['grandTotal'])) * 100,
                    'currency' => 'GBP',
                    'description' => $data['orderId'] . '#' . '0' . '#' . '2' . '#' . $this->session->userdata('customerId'),
                    'source' => $this->input->post('stripeToken'),
                );
                $charge = \Stripe\Charge::create($infoArray);
            } catch (\Stripe\Error\Card $e) {
                array_push($errorArray, $e->getMessage());
            } catch (\Stripe\Error\RateLimit $e) {
                array_push($errorArray, $e->getMessage());
            } catch (\Stripe\Error\InvalidRequest $e) {
                array_push($errorArray, $e->getMessage());
            } catch (\Stripe\Error\Authentication $e) {
                array_push($errorArray, $e->getMessage());
            } catch (\Stripe\Error\ApiConnection $e) {
                array_push($errorArray, $e->getMessage());
            } catch (\Stripe\Error\Base $e) {
                array_push($errorArray, $e->getMessage());
            } catch (Exception $e) {
                array_push($errorArray, $e->getMessage());
            } finally {
                if (!empty($errorArray)) {
                    $this->session->set_flashdata('error', $this->lang->line('card_payment_rejected'));
                    redirect('my-account/checkout');
                } else {
                    if (!empty($charge)) {
                        if ($charge->id && $charge->description && $charge->paid && $charge->status === 'succeeded') {
                            $explodedArr = explode('#', $charge->description);
                            $data['onlinePaymentDetails'] = array(
                                'reference_id' => $charge->id,
                                'amount' => $charge->amount,
                                'paid' => $charge->paid,
                                'status' => $charge->status,
                                'orderId' => $explodedArr[0],
                            );
                            $data['onlinePaymentDetails'] = serialize($data['onlinePaymentDetails']);
                            $data['isPaid'] = 3;
                            $data['payment'] = array(
                                array(
                                    'id' => 7,
                                    'type' => 'Online',
                                    'amount' => to_currency_no_money($charge->amount / 100),
                                    'code' => '',
                                )
                            );
                            $data['payment'] = serialize($data['payment']);
                            $id = $this->Myaccount_Model->saveOrder($data);
                            redirect('my-account/order-confirmation/' . $id);
                        } else {
                            $this->session->set_flashdata('error', $this->lang->line('card_payment_rejected'));
                            redirect('my-account/checkout');
                        }
                    }
                }
            }
        }
    }

    public function order_confirmation($id) {
        $data['order'] = $this->Myaccount_Model->get_single('order', array('cid' => $this->customer['id'], 'sid' => $id))->row_array();
        if (!empty($data['order'])) {
            $this->Cart_Model->clearCart();
            $this->page_title = "Order Confirmation";
            $this->current_section = "Order Confirmation";
            $data['url'] = base_url(uri_string());
            $this->render('myaccount/order_confirmation', $data);
        } else {
            redirect(site_url('my-account/orders'));
        }
    }

    public function confirmed_status() {
        $orderid = $this->input->post('id');
        if ($this->Myaccount_Model->exists('order', 'sid', $orderid)) {
            $order = $this->Myaccount_Model->get_single('order', array('sid' => $orderid))->row();
            $orderInfo = unserialize($order->orderInfo);
            $receivedTime = null;
            if ($order->type == 'collection') {
                $receivedTime = $orderInfo['collectionTime'];
            } else {
                $receivedTime = $orderInfo['deliveryTime'];
            }
            $responseText = null;
            if ($order->status_online == 3) {
                echo '<div class="status" style="padding:5px; font-weight:bold; color: green; text-transform: uppercase; font-size:17px; text-align:center;">Your order has been accepted </div>';
                $responseText = '<div class="status" style="color:#000; padding-bottom:5px;  font-size:16px;">Thank you for being patient,your order has been accepted for <br/><strong style="font-size:20px;text-transform: uppercase">' . $receivedTime . '</strong></div><style>.loading{display:none;}</style>';
            }
            if ($order->status_online == 4) {
                $responseText = '<div class="status" style="color:#ff0000; font-size:17px;">Your order has been rejected</div>';
                if (trim($order->rejectMsg)) {
                    $responseText .= '<div style="text-align:center; font-size:14px; color: #000000;">Message from restaurant: <br/><span style="font-size:14px; font-style:italic;">' . $order->rejectMsg . '</span></div><style>.loading{display:none;}</style>';
                }
            }
            if ($order->status_online == 2) {
                $responseText = '<div class="status" style="font-size:17px;">Your order is under acknowledgement</div>';
            }
            echo $responseText;
        } else {
            $responseText = '<div class="status" style="color:#ff0000; font-size:17px;">Your order has been rejected</div>';
            echo $responseText;
        }
    }

    public function orders() {
        $data['url'] = base_url(uri_string());
        $data['customer'] = $this->customer;
        $data['orders'] = $this->Myaccount_Model->get_list('order', array('cid' => $this->customer['id'], 'source' => 'online'), null, 10, 0, 'sid', 'DESC')->result();
        $this->page_title = "My Orders";
        $this->current_section = "My Orders";
        $this->render('myaccount/orders', $data);
    }

    public function orderdetail($id = null) {
        $data['order'] = $this->Myaccount_Model->get_single('order', array('cid' => $this->customer['id'], 'sid' => $id))->row_array();
        if (empty($data['order'])) {
            redirect(site_url('my-account/orders'));
        }
        $data['url'] = base_url(uri_string());
        $data['customer'] = $this->customer;
        $this->page_title = "Order Detail";
        $this->current_section = "Order Detail";
        $this->render('myaccount/orderdetail', $data);
    }

    public function signout() {
        if ($this->Myaccount_Model->customerLogginOut()) {
            redirect(site_url());
        }
    }

    private function getManagedTime() {
        $timeSlot = array();
        $orderType = $this->session->userdata('onlineOrderType');
        $waitingTime = 0;
        if ($orderType === 'collection') {
            $waitingTime = $this->restaurantInfo['default_time_collection'];
        } else {
            $waitingTime = $this->session->userdata('deliveryWaitingTime') ? $this->session->userdata('deliveryWaitingTime') : $this->restaurantInfo['default_time_delivery '];
        }
        $serviceTime = serviceTime();
        $todayServiceTime = array();
        if (!empty($serviceTime)) {
            foreach ($serviceTime as $st) {
                $manageSt = array(
                    'start' => $st[date('D')]->start,
                    'end' => $st[date('D')]->end,
                );
                array_push($todayServiceTime, $manageSt);
            }
        }
        if (!empty($todayServiceTime)) {
            $choosenStart = $todayServiceTime[0]['start'];
            $choosenEnd = $todayServiceTime[0]['end'];
            $choosenStartTimestamp = strtotime(date('h:i a', strtotime($choosenStart)));
            $choosenEndTimestamp = strtotime(date('h:i a', strtotime($choosenEnd)));
            if (count($todayServiceTime) > 1) {
                foreach ($todayServiceTime as $time) {
                    $thisStartTimestamp = strtotime(date('h:i a', strtotime($time['start'])));
                    $thisEndTimestamp = strtotime(date('h:i a', strtotime($time['end'])));
                    if ($thisStartTimestamp < $choosenStartTimestamp) {
                        $choosenStart = $time['start'];
                    }
                    if ($thisEndTimestamp > $choosenEndTimestamp) {
                        $choosenEnd = $time['end'];
                    }
                }
            }
            $openedObj = new DateTime($choosenStart);
            $openingTime = $openedObj->format('h:i a');
            $closed = $choosenEnd;
            $closedObj = new DateTime($closed);
            $interval = $openedObj->diff($closedObj);
            $totalMins = 0;
            if ($interval->h >= 1) {
                $totalMins += $interval->h * 60;
            }
            if ($interval->i >= 1) {
                $totalMins += $interval->i;
            }
            $timeSlotIndex = ceil(($totalMins) / 10);
            $nowOffsetTime = date('h:i a');
            $nowOffsetTimeObj = new DateTime($nowOffsetTime);
            $nowOffsetTimeObj->add(new DateInterval('PT' . $waitingTime . 'M'));
            $nowOffset = $nowOffsetTimeObj->format('h:i a');
            for ($i = 0; $i < $timeSlotIndex; $i++) {
                $nowSlotDate = new DateTime($openingTime);
                $nowSlotDate->add(new DateInterval('PT10M'));
                $nowSlotTime = $nowSlotDate->format('h:i a');
                if (strtotime(date('h:i a', strtotime($nowSlotTime))) > strtotime(date('h:i a', strtotime($nowOffset)))) {
                    $timeSlot[] = $nowSlotTime;
                }
                $openingTime = $nowSlotTime;
            }
        }
        return $timeSlot;
    }

}
