<?php
/******************************************************************************
 *   ______                                                                   *
 *  /       \                                                                 *
 * /$$$$$$  | ________  __    __   ______    ______                           *
 * $$ |__$$ |/        |/  |  /  | /      \  /      \                          *
 * $$    $$ |$$$$$$$$/ $$ |  $$ |/$$$$$$  |/$$$$$$  |                         *
 * $$$$$$$$ |  /  $$/  $$ |  $$ |$$ |  $$/ $$    $$ |                         *
 * $$ |  $$ | /$$$$/__ $$ \__$$ |$$ |      $$$$$$$$/                          *
 * $$ |  $$ |/$$      |$$    $$/ $$ |      $$       |                         *
 * $$/   $$/ $$$$$$$$/  $$$$$$/  $$/        $$$$$$$/                          *
 *                                                                            *
 * @PROJECT    : 3D Preview Extension [Magetop.com]                           *
 * @AUTHOR     : Azure - Developer                                            *
 * @COPYRIGHT  : © 2019  Magetop.com                                          *
 * @LINK       : https://Magetop.com                                          *
 * @CREATED    :  10/01/2022                                                  *
 ******************************************************************************/

namespace Magetop\Advancepreview\Controller\Adminhtml\Order;

use Magento\Backend\App\Action;


class UpdateItemStatus extends Action
{
    protected $jsonFactory;
    /**
     * @var \Magetop\Advancepreview\Model\PreviewOrderItemsFactory
     */
    protected $previewOrderItemsFactory;
    /**
     * @var \Magetop\Advancepreview\Model\ResourceModel\PreviewOrderItemsFactory
     */
    protected $resPreviewOrderItemsFactory;
    protected $colPreviewOrderItemsFactory;
    protected $emailHelper;
    protected $_invoiceService;
    protected $_transaction;
    protected $orderFactory;
    protected $resOrderFactory;
    protected $_invoiceSender;
    protected $priceHelper;
    function __construct(
        Action\Context $context,
        \Magento\Framework\Controller\Result\JsonFactory $jsonFactory,
        \Magento\Framework\Pricing\Helper\Data $priceHelper,
        \Magento\Sales\Model\Service\InvoiceService $invoiceService,
        \Magento\Framework\DB\Transaction $transaction,
        \Magento\Sales\Model\Order\Email\Sender\InvoiceSender $invoiceSender,
        \Magento\Sales\Model\OrderFactory $orderFactory,
        \Magento\Sales\Model\ResourceModel\OrderFactory $resOrderFactory,
        \Magetop\Advancepreview\Model\PreviewOrderItemsFactory $previewOrderItemsFactory,
        \Magetop\Advancepreview\Model\ResourceModel\PreviewOrderItemsFactory $resPreviewOrderItemsFactory,
        \Magetop\Advancepreview\Model\ResourceModel\PreviewOrderItems\CollectionFactory $colPreviewOrderItemsFactory,
        \Magetop\Advancepreview\Helper\Email $emailHelper
    )
    {
        parent::__construct($context);
        $this->jsonFactory = $jsonFactory;
        $this->previewOrderItemsFactory = $previewOrderItemsFactory;
        $this->resPreviewOrderItemsFactory = $resPreviewOrderItemsFactory;
        $this->colPreviewOrderItemsFactory = $colPreviewOrderItemsFactory;
        $this->emailHelper = $emailHelper;
        $this->_invoiceService = $invoiceService;
        $this->_transaction = $transaction;
        $this->orderFactory = $orderFactory;
        $this->resOrderFactory = $resOrderFactory;
        $this->_invoiceSender = $invoiceSender;
        $this->priceHelper = $priceHelper;
    }
    public function execute()
    {
        $response = [
            'status'=>'error',
            'message'=>__('Can not update order item status, please check again'),
            'item_status'=>''

        ];
        /** @var \Magetop\Advancepreview\Helper\Data $previewHelper*/
        $previewHelper = $this->_objectManager->get('\Magetop\Advancepreview\Helper\Data');
        $myfistEmail = $previewHelper->getOpdSetting('trans_email/ident_general/email');
        $status = $this->getRequest()->getParam('status','');
        $txtOrder = $this->getRequest()->getParam('txt_order','');
        $tracking_info = $this->getRequest()->getParam('tracking_info','');
        $itemId = (int)$this->getRequest()->getParam('item_id',0);
        $productName = $this->getRequest()->getParam('product_name','');
        $customerName = $this->getRequest()->getParam('customer_name','');
        $customerId = $this->getRequest()->getParam('customer_id',0);
        $customerEmail = $this->getRequest()->getParam('customer_email','');
        $orderId = $this->getRequest()->getParam('order_id',0);
        $status = trim($status);
        $order = $this->getOrderByIncrementId($txtOrder);
        $storeId = $order->getStoreId();
        if($itemId <= 0 || $status == '' || !$order) {
            $response['message'] = __('Item not found or status is not available');
        }
        else {
            $previewItem = $this->getPreviewItemByItemId($itemId);
            if($previewItem->getId()) {
                $isTracking = false;
                $dataUpdate = [
                    'status'=>$status,
                     'custom_item_id'=>$previewItem->getId(),
                    'updated_at'=>date('Y-m-d H:i:s')
                ];
                if($status == 'shipped' && $tracking_info != '') {
                    $isTracking = true;
                    $dataUpdate['tracking_info'] = $tracking_info;
                }
                $statusLabels = [
                    'new'=>'New',
                    'process'=>'In progress',
                    'shipping'=>'Ready for shipping/Production done',
                    'shipped'=>'Shipped'
                ];
                $statusCheckSendMail = '';
                $emailStatusId = 'eak_admin_update_order_item_status';
                if($status == 'process') {
                    $statusCheckSendMail = 'status_in_progress';
                    $emailStatusId = 'eak_admin_update_order_item_status_process';
                }
                else if($status == 'shipping') {
                    $statusCheckSendMail = 'status_shipping';
                    $emailStatusId = 'eak_admin_update_order_item_status_shipping';
                }
                else if($status == 'shipped') {
                    $statusCheckSendMail = 'status_shipped';
                    $emailStatusId = 'eak_admin_update_order_item_status_shipped';
                }
                else if($status == 'delivered') {
                    $statusCheckSendMail = 'status_delivered';
                    $emailStatusId = 'eak_admin_update_order_item_status_delivered';
                }
                $txtStatus = isset($statusLabels[$status]) ? $statusLabels[$status] : ucfirst($status);
                $updateId = $this->savePreviewOrderItem($dataUpdate);
                if($updateId > 0) {
                    $response['status'] = 'success';
                    $response['message'] =  __('You have updated order status successfully');
                    $response['item_status'] = $txtStatus;
                   /* if($status == 'shipping') {
                        $emailShippingId = 'eak_customer_order_item_ready_sale';
                        //send email
                        $templatavals = [
                            'customer_name'=>$customerName,
                            'product_name'=>$productName,
                            'item_status'=>'Sale',
                        ];
                        $send = $this->sendEmailToCustomer($customerEmail,$emailShippingId,$templatavals);
                        $response['send'] = $send['message'];
                    }
                    else if($status == 'shipped') {
                        $emailShippedId = 'eak_customer_order_item_ready_shipped';
                        //send email
                        $templatavals = [
                            'customer_name'=>$customerName,
                            'product_name'=>$productName,
                            'item_status'=>'Shipped',
                        ];
                        $send = $this->sendEmailToCustomer($customerEmail,$emailShippedId,$templatavals);
                        $response['send'] = $send['message'];
                    }*/
                    $emailId = 'eak_admin_update_order_item_status';
                    $itemDesignPrice = $this->getDesignItemPrice($order,$itemId);
                    $itemDesignPrice = $this->priceHelper->currency($itemDesignPrice, true, false);
                    $storeManager = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface');
                    $loginUrl = $storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_WEB).'customer/account/login';
                    $customerPrefix = $order->getCustomerPrefix();
                    $newCustomerName = str_replace($customerPrefix, '', $order->getCustomerName());
                    $customerPrefix = $this->getTranslateCustomerPrefix($customerPrefix, $storeId);
                    $newCustomerName = $customerPrefix .' '. $newCustomerName;
                    $templatavals = [
                        'txt_order'=>$order->getIncrementId(),
                        'customer_name'=>$newCustomerName,
                        'product_name'=>$productName,
                        'item_status'=>__($txtStatus),
                        'order_create_at'=>date('m/d/Y', strtotime($order->getCreatedAt())),
                        'item_price'=>$itemDesignPrice,
                        'myfit_mail'=>$myfistEmail,
                        'link_login'=>$loginUrl
                    ];
                    if($this->emailHelper->checkIsSendEmail($statusCheckSendMail,$customerId)) {
                        if($isTracking) {
                            $emailId = 'eak_admin_update_order_item_send_tracking';
                            $templatavalsTracking = [
                                'txt_order'=>$order->getIncrementId(),
                                'customer_name'=>$newCustomerName,
                                'product_name'=>$productName,
                                'tracking_info'=>$tracking_info,
                                'order_create_at'=>date('m/d/Y', strtotime($order->getCreatedAt())),
                                'item_price'=>$itemDesignPrice,
                                'myfit_mail'=>$myfistEmail,
                                'link_login'=>$loginUrl

                            ];
                            $send = $this->sendEmailToCustomer($customerEmail,'eak_admin_update_order_item_send_tracking',$templatavalsTracking, $storeId);
                        }
                        $send = $this->sendEmailToCustomer($customerEmail,'eak_admin_update_order_item_status',$templatavals, $storeId);
                        $response['send'] = $send['message'];

                    }
                    else {
                        $response['send'] = 'was disabled';
                    }
                    if($status == 'delivered') {

                        $qty = $this->getRequest()->getParam('qty',0);
                        $totalPrice = $this->getRequest()->getParam('total',0);
                        $itemId = ''.$itemId;
                        /*if($this->emailHelper->checkIsSendEmail($statusCheckSendMail,$customerId)) {
                            $send = $this->sendEmailToCustomer($customerEmail,$emailId,$templatavals);
                        }*/
                        $response['invoice'] = $this->generateInvoice($order,$itemId,$qty,$totalPrice,$updateId);
                       /* if($isCreateInvoice) {
                            $response['invoice'] = 'INvoice ok';
                        }
                        else {
                            $response['invoice'] = $isCreateInvoice;
                        }*/
                    }


                }
            }
            else {
                $response['message'] = __('Item not found or status is not available');
            }
        }
        if($response['status'] == 'success') {
            $this->messageManager->addSuccessMessage($response['message']);
        }
        else {
            $this->messageManager->addErrorMessage($response['message']);
        }
        return $this->jsonFactory->create()->setData($response);

    }
    public function getPreviewItemByItemId($itemId = 0) {
        $collection = $this->colPreviewOrderItemsFactory->create()
            ->addFieldToSelect(array('status'))
            ->addFieldToFilter('item_id',$itemId);
        $previewItem = $collection && $collection->getSize() > 0 ? $collection->getFirstItem() : null;
        return $previewItem;

    }

    /**
     * @param array $previewData
     * @return int
     */
    protected function savePreviewOrderItem($previewData = []) {
        $model = $this->previewOrderItemsFactory->create();
        $model->setData($previewData);
        $id = 0;
        try {
            $this->resPreviewOrderItemsFactory->create()->save($model);
            $id =  $model->getId();
        }
        catch (\Exception $exception) {

        }
        return $id;

    }
    protected function generateInvoice($order, $itemId,$qty,$total,$previewId) {
//        $orderId = 1; //order id for which want to create invoice
//        $order = $this->getOrder($orderId);
        $isSend = false;
        $dmId = 0;
        try {
            if($order->canInvoice()) {
                $itemsArray = [$itemId=>$qty]; //here 80 is order item id and 2 is it's quantity to be invoice
                $shippingAmount = '0';
                $subTotal = $total;
                $baseSubtotal = $total;
                $grandTotal = $total;
                $baseGrandTotal = $total;
                $invoice = $this->_invoiceService->prepareInvoice($order, $itemsArray);
                $invoice->setShippingAmount($shippingAmount);
                $invoice->setSubtotal($subTotal);
                $invoice->setBaseSubtotal($baseSubtotal);
                $invoice->setGrandTotal($grandTotal);
                $invoice->setBaseGrandTotal($baseGrandTotal);
                $invoice->register();
                $transactionSave = $this->_transaction->addObject(
                    $invoice
                )->addObject(
                    $invoice->getOrder()
                );
                $transactionSave->save();

                //send notification code
                $order->addStatusHistoryComment(
                    __('Notified customer about invoice #%1.', $invoice->getId())
                )
                    ->setIsCustomerNotified(true)
                    ->save();
                if($invoice && $invoice->getId()) {
                    // update order
                    $this->updateMainOrderStatus($order->getId());
                    $dmId = $invoice->getId();
                    $isSend = true;
                    $updateCustomOrderItem = [
                        'custom_item_id'=>$previewId,
                        'invoice_id'=>$invoice->getId(),
                    ];
                    $this->savePreviewOrderItem($updateCustomOrderItem);
                    // send email
                    if($this->emailHelper->checkIsSendEmail('status_delivered',$order->getCustomerId())) {
                        $this->_invoiceSender->send($invoice);
                       /* $emailId = 'eak_admin_update_order_item_invoice';

                        $templatavals = [
                            'txt_order'=>$order->getIncrementId(),
                            'customer_name'=>$order->getCustomerName(),
                            'txt_invoice'=>$invoice->getIncrementId(),
                            'link'=>$this->_url->getUrl('advance_preview/index/index/').'invoice_id/'.$invoice->getId().'/item_id/'.$itemId.'/type/3'
                        ];
                        $send = $this->sendEmailToCustomer($order->getCustomerEmail(),$emailId,$templatavals);*/
                    }

                }
            }
            else {
                $dmId = 'order can not invoice';
            }
        }
        catch (\Exception $exception) {
            $dmId = $exception->getMessage();
        }
        return $dmId;
    }
    protected function updateMainOrderStatus($orderId) {
        $order = $this->orderFactory->create();
        try {
            $this->resOrderFactory->create()->load($order, $orderId);
            $orderState = \Magento\Sales\Model\Order::STATE_PROCESSING;
            $order->setState($orderState)->setStatus($orderState);
            $this->resOrderFactory->create()->save($order);
            return true;
        }
        catch (\Exception $exception) {

        }
        return  false;
    }
    protected function sendEmailToCustomer($toEmail, $emailId, $templateVars = [], $storeId = null) {
        $sendResponse = array(
            'status'=>'error',
            'message'=>'Can not send email'
        );
        $storeName = 'myfitmix';
        $templateVars['custom_store_name'] = $storeName;
//        $emailId = 'eak_customer_order_item_ready_sale';
        $formEmail = 'info@myfitmix.de';
        if($toEmail == '') {
            $sendResponse['message'] = 'Email not found';
        }
        else {
            $sendResponse = $this->emailHelper->sendAdvanceEmail($emailId,$templateVars,$storeName,$formEmail,$toEmail, $storeId);
        }
        return $sendResponse;
    }
    protected function getOrder($orderId) {
        $model =  $this->orderFactory->create();
        try {
            $this->resOrderFactory->create()->load($model,$orderId);
        }
        catch (\Exception $exception) {

        }
        return $model;
    }
    protected function getDesignItemPrice(
        \Magento\Sales\Model\Order $order,
        $itemId
    ) {
        $price = 0;
        if($order && $order->getAllItems()) {
            foreach ($order->getAllVisibleItems() as $item) {
                if($item->getId() == $itemId) {
                    $infoRequest = $item->getProductOptionByCode('info_buyRequest');
                    $price = $infoRequest['txt_project_final_price'];
                }

            }
        }
        return $price;
    }
    protected function getOrderByIncrementId($incrementId) {
        $model =  $this->orderFactory->create();
        try {
            $this->resOrderFactory->create()->load($model,$incrementId,'increment_id');
        }
        catch (\Exception $exception) {

        }
        return $model;
    }

    protected function getTranslateCustomerPrefix($text, $storeId) {
        if($storeId == 2) {
            return $text;
        }
        if($text == 'Mr') {
            $text = 'Sehr geehrter Her';
        }
        else if($text == 'Mrs') {
            $text = 'Sehr geehrte Frau';
        }
        return  $text;
    }

}
