<?php

namespace common\components;

use common\models\Banner;
use common\models\BidList;
use common\models\Cart;
use common\models\Tags;
use common\models\CartDetails;
use common\models\Categories;
use common\models\InsertedTags;
use common\models\Images;
use common\models\Notification;
use common\models\Payment;
use common\models\Plan;
use common\models\Product;
use common\models\ProductOtherData;
use common\models\ProductType;
use common\models\RatingProduct;
use common\models\ReportProduct;
use common\models\Users;
use common\models\Wishlist;
use Yii;
use yii\base\Component;
use yii\data\ActiveDataProvider;
use yii\helpers\ArrayHelper;
use yii\helpers\Url;
use yii\web\UploadedFile;

class ProductComponent extends Component
{
    public function add_update_product($product, $login_id, $tags_title = '', $update_tag = false, $api = false)
    {
        try {
            $check_plan = Yii::$app->general->check_plan_expired($login_id, true);
            if ($product->isNewRecord && empty($check_plan['status'])) {
                return array('status' => false, 'message' => 'You have reached the limit of your current plan, Please click here');
            }

            $product->status        = Product::STATUS_APPROVE;
            $product->manage_stock  = Product::STOCK_YES;
            $product->user_id       = $login_id;
            $is_saler               = Yii::$app->common_user->check_user_is_saler($login_id);

            if ($product->is_auction == Product::AUCTION_YES) {
                $product->min_start_bid_required    = true;
                $product->price     = $product->min_start_bid;
                $product->qty       = Product::STOCK;
            }

            $product->is_delivery = isset($_POST['Product']['is_delivery']) ? $_POST['Product']['is_delivery'] : '';
            if ($product->is_delivery == Product::FREE) {
                $product->delivery_charge = 0;
            }

            $type   = ($product->isNewRecord) ? 'added' : 'updated';
            if ($product->validate() && $product->save()) {

                if ($api || !empty(UploadedFile::getInstances($product, 'image'))) {
                    $upload_image   = Yii::$app->upload->imageUpload($product->id, $product, 'image', Images::TYPE_PRODUCT, Images::FOLDER_PRODUCT, false, true, $api);
                    if ($upload_image['status'] == false) {
                        return array('status' => false, 'message' => $upload_image['message']);
                    }
                    $main_image_id = Images::find()->where(['pre_define_id' => $product->id, 'image_type' => Images::TYPE_PRODUCT, 'main_image' => Images::IMAGE_MAIN])->one();
                    $product->main_image_id = !empty($main_image_id) ? $main_image_id->id : null;
                    if (!empty($main_image_id) && !$product->save()) {
                        return array('status' => false, 'message' => Yii::$app->general->error($product->errors));
                    }
                }

                $this->saveOtherinfo($product->id, $product->sub_category_id);

                // Will Check User is Saler if yes then Default items will be store.
                if ($is_saler != Yii::$app->common_user->check_user_is_saler($login_id)) {
                    Yii::$app->common_user->become_saler($login_id);
                }

                if ($update_tag == true) {
                    InsertedTags::deleteAll(['related_id' => $product->id, 'type' => InsertedTags::TYPE_SEO_TAGS]);
                }

                $tags_find          = Tags::find()->where(['title' => $tags_title])->all();
                if (!empty($tags_title) && !empty($tags_find)) {
                    foreach ($tags_find as $value) {
                        $inserted_tags                      = new InsertedTags();
                        $inserted_tags->related_id          = $product->id;
                        $inserted_tags->tag_id              = $value->id;
                        $inserted_tags->type                = InsertedTags::TYPE_SEO_TAGS;
                        if (!$inserted_tags->validate() || !$inserted_tags->save()) {
                            return array('status' => false, 'message' => Yii::$app->general->error($inserted_tags->errors));
                        }
                    }
                }

                $data = [
                    "product_id" => $product->id,
                    "title" => $product->title,
                ];

                if ($product->is_auction == Product::AUCTION_YES) {
                    return array('status' => true, 'data' => $data, 'message' => 'Auction Product has been ' . $type . ' successfully.');
                } else {
                    return array('status' => true, 'data' => $data, 'message' => 'Product has been ' . $type . ' successfully.');
                }
            } else {
                return array('status' => false, 'message' => Yii::$app->general->error($product->errors));
            }
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage());
        }
    }

    public function add_remove_wishlist($product_id, $user_id)
    {
        try {
            $product    = Wishlist::find()->where(['product_id' => $product_id, 'user_id' => $user_id])->one();
            if (empty($product)) {
                $wish_list_product              = new Wishlist();
                $wish_list_product->user_id     = $user_id;
                $wish_list_product->product_id  = $product_id;
                if ($wish_list_product->validate() && $wish_list_product->save()) {
                    return array('status' => true, 'data' => 'add', 'message' => 'Product successfully added to wishlist');
                } else {
                    return array('status' => false, 'message' => Yii::$app->general->error($wish_list_product->errors));
                }
            } else {
                if ($product->delete()) {
                    return array('status' => true, 'data' => 'remove', 'message' => 'Product successfully removed from wishlist');
                } else {
                    return array('status' => false, 'message' => Yii::$app->general->error($product->errors));
                }
            }
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage());
        }
    }

    public function wishlist_products($page = 0, $search = '', $login_id)
    {
        try {
            $data = $wishlist_data = $models = array();
            $wishlist_data      = Wishlist::find()->joinWith(['product', 'user'])->where(['wishlist.user_id' => $login_id])->asArray()->orderBy(['wishlist.id' => SORT_DESC]);

            if ($search != '') {
                $wishlist_data->andFilterWhere([
                    'or',
                    ['like', 'product.title', $search],
                    ['like', 'product.description', $search],
                    ['like', 'product.short_description', $search],
                    ['like', 'product.price', $search],
                    // ['like', 'product.sell_price', $search],
                    ['like', 'product.qty', $search],
                ]);
            }

            $pageSize = Product::WISHLIST_PAGE_SIZE;
            $provider = new ActiveDataProvider([
                'query' => $wishlist_data,
                'pagination' => [
                    'page' => $page,
                    'pageParam' => 'page',
                    'defaultPageSize' => $pageSize,
                ]
            ]);

            $models = $provider->getModels();

            if (!empty($models)) {
                foreach ($models as $key => $value) {
                    $get_sub_cat                    = ProductOtherData::find()->where(['product_id' => $value['product_id']])->asArray()->all();
                    $main_img                       = Images::find()->where(['id'  => $value['product']['main_image_id'], 'image_type' => Images::TYPE_PRODUCT, 'main_image' => Images::IMAGE_MAIN])->one();
                    $get_img                        = Yii::$app->general->get_images_path((!empty($main_img)) ? 'MEDIUM_' . $main_img->image_name : '', Images::FOLDER_PRODUCT, Images::PLACEHOLDER_FOR_PRODUCT);

                    $category = $cat = [];
                    if (!empty($get_sub_cat)) {
                        foreach ($get_sub_cat as $sub_cat) {
                            $category    = $sub_cat['sub_category_id'];
                            $cat[$category] = $category;
                        }
                    }

                    $data[$key]['product_id']           = $value['product_id'];
                    $data[$key]['title']                = $value['product']['title'];
                    $data[$key]['description']          = $value['product']['description'];
                    $data[$key]['short_description']    = $value['product']['short_description'];
                    $data[$key]['parent_id']            = $value['product']['parent_id'];
                    $data[$key]['sub_category_id']      = array_values($cat);
                    $data[$key]['price']                = (!empty($value['product']['price'])) ? Yii::$app->general->convert_currency($value['product']['price']) : '';
                    // $data[$key]['sell_price']           = (!empty($value['product']['sell_price'])) ? Yii::$app->general->convert_currency($value['product']['sell_price']) : '';
                    $data[$key]['price_']               = (int)$value['product']['price'];
                    // $data[$key]['sell_price_']          = (int)$value['product']['sell_price'];
                    $data[$key]['qty']                  = $value['product']['qty'];
                    $data[$key]['is_auction']           = $value['product']['is_auction'];
                    $data[$key]['auction_period']       = $value['product']['auction_period'];
                    $data[$key]['main_image']['id']     = (!empty($main_img)) ? $main_img->id : 0;
                    $data[$key]['main_image']['path']   = $get_img;
                }
            }

            $pagination     = Yii::$app->general->pagination($provider, $pageSize, $page);

            if ($pagination['status'] == false) {
                return ['status' => false, 'message' => $pagination['message'], 'data' => Product::PAGINATION_ARRAY];
            }

            return ['status' => true, 'message' => '', 'data' => ['items' => $data, 'pagination' => $pagination['pagination']]];
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage(), 'data' => Product::PAGINATION_ARRAY);
        }
    }

    public function add_to_cart($item_id, $item_qty, $user_id, $want_data = true)
    {
        try {
            $data       = [];
            $check_qty  = Product::findOne(['id' => $item_id, 'active' => Product::S_ACTIVE]);
            if (empty($check_qty)) {
                return array('status' => false, 'message' => "Product Not Found");
            }
            if ($check_qty->qty < $item_qty) {
                return array('status' => false, 'product_qty' => $check_qty->qty, 'message' => 'Product is Out of stock!');
            }

            $exist_cart = Cart::find()->where(['user_id' => $user_id])->one();

            if ((empty($exist_cart))) {
                $add_cart           = new Cart();
                $add_cart->user_id  = $user_id;
                if (!$add_cart->validate() || !$add_cart->save()) {
                    return array('status' => false, 'message' => Yii::$app->general->error($add_cart->errors));
                }
            }
            $cart_id    = empty($exist_cart) ? $add_cart->id : $exist_cart->id;

            $cart_detail                = CartDetails::find()->where(['cart_id' => $cart_id, 'item_id' => $item_id])->one();
            $add_cart_details           = (!empty($cart_detail)) ? $cart_detail : new CartDetails();
            $add_cart_details->cart_id  = $cart_id;
            $add_cart_details->item_id  = $item_id;
            $add_cart_details->item_qty = $item_qty;
            $add_cart_details->type     = ($check_qty->is_auction == Product::AUCTION_YES) ? CartDetails::TYPE_AUCTION : CartDetails::TYPE_PRODUCT;

            if ($add_cart_details->validate() && $add_cart_details->save()) {
                if ($want_data) {
                $show_product   = Product::findOne($add_cart_details->item_id);
                $get_main_image = Images::find()->where(['pre_define_id' => $add_cart_details->item_id, 'image_type' => Images::TYPE_PRODUCT, 'main_image' => Images::IMAGE_MAIN])->one();
                $main_image     = !empty($get_main_image) ? 'MEDIUM_' . $get_main_image->image_name : '';
                $product_image  = Yii::$app->general->get_images_path($main_image, Images::FOLDER_PRODUCT, Images::PLACEHOLDER_FOR_PRODUCT);
                $total_price    = $show_product->price * $item_qty;
                $count          = CartDetails::find()->joinWith('cart')->where(['user_id' => $user_id])->count();

                $user_data       = Yii::$app->common_user->get_user_data($user_id);
                if ($user_data['status'] == false) {
                    return $user_data;
                }

                $data   = [
                    'user_id'           => $user_id,
                    'cart_id'           => $add_cart_details->cart_id,
                    'item_id'           => (int)$add_cart_details->item_id,
                    'item_name'         => $show_product->title,
                    'short_description' => $show_product->short_description,
                    'item_image'        => $product_image,
                    'item_qty'          => (int)$add_cart_details->item_qty,
                    'total_price'       => Yii::$app->general->convert_currency($total_price),
                    'total_price_'      => $total_price,
                    'count'             => $count,
                    'user_data'         => $user_data['data'],
                ];
                }

                return array('status' => true, 'data' => $data, 'message' => 'Product has been successfully added to cart.');
            } else {
                return array('status' => false, 'message' => Yii::$app->general->error($add_cart_details->errors));
            }
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage());
        }
    }

    public function remove_to_cart($item_id, $user_id)
    {
        try {
            $check_cart = Cart::find()->joinWith(['cartDetails'])->where(['`cart`.`user_id`' => $user_id, '`cart_details`.`item_id`' => $item_id])->one();

            if (empty($check_cart)) {
                return array('status' => false, 'message' => 'No Data Found!');
            }

            $remove_cart = CartDetails::find()->where(['item_id' => $item_id, 'cart_id' => $check_cart->id])->one();
            if ($remove_cart->delete()) {
                return array('status' => true, 'message' => 'Product has been successfully removed from cart.');
            } else {
                return array('status' => false, 'message' => Yii::$app->general->error($remove_cart->errors));
            }
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage());
        }
    }

    public function cart_list($login_id, $page = 0, $search = '')
    {
        try {
            $data = $listData = $models = $product_total = array();
            $listData       = CartDetails::find()->joinWith(['cart', 'item'])->where(['`cart`.`user_id`' => $login_id])->asArray()->orderBy(['cart_details.id' => SORT_DESC]);

            if ($search != '') {
                $listData->andFilterWhere([
                    'or',
                    ['like', '`product`.`title`', $search],
                    ['like', '`product`.`short_description`', $search],
                    ['like', '`cart_details`.`item_qty`', $search],
                ]);
            }

            $pageSize = Product::CART_PAGE_SIZE;
            $provider = new ActiveDataProvider([
                'query' => $listData,
                'pagination' => [
                    'page' => $page,
                    'pageParam' => 'page',
                    'defaultPageSize' => $pageSize,
                ]
            ]);

            $models = $provider->getModels();

            if (!empty($models)) {
                foreach ($models as $key => $value) {
                    $image          = Images::find()->where(['id' => $value['item']['main_image_id'], 'image_type' => Images::TYPE_PRODUCT, 'main_image' => Images::IMAGE_MAIN])->one();
                    $file_name      = !empty($image) ? $image['image_name'] : '';
                    $show_image     = Yii::$app->general->get_images_path($file_name, Images::FOLDER_PRODUCT, Images::PLACEHOLDER_FOR_PRODUCT);
                    $total_price    = ($value['item']['price'] * $value['item_qty']) + $value['item']['delivery_charge'];
                    array_push($product_total, $total_price);

                    $data[$key]['id']                       = (int)$value['id'];
                    $data[$key]['user_id']                  = (int)$value['cart']['user_id'];
                    $data[$key]['cart_id']                  = (int)$value['cart_id'];
                    $data[$key]['item_id']                  = (int)$value['item_id'];
                    $data[$key]['item_name']                = $value['item']['title'];
                    $data[$key]['short_description']        = $value['item']['short_description'];
                    $data[$key]['item_qty']                 = (int)$value['item_qty'];
                    $data[$key]['product_qty']              = $value['item']['qty'];
                    $data[$key]['delivery_charge']          = ($value['item']['delivery_charge'] != 0) ? Yii::$app->general->convert_currency($value['item']['delivery_charge']) : 'Free';
                    $data[$key]['delivery_charge_']         = ($value['item']['delivery_charge'] != 0) ? $value['item']['delivery_charge'] : 'Free';
                    $data[$key]['can_remove_product']       = ($value['type'] == CartDetails::TYPE_PRODUCT) ? true : false;
                    $data[$key]['total_price']              = Yii::$app->general->convert_currency($total_price);
                    $data[$key]['total_price_']             = $total_price;
                    $data[$key]['price']                    = Yii::$app->general->convert_currency($value['item']['price']);
                    $data[$key]['price_']                   = $value['item']['price'];
                    $data[$key]['main_image']['id']         = (!empty($image)) ? $image->id : 0;
                    $data[$key]['main_image']['path']       = $show_image;
                }
            }

            $pagination     = Yii::$app->general->pagination($provider, $pageSize, $page);

            $cart_total     = [
                'grand_total_'  => array_sum($product_total),
            ];

            if ($pagination['status'] == false) {
                return ['status' => false, 'message' => $pagination['message'], 'data' => Product::PAGINATION_ARRAY];
            }

            return ['status' => true, 'message' => '', 'data' => ['items' => $data, 'pagination' => $pagination['pagination'], 'cart_total' => $cart_total]];
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return ['status' => false, 'message' => $e->getMessage(), 'data' => Product::PAGINATION_ARRAY];
        }
    }

    // To get User Products
    public function get_user_products($user_id)
    {
        $product_list   = [];
        $user_product   = Product::find()->where(['user_id' => $user_id])->all();
        $product_list   = ArrayHelper::map($user_product, 'id', 'title');
        return $product_list;
    }

    //Get the multiple sub categories
    public function get_multiple_sub_cat($product_id)
    {
        $otherdata  = ProductOtherData::findAll(['product_id' => $product_id]);
        $otherdata  = ArrayHelper::getColumn($otherdata, 'sub_category_id');

        return $otherdata;
    }

    //Save the multiple categories 
    public function saveOtherinfo($product_id, $subcat)
    {
        if (empty($subcat) || !isset($subcat) || $subcat == '') {
            return array('status' => false, 'message' => Yii::t('app', ucfirst($product_id) . ' cannot be blank.'));
        }
        $subcategory = $this->get_multiple_sub_cat($product_id);
        if (!empty($subcategory)) {
            $delete = $this->deleteOtherinfo($product_id);
            if (!$delete) {
                return array('status' => false, 'message' => Yii::t('app', 'Something Went Wrong. ' . ucfirst($product_id) . ' not Updated.'));
            }
        }

        foreach ($subcat as $d) {
            $other_data      = new ProductOtherData();
            $other_data->product_id         = $product_id;
            $other_data->sub_category_id    = $d;
            $other_data->save();
        }
        return array('status' => true);
    }

    //Delete the categories 
    public function deleteOtherinfo($product_id)
    {
        $subcategory = $this->get_multiple_sub_cat($product_id);
        if (!empty($subcategory)) {
            return ProductOtherData::deleteAll(['product_id' => $product_id]);
        }
        return true;
    }

    public function delete_product($product_id)
    {
        try {
            $product     = Product::findOne($product_id);
            if (empty($product)) {
                return array('status' => false, 'message' => "Product Not Found!");
            }

            $product->active  = Product::S_DELETE;
            if ($product->validate() && $product->save()) {
                return array('status' => true, 'message' => "Product has been deleted successfully.");
            } else {
                return array('status' => false, 'message' => Yii::$app->general->error($product->errors));
            }
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_', 'v1');
            return ['status' => false, 'message' => $e->getMessage()];
        }
    }

    public function set_main_image($id)
    {
        try {
            $new_image  = Images::find()->where(['id' => $id, 'image_type' => Images::TYPE_PRODUCT])->one();
            $pro_id     = !empty($new_image) ? $new_image->pre_define_id : 0;
            $old_image  = Images::find()->where(['pre_define_id' => $pro_id, 'image_type' => Images::TYPE_PRODUCT, 'main_image' => Images::IMAGE_MAIN])->one();
            $product    = Product::findOne($pro_id);

            if (!empty($new_image) && !empty($product) && !empty($old_image)) {

                $product->main_image_id = $id;
                $new_image->main_image  = Images::IMAGE_MAIN;
                $old_image->main_image  = Images::IMAGE_OTHER;

                if ($old_image->validate() && $old_image->save()) {
                    if ($new_image->validate() && $new_image->save()) {
                        if ($product->validate() && $product->save()) {
                            return array('status' => true, 'message' => Yii::t('app', 'Main Image id has changed'), 'data' => array());
                        } else {
                            return array('status' => false, 'message' => Yii::$app->general->error($product->errors));
                        }
                    } else {
                        return array('status' => false, 'message' => Yii::$app->general->error($new_image->errors));
                    }
                } else {
                    return array('status' => false, 'message' => Yii::$app->general->error($old_image->errors));
                }
            } else {
                return array('status' => false, 'message' => "Main Image id is empty");
            }
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage());
        }
    }

    public function image_delete($id)
    {
        try {
            $image  = Images::find()->where(['id' => $id, 'image_type' => Images::TYPE_PRODUCT])->one();
            if (empty($image)) {
                return array('status' => false, 'message' => Yii::t('app', 'No image found.'));
            }

            if ($image->main_image == Images::IMAGE_MAIN) {
                return array('status' => false, 'message' => Yii::t('app', 'You cannot delete Main Image.'));
            }

            $del    = Yii::$app->upload->deleteImage($image->image_name, 'product');

            if ($del == false) {
                return array('status' => false, 'message' => Yii::t('app', 'Image is not deleted from the folder'));
            }
            if ($image->delete()) {
                return array('status' => true, 'message' => Yii::t('app', 'Image Deleted'), 'data' => array());
            } else {
                return array('status' => false, 'message' => Yii::$app->general->error($image->errors));
            }
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage());
        }
    }

    public function one_product_detail($user_id, $id, $want_similar_product = true, $want_bid_history = true, $auction_product = '')
    {
        try {
            $similar_product    = $auction_data = [];
            $get_product        = Product::getDb()->cache(function ($db) use ($id) {
                return Product::find()->joinWith(['user'])->where(['`product`.`id`' => $id])->one();
            });
            if (!empty($get_product)) {
                $get_main_image = Images::getDb()->cache(function ($db) use ($id) {
                    return Images::find()->where(['pre_define_id' => $id, 'image_type' => Images::TYPE_PRODUCT, 'main_image' => Images::IMAGE_MAIN])->one();
                });
                $main_image     = !empty($get_main_image) ? 'MEDIUM_' . $get_main_image->image_name : '';
                $main_image     = Yii::$app->general->get_images_path($main_image, Images::FOLDER_PRODUCT, Images::PLACEHOLDER_FOR_PRODUCT);

                $get_category   = ProductOtherData::getDb()->cache(function ($db) use ($id) {
                    return ProductOtherData::find()->select('sub_category_id')->where(['product_id' => $id])->all();
                });
                $get_images     = Images::getDb()->cache(function ($db) use ($id) {
                    return Images::find()->where(['pre_define_id' => $id, 'image_type' => Images::TYPE_PRODUCT])->all();
                });
                $get_user_img   = Images::getDb()->cache(function ($db) use ($get_product) {
                    return Images::findOne(['pre_define_id' => $get_product->user_id, 'image_type' => Images::TYPE_USER, 'main_image' => Images::IMAGE_MAIN]);
                });

                $sub_categories = [];
                if (!empty($get_category)) {
                    foreach ($get_category as $sub_cat) {
                        array_push($sub_categories, $sub_cat['sub_category_id']);
                    }
                }

                $imgs           = [];
                if (!empty($get_images)) {
                    foreach ($get_images as $k => $images) {
                        $imgs[$k]['id']     = (!empty($images)) ? $images['id'] : 0;
                        $imgs[$k]['path']   = Yii::$app->general->get_images_path('MEDIUM_' . $images['image_name'], Images::FOLDER_PRODUCT, Images::PLACEHOLDER_FOR_PRODUCT);
                    }
                } else {
                    $imgs[0]['id']      = 0;
                    $imgs[0]['path']    = Yii::$app->general->img_assets(Images::PLACEHOLDER_FOR_PRODUCT);
                }

                $user_rating            = $this->get_my_rating($get_product->id, $user_id);
                $product_rating         = $this->get_product_rating($id);
                $can_rate               = Yii::$app->order->check_user_can_rate($user_id, $get_product->id);

                $wishlist               = Wishlist::findOne(['user_id' => $user_id, 'product_id' => (int)$id]);
                $cart                   = Cart::getDb()->cache(function ($db) use ($id, $user_id) {
                    return Cart::find()->joinWith('cartDetails')->where(['user_id' => $user_id])->andWhere(['item_id' => $id])->one();
                });
                $check_return_policy    = ($get_product->is_return == Product::IS_RETURN_YES) ? 'Seller does accept returns.' : 'Seller does not accept returns.';

                $chat_exist             = Yii::$app->common_user->check_chat_exist($user_id, $get_product['user']['id'], $get_product['id']);

                $user_image             = Yii::$app->general->get_images_path(!empty($get_product['user']['profile_pic']) ? $get_product['user']['profile_pic'] : '', Images::FOLDER_USER);

                if ($want_similar_product && !empty($get_category)) {
                    $Arry_rand          = array_rand($get_category);
                    $same_product       = ProductOtherData::getDb()->cache(function ($db) use ($id, $get_category, $Arry_rand) {
                        return ProductOtherData::find()->joinWith('product')
                            ->where(['sub_category_id' => $get_category[$Arry_rand]])
                            ->andWhere(['<>', 'product_id', $id])
                            ->limit(Product::SIMILAR_PRODUCT)
                            ->all();
                    });

                    if (!empty($same_product)) {
                        foreach ($same_product as $key => $s_product) {
                            $p_image    = Images::getDb()->cache(function ($db) use ($s_product) {
                                return Images::findOne(['id' => $s_product['product']['main_image_id'], 'main_image' => Images::IMAGE_MAIN, 'image_type' => Images::TYPE_PRODUCT]);
                            });
                            $similar_product[$key]['id']        = $s_product['product']['id'];
                            $similar_product[$key]['title']     = $s_product['product']['title'];
                            $similar_product[$key]['price']     = Yii::$app->general->convert_currency($s_product['product']['price']);
                            $similar_product[$key]['price_']    = $s_product['product']['price'];
                            $similar_product[$key]['main_image']['id']   = (!empty($p_image)) ? $p_image->id : 0;
                            $similar_product[$key]['main_image']['path'] = Yii::$app->general->get_images_path((!empty($p_image)) ? 'MEDIUM_' . $p_image->image_name : '', Images::FOLDER_PRODUCT);
                        }
                    }
                }
                $delivery_within    = Yii::$app->user_meta->get_meta_value($get_product['user']['id'], 'delivery_within');
                $product_cate       = Categories::getDb()->cache(function ($db) use ($get_product) {
                    return Categories::findOne($get_product->parent_id);
                });
                $product_type       = ProductType::getDb()->cache(function ($db) use ($get_product) {
                    return ProductType::findOne($get_product->product_type_id);
                });

                $show_button        = ($get_product['is_auction'] == Product::AUCTION_NO && $get_product['user_id'] != $user_id) ? true : false;
                $show_button_auc    = ($get_product['is_auction'] == Product::AUCTION_YES && $get_product['user_id'] != $user_id && $user_id != 0) ? true : false;

                if ($want_bid_history == true && $get_product->is_auction == Product::AUCTION_YES) {
                    $data   = $this->product_bid_history($get_product->id, false, 0, '', $auction_product);
                    if (empty($data['status'])) {
                        return $data;
                    }
                    $auction_data   = $data['data'];
                }

                $data       = [
                    'product_id'        => $get_product->id,
                    'title'             => $get_product->title,
                    'description'       => $get_product->description,
                    'short_description' => $get_product->short_description,
                    'parent_id'         => $get_product->parent_id,
                    'parent_name'       => !empty($product_cate) ? $product_cate->title : '',
                    'sub_category_id'   => $sub_categories,
                    'product_type'      => !empty($product_type) ? $product_type->title : '',
                    'price'             => isset($get_product->price) ? Yii::$app->general->convert_currency($get_product->price) : '',
                    // 'sell_price'        => isset($get_product->sell_price) ? Yii::$app->general->convert_currency($get_product->sell_price) : '',
                    // 'special_price'     => isset($get_product->special_price) ? Yii::$app->general->convert_currency($get_product->special_price) : '',
                    'price_'            => $get_product->price,
                    // 'sell_price_'       => $get_product->sell_price,
                    // 'special_price_'    => $get_product->special_price,
                    'qty'               => $get_product->qty,
                    'is_auction'        => $get_product->is_auction,
                    'is_feature'        => $get_product->is_feature,
                    'is_return'         => $get_product->is_return,
                    'is_refund'         => $get_product->is_refund,
                    'auction_period'    => $get_product->auction_period,
                    'auction_data'      => $auction_data,

                    'main_image'        =>  [
                        'id'     => (int)$get_product->main_image_id,
                        'path'   => $main_image,
                    ],

                    'images'            => $imgs,

                    'product_rating'    => $product_rating['average_product_rating'],
                    'reviews'           => $product_rating['product_rating_count'],
                    'user_rating'       => $user_rating,
                    'can_rate'          => $can_rate,
                    'delivery_charge_'  => ($get_product->delivery_charge != 0) ? $get_product->delivery_charge : 'Free',
                    'delivery_charge'   => ($get_product->delivery_charge != 0) ? Yii::$app->general->convert_currency($get_product->delivery_charge) : 'Free',
                    'total_price'       => Yii::$app->general->convert_currency($get_product->price + $get_product->delivery_charge),
                    'total_price_'      => $get_product->price + $get_product->delivery_charge,

                    'wishlist'          => !empty($wishlist) ? true : false,
                    'cart_data'         => !empty($cart) ? true : false,

                    'seller'            => [
                        'delivery_time' => (($delivery_within) ? $delivery_within : Users::DELIVERY_WITHIN) . " working days",
                        'return_policy' => $check_return_policy,
                        'user_id'       => $get_product['user']['id'],
                        'user_name'     => $get_product['user']['firstname'] . ' ' . $get_product['user']['lastname'],
                        'phone_number'  => $get_product['user']['phone_code'] . ' ' . $get_product['user']['phone'],
                        'main_image'    => [
                            'id'        => !empty($get_user_img) ? $get_user_img->id : 0,
                            'path'      => $user_image,
                        ],
                    ],

                    'similar_product'   => $similar_product,

                    'chat_data'         => [
                        'receiver_id'   => $get_product->user_id,
                        'owner_name'    => $get_product['user']['firstname'] . ' ' . $get_product['user']['lastname'],
                        'product_id'    => $get_product->id,
                        'sender_id'     => $user_id,
                        'chat_token'    => $chat_exist
                    ],
                    'show_button'       => $show_button,
                    'show_button_auc'   => $show_button_auc,

                ];

                return array('status' => true, 'data' => $data, 'message' => "Data get sucessfully");
            } else {
                return array('status' => false, 'message' => "No Product found.!", 'data' => $id);
            }
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage());
        }
    }

    public function my_products($login_id, $page = 0, $search = '', $type = 'both')
    {
        try {
            if ($type == 'both') {
                $InStock                = $this->query($login_id, $search, $page, 'instock');
                $OutStock               = $this->query($login_id, $search, $page, 'outstock');

                if ($InStock['status'] == false || $OutStock['status'] == false) {
                    $message = !empty($InStock['message']) ? $InStock['message'] : $OutStock['message'];
                    return array('status' => false, 'message' => $message, 'data' => ['in_stock' => Product::PAGINATION_ARRAY, 'out_stock' => Product::PAGINATION_ARRAY]);
                }

                $inStock_pagination     = Yii::$app->general->pagination($InStock['data']['provider'], $InStock['data']['pageSize'], $page);
                $outStock_pagination    = Yii::$app->general->pagination($OutStock['data']['provider'], $OutStock['data']['pageSize'], $page);

                if ($inStock_pagination['status'] == false || $outStock_pagination['status'] == false) {
                    $message = !empty($inStock_pagination['message']) ? $inStock_pagination['message'] : $outStock_pagination['message'];
                    return array('status' => false, 'message' => $message, 'data' => ['in_stock' => Product::PAGINATION_ARRAY, 'out_stock' => Product::PAGINATION_ARRAY]);
                }

                $in_stock_data  = ['items' => $InStock['data']['product_data'], 'pagination' => $inStock_pagination['pagination']];
                $out_stock_data = ['items' => $OutStock['data']['product_data'], 'pagination' => $outStock_pagination['pagination']];
                return array('status' => true, 'data' => ['in_stock' => $in_stock_data, 'out_stock' => $out_stock_data]);
            } else {
                $MyStock    = $this->query($login_id, $search, $page, $type);
                if ($MyStock['status'] == false) {
                    return array('status' => false, 'message' => $MyStock['message'], 'data' => Product::PAGINATION_ARRAY);
                }

                $MyStock_pagination = Yii::$app->general->pagination($MyStock['data']['provider'], $MyStock['data']['pageSize'], $page);

                if ($MyStock_pagination['status'] == false) {
                    return array('status' => false, 'message' => $MyStock_pagination['message'], 'data' => Product::PAGINATION_ARRAY);
                }

                $my_stock_data = ['items' => $MyStock['data']['product_data'], 'pagination' => $MyStock_pagination['pagination']];
                return array('status' => true, 'data' => $my_stock_data);
            }
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage(), 'data' => ['in_stock' => Product::PAGINATION_ARRAY, 'out_stock' => Product::PAGINATION_ARRAY]);
        }
    }

    public function my_auction_products($login_id, $page = 0, $search = '', $type = 'both')
    {
        try {
            if ($type == 'both') {
                $ongoing    = $this->query($login_id, $search, $page, 'on-going');
                $expired    = $this->query($login_id, $search, $page, 'expired');

                if ($ongoing['status'] == false || $expired['status'] == false) {
                    $message = !empty($ongoing['message']) ? $ongoing['message'] : $expired['message'];
                    return array('status' => false, 'message' => $message, 'data' => ['on-going' => Product::PAGINATION_ARRAY, 'expired' => Product::PAGINATION_ARRAY]);
                }

                $ongoing_pagination     = Yii::$app->general->pagination($ongoing['data']['provider'], $ongoing['data']['pageSize'], $page);
                $expired_pagination    = Yii::$app->general->pagination($expired['data']['provider'], $expired['data']['pageSize'], $page);

                if ($ongoing_pagination['status'] == false || $expired_pagination['status'] == false) {
                    $message = !empty($ongoing_pagination['message']) ? $ongoing_pagination['message'] : $expired_pagination['message'];
                    return array('status' => false, 'message' => $message, 'data' => ['on-going' => Product::PAGINATION_ARRAY, 'expired' => Product::PAGINATION_ARRAY]);
                }

                $ongoing_data  = ['items' => $ongoing['data']['product_data'], 'pagination' => $ongoing_pagination['pagination']];
                $expired_data = ['items' => $expired['data']['product_data'], 'pagination' => $expired_pagination['pagination']];
                return array('status' => true, 'data' => ['on-going' => $ongoing_data, 'expired' => $expired_data]);
            } else {
                $Myproduct    = $this->query($login_id, $search, $page, $type, 'auction');
                if ($Myproduct['status'] == false) {
                    return array('status' => false, 'message' => $Myproduct['message'], 'data' => Product::PAGINATION_ARRAY);
                }

                $Myproduct_pagination = Yii::$app->general->pagination($Myproduct['data']['provider'], $Myproduct['data']['pageSize'], $page);

                if ($Myproduct_pagination['status'] == false) {
                    return array('status' => false, 'message' => $Myproduct_pagination['message'], 'data' => Product::PAGINATION_ARRAY);
                }

                $my_auction_data = ['items' => $Myproduct['data']['product_data'], 'pagination' => $Myproduct_pagination['pagination']];
                return array('status' => true, 'data' => $my_auction_data);
            }
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage(), 'data' => ['on-going' => Product::PAGINATION_ARRAY, 'expired' => Product::PAGINATION_ARRAY]);
        }
    }

    public function rate_management($user_id, $product_id, $rate, $text = '')
    {
        try {
            if (Yii::$app->order->check_user_can_rate($user_id, $product_id)) {
                $rating     = RatingProduct::findOne(['product_id' => $product_id, 'rate_by' => $user_id]);
                $rating     = empty($rating) ? new RatingProduct() : $rating;
                $rating->product_id     = $product_id;
                $rating->rating         = $rate;
                $rating->rate_by        = $user_id;
                $rating->description    = $text;
                if ($rating->validate() && $rating->save()) {
                    $average    = $this->update_rate($product_id);
                    return ['status' => true, 'message' => 'Thank You for rating.', 'data' =>  $rating->product_id];
                }
                return ['status' => false, 'message' => Yii::$app->general->error($rating->errors)];
            } else {
                $product        = Product::findOne($product_id);
                $product_name   = !empty($product) ? $product->title : 'this';
                return ['status' => false, 'message' => "You cannot rate " . $product_name . " product."];
            }
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return ['status' => false, 'message' => $e->getMessage()];
        }
    }

    public function update_rate($product_id)
    {
        $sum_rate = $average = 0;
        $product_rates  = RatingProduct::findAll(['product_id' => $product_id]);
        if (!empty($product_rates)) {
            foreach ($product_rates as $user_rate) {
                $sum_rate   = $user_rate->rating + $sum_rate;
            }
            $average    = round($sum_rate / count($product_rates), 2);
        }
        Yii::$app->user_meta->update_product_meta($product_id, "average_rate", $average);
        return $average;
    }

    public function query($login_id, $search, $page, $type, $product_type = '')
    {
        try {
            $eventData = $models = $data = [];
            $auction_product = '';

            if ($product_type == "auction") {
                $eventData = Product::find()->where(['user_id' => $login_id, 'active' => Product::S_ACTIVE])->andWhere(['is_auction' => Product::AUCTION_YES])->asArray();
                if ($type == 'on-going') {
                    $eventData->andwhere(['is_auction_expired' => Product::AUCTION_NOT_EXPIRED]);
                } else {
                    $eventData->andwhere(['is_auction_expired' => Product::AUCTION_EXPIRED]);
                    $auction_product = 'auction';
                }
            } else {
                $eventData = Product::find()->where(['user_id' => $login_id, 'active' => Product::S_ACTIVE])->andWhere(['is_auction' => Product::AUCTION_NO])->asArray();
                if ($type == 'instock') {
                    $eventData->andWhere(['<>', 'qty', '0']);
                } else {
                    $eventData->andWhere(['qty' => '0']);
                }
            }
            $eventData  = $eventData->orderBy(['id' => SORT_DESC]);

            if ($search != '') {
                $eventData->andFilterWhere([
                    'or',
                    ['like', 'title', $search],
                    ['like', 'description', $search],
                    ['like', 'short_description', $search],
                    ['like', 'price', $search],
                    ['like', 'slug', $search],
                ]);
            }

            $pageSize = PRODUCT::PRODUCT_LIMIT;
            $provider = new ActiveDataProvider([
                'query' => $eventData,
                'pagination' => [
                    'page'              => $page,
                    'pageParam'         => 'page',
                    'defaultPageSize'   => $pageSize,
                ]
            ]);

            $models =   $provider->getModels();
            if (!empty($models)) {
                foreach ($models as $key => $value) {
                    $product_detail   = $this->one_product_detail($login_id, $value['id'], false, false, $auction_product);
                    if ($product_detail['status']) {
                        $data[$key] = $product_detail['data'];
                    } else {
                        return $product_detail;
                    }
                }
            }

            return ['status' => true, 'data' => ['pageSize' => $pageSize, 'provider' => $provider, 'product_data' => $data]];
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage(), 'data' => Product::PAGINATION_ARRAY);
        }
    }

    public function search_filter($query, $where, $api = false, $is_user_side = true)
    {
        if (!empty($where['sort_by'])) {
            switch ($where['sort_by']) {
                case 'price_low_to_high':
                    $query->orderBy(['price' => SORT_ASC]);
                    break;
                case 'price_high_to_low':
                    $query->orderBy(['price' => SORT_DESC]);
                    break;
                case 'name_a_to_z':
                    $query->orderBy(['title' => SORT_ASC]);
                    break;
                case 'name_z_to_a':
                    $query->orderBy(['title' => SORT_DESC]);
                    break;
                case 'new_arrivals':
                    $query->orderBy(['id' => SORT_DESC]);
                    break;
                default:
                    break;
            }
        }

        if (!empty($where['category'])) {
            $sub_cat = explode(',', $where['category']);
            if (!empty($sub_cat)) {
                foreach ($sub_cat as $cat_sub) {
                    if ($api) {
                        $query->orFilterWhere(['sub_category_id' => $cat_sub]);
                    } else {
                        $child_cat  = Categories::find()->where(['slug' => $cat_sub, 'type' => Categories::TYPE_CHILD])->one();
                        $query->orFilterWhere(['sub_category_id' => $child_cat]);
                    }
                }
            }
        }

        if (!empty($where['min_price']) && !empty($where['max_price'])) {
            $query->andFilterWhere(['between', 'price', $where['min_price'], $where['max_price']]);
        }

        if ($where['search'] != '') {
            $query->andFilterWhere(['like', 'title', $where['search']]);
        }

        if ($where['is_auction']) {
            $query->andFilterWhere(['is_auction' => Product::AUCTION_YES]);
        }

        if ($is_user_side == true) {
            $query->andFilterWhere(['active' => Product::S_ACTIVE])
                ->andWhere(['<>', 'qty', Product::STOCK_NO])
                ->andFilterWhere(['is_auction_expired' => Product::AUCTION_NOT_EXPIRED]);
        }

        if (!empty($where['parent_category'])) {
            $category_data = Categories::find()->where(['title' => $where['parent_category']])->orWhere(['id' => $where['parent_category']])->one();
            $query->andFilterWhere(['parent_id' => !empty($category_data->id) ? $category_data->id : ""]);
        }

        return $query;
    }

    public function get_my_rating($product_id, $user_id)
    {
        $rating = RatingProduct::getDb()->cache(function ($db) use ($product_id, $user_id) {
            return RatingProduct::find()->where(['product_id' => $product_id, 'rate_by' => $user_id])->one();
        });
        if (!empty($rating)) {
            return ['rating' => $rating->rating, 'description' => $rating->description];
        } else {
            return ['rating' => 0, 'description' => ''];
        }
    }

    public function get_product_rating($product_id)
    {
        $user_rating_count = RatingProduct::getDb()->cache(function ($db) use ($product_id) {
            return RatingProduct::find()->where(['product_id' => $product_id])->count();
        });
        $rating             = Yii::$app->user_meta->get_product_value($product_id, 'average_rate');
        return ['average_product_rating' => $rating ? $rating : 0, 'product_rating_count' => !empty($user_rating_count) ? $user_rating_count : 0];
    }

    public function feature_product($product_id, $user_id, $transaction_id, $raw_data)
    {
        try {
            $product    = Product::findOne(['id' => $product_id, 'user_id' => $user_id, 'active' => Product::S_ACTIVE]);
            if (!empty($product)) {
                $add_paymant                    = new Payment();
                $add_paymant->user_id           = $user_id;
                $add_paymant->order_id          = null;
                $add_paymant->transaction_id    = $transaction_id;
                $add_paymant->related_id        = $product_id;
                $add_paymant->platform          = Payment::STRIPE;
                $add_paymant->type              = Payment::FEATURE;
                $add_paymant->raw_data          = $raw_data;

                if ($add_paymant->validate() && $add_paymant->save()) {

                    $product->is_feature        = Product::IS_FEATURE_YES;
                    $product->feature_time      = time();
                    if ($product->validate() && $product->save()) {
                        return ['status' => true, 'message' => 'This Product has been feature successfull.'];
                    } else {
                        return ['status' => false, 'message' => Yii::$app->general->error($product->errors)];
                    }
                } else {
                    return ['status' => false, 'message' => Yii::$app->general->error($add_paymant->errors)];
                }
            } else {
                return ['status' => false, 'message' => "This product is not belongs to you!"];
            }
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage());
        }
    }

    //Adding Report of Product
    public function add_report($user_id, $product_id, $description)
    {
        try {
            $report              = new ReportProduct();
            $report->user_id     = $user_id;
            $report->product_id  = $product_id;
            $report->description = $description;

            if ($report->validate() && $report->save()) {
                $admins = Yii::$app->common_user->superAdminIDs();
                foreach($admins as $admin) {
                    $product    = Product::findOne($product_id);
                    $message    = Yii::$app->common_user->get_full_name($user_id) . ' have report ' . $product->title . ' Product.';
                    /** Sent Notification */
                    $noti_data  = array(
                        'to_user_id'    => $admin,
                        'title'         => 'Report Product.',
                        'message'       => $message,
                        'type'          => Notification::TYPE_PRODUCT,
                        'from_user_id'  => $user_id,
                    );
                    $notify = Yii::$app->notification->send($noti_data);
                    /** Sent Notification END */

                    $subject_array['{{report_from}}']   = Yii::$app->common_user->get_full_name($user_id);
                    $string_array['{{message}}']        = $message;
                    $admins = Yii::$app->general->send_email($admin, $string_array, 'report_product', $subject_array);
                }
                return ['status' => true, 'message' => 'Report submitted successfully'];
            } else {
                return ['status' => false, 'message' => Yii::$app->general->error($report->errors)];
            }
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage());
        }
    }

    //Adding payment of banner 
    public function banner_payment($banner_id, $user_id, $transaction_id, $raw_data)
    {
        try {
            $banner     = Banner::find()->where(['id' => $banner_id, 'user_id' => $user_id])->one();
            if (empty($banner)) {
                return ['status' => false, 'message' => 'This banner is not belongs to you.'];
            }

            $add_banner_payment                    = new Payment();
            $add_banner_payment->user_id           = $user_id;
            $add_banner_payment->order_id          = null;
            $add_banner_payment->transaction_id    = $transaction_id;
            $add_banner_payment->related_id        = $banner_id;
            $add_banner_payment->platform          = Payment::STRIPE;
            $add_banner_payment->type              = Payment::BANNER;
            $add_banner_payment->raw_data          = $raw_data;

            if ($add_banner_payment->validate() && $add_banner_payment->save()) {
                $plan       = Plan::findOne(Plan::BANNER_ID);
                $duration   = $plan->plan_duration . ' ' . $plan->duration_type;
                $today_date = date("Y-m-d H:i:s");
                $banner->status         = Banner::STATUS_ACCEPT;
                $banner->expired_date   = strtotime($today_date . ' + ' . $duration);
                if ($banner->validate() && $banner->save()) {
                    return ['status' => true, 'message' => 'This banner payment done.'];
                } else {
                    return ['status' => false, 'message' => Yii::$app->general->error($banner->errors)];
                }
            } else {
                return ['status' => false, 'message' => Yii::$app->general->error($add_banner_payment->errors)];
            }
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage());
        }
    }

    public function rating_data($page, $product_id)
    {
        try {
            $query      = RatingProduct::find()->where(['product_id' => $product_id])->asArray();
            $pageSize   = Product::RATING_LIMIT;
            $provider   = new ActiveDataProvider([
                'query' => $query,
                'pagination' => [
                    'page' => $page,
                    'pageParam' => 'page',
                    'defaultPageSize' => $pageSize,
                ]
            ]);
            $models     = $provider->getModels();
            $pagination = Yii::$app->general->pagination($provider, $pageSize, $page);
            if (empty($pagination['status'])) {
                return $pagination;
            }

            return array('status' => true, 'data' => array('items' => $models, 'pagination' => $pagination['pagination']));
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage());
        }
    }

    public function get_banner($type)
    {
        try {
            $banner_data = [];
            $get_banner     = Banner::find()->where(['type' => $type, 'status' => [Banner::STATUS_BY_ADMIN, Banner::STATUS_ACCEPT]])
                ->andWhere(['>', 'expired_date', time()])
                ->orderBy(['id' => SORT_DESC])
                ->limit(Product::BANNER_LIMIT)
                ->all();

            if (!empty($get_banner)) {
                foreach ($get_banner as $key => $banner) {
                    $image          = Images::findOne($banner->image_id);
                    $b_image        = Yii::$app->general->get_images_path(!empty($image) ? $image->image_name : '', Images::FOLDER_BANNER);
                    $banner_data[$key]['id']                    = $banner->id;
                    $banner_data[$key]['user_id']               = $banner->user_id;
                    $banner_data[$key]['product_id']            = $banner->product_id;
                    $banner_data[$key]['external_url']          = $banner->external_url;
                    $banner_data[$key]['show_profile']          = $banner->show_profile;
                    $banner_data[$key]['main_image']['id']      = !empty($image) ? $image->id : 0;
                    $banner_data[$key]['main_image']['path']    = $b_image;
                }
                return array('status' => true, 'data' => $banner_data, 'message' => 'Get Banner successfully');
            } else {
                return array('status' => true, 'data' => [], 'message' => 'No Banner Data Found!');
            }
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage(), 'data' => []);
        }
    }

    //  Add Bid
    public function add_bid($user_id, $product_id, $price)
    {
        try {
            $check_product  = Product::findOne(['id' => $product_id, 'is_auction' => Product::AUCTION_YES, 'is_auction_expired' => Product::AUCTION_NOT_EXPIRED, 'active' => Product::S_ACTIVE]);
            if (empty($check_product)) {
                return ['status' => false, "message" => "Product is Invalid.!"];
            }

            $check_bid_list = BidList::find()->where(['product_id' => $product_id])->orderBy(['price' => SORT_DESC])->one();
            $min_bid        = !empty($check_bid_list) ? $check_bid_list->price : $check_product->price;

            /*
            if (!empty($check_bid_list) && $check_bid_list->user_id == $user_id) {
                return ['status' => false, "message" => 'Not allow.'];
            }
            */

            if ($price <= $min_bid) {
                return ['status' => false, "message" => 'Price must be greater than ' . $min_bid];
            }

            $add_bid                = new BidList();
            $add_bid->user_id       = $user_id;
            $add_bid->product_id    = $product_id;
            $add_bid->price         = $price;
            if ($add_bid->validate() && $add_bid->save()) {
                if (!empty($check_bid_list)) {
                    /** Sent Notification */
                    $noti_data = array(
                        'to_user_id'    => $check_bid_list->user_id,
                        'title'         => 'Your bid is surpassed.',
                        'message'       => 'Your bid is surpassed by another user.',
                        'type'          => Notification::TYPE_PRODUCT,
                        'from_user_id'  => null,
                    );
                    $notify = Yii::$app->notification->send($noti_data);
                    /** Sent Notification END */
                }
                return ['status' => true, 'message' => "Bid Successfully Added."];
            } else {
                return ['status' => false, "message" => Yii::$app->general->error($add_bid->errors)];
            }
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage());
        }
    }

    //  My Bid Product
    public function my_bids($user_id, $type, $page = 0, $search = '')
    {
        try {
            if (empty($type)) {
                return ['status' => false, 'data' => Product::PAGINATION_ARRAY, 'message' => "Type cannot be blank"];
            }

            $pageSize   = Users::PAGE_SIZE;
            $bid_data   = $this->bid_data_query($user_id, $type, $search, $page, $pageSize);
            if (empty($bid_data['status'])) {
                return $bid_data;
            }

            $pagination = Yii::$app->general->pagination($bid_data['data']['provider'], $pageSize, $page);
            if (empty($pagination['status'])) {
                return $pagination;
            }

            return ['status' => true, 'data' => ['items' => $bid_data['data']['items'], 'pagination' => $pagination['pagination']]];
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage(), 'data' => Product::PAGINATION_ARRAY);
        }
    }

    public function bid_data_query($user_id, $type, $search, $page, $pageSize)
    {
        try {
            $models = $product_detail = [];

            $user_bid_product   = BidList::find()->joinWith('product')->where(['bid_list.user_id' => $user_id, "is_auction" => Product::AUCTION_YES]);
            if ($type == "on-going") {
                $user_bid_product->andWhere(['is_auction_expired' => Product::AUCTION_NOT_EXPIRED]);
            } else if ($type == "expired") {
                $user_bid_product->andWhere(['is_auction_expired' => Product::AUCTION_EXPIRED]);
            }

            if ($search != '') {
                $user_bid_product->andFilterWhere([
                    'or',
                    ['like', 'title', $search],
                ]);
            }

            $provider = new ActiveDataProvider([
                'query' => $user_bid_product,
                'pagination' => [
                    'page'              => $page,
                    'pageParam'         => 'page',
                    'defaultPageSize'   => $pageSize,
                ]
            ]);

            $models =   $provider->getModels();

            if (!empty($models)) {
                foreach ($models as $k => $bid_product) {
                    $bid_list_product   = BidList::find()->where(['product_id' => $bid_product])->orderBy(['price' => SORT_DESC])->one();
                    $expired_price      = !empty($bid_list_product) ? $bid_list_product->price : $bid_product->price;

                    $get_product_img    = Images::findOne(['pre_define_id' => $bid_product['product']->id, 'image_type' => Images::TYPE_PRODUCT, 'main_image' => Images::IMAGE_MAIN]);

                    $product_detail[$k]['id']                   = $bid_product->id;
                    $product_detail[$k]['title']                = $bid_product['product']->title;
                    $product_detail[$k]['my_bid']               = Yii::$app->general->convert_currency($bid_product->price);
                    $product_detail[$k]['on_going']             = Yii::$app->general->convert_currency($expired_price);
                    $product_detail[$k]['my_bid_']              = $bid_product->price;
                    $product_detail[$k]['on_going_']            = $expired_price;
                    $product_detail[$k]['main_image']['id']     = !empty($get_product_img) ? $get_product_img['id'] : 0;
                    $product_detail[$k]['main_image']['path']   = Yii::$app->general->get_images_path(!empty($get_product_img) ? 'MEDIUM_' . $get_product_img['image_name'] : '', Images::FOLDER_PRODUCT, Images::PLACEHOLDER_FOR_PRODUCT);
                }
                return ['status' => true, 'data' => ['provider' => $provider, 'items' => $product_detail], 'message' => ''];
            } else {
                return ['status' => false, 'data' => Product::PAGINATION_ARRAY, 'message' => "No data found!"];
            }
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage(), 'data' =>  Product::PAGINATION_ARRAY);
        }
    }

    // Bid History
    public function product_bid_history($product_id, $want_history = true, $page = 0, $search = '', $product_type = '')
    {
        try {
            if ($product_type == 'auction') {
                $get_product    = Product::getDb()->cache(function ($db) use ($product_id) {
                    return Product::findOne(['id' => $product_id, 'is_auction' => Product::AUCTION_YES, 'is_auction_expired' => Product::AUCTION_EXPIRED]);
                });
            } else {
                $get_product    = Product::getDb()->cache(function ($db) use ($product_id) {
                    return Product::findOne(['id' => $product_id, 'is_auction' => Product::AUCTION_YES, 'is_auction_expired' => Product::AUCTION_NOT_EXPIRED]);
                });
            }
            if (empty($get_product)) {
                return ['status' => false, 'data' => [], 'message' => "Product is Invalid!."];
            }

            $winner     = BidList::getDb()->cache(function ($db) use ($get_product) {
                return BidList::find()->where(['product_id' => $get_product->id])->orderBy(['price' => SORT_DESC])->one();
            });
            $p_image    = Images::getDb()->cache(function ($db) use ($get_product) {
                return Images::findOne(['pre_define_id' => $get_product->id, 'image_type' => Images::TYPE_PRODUCT, 'main_image' => Images::IMAGE_MAIN]);
            });

            // Bid Product Detail      
            $product_data['title']                   = $get_product->title;
            $product_data['price']                   = Yii::$app->general->convert_currency($get_product->price);
            $product_data['price_']                  = $get_product->price;
            $product_data['main_image']['id']        = !empty($p_image) ? $p_image->id : 0;
            $product_data['main_image']['path']      = Yii::$app->general->get_images_path(!empty($p_image) ? 'MEDIUM_' . $p_image->image_name : '', Images::FOLDER_PRODUCT, Images::PLACEHOLDER_FOR_PRODUCT);

            // Bidding
            $bidding['time_left']       = date('d-M-Y h:i:s A', strtotime('+' . $get_product->auction_period, $get_product->created_at));
            $bidding['bids']            = BidList::getDb()->cache(function ($db) use ($product_id) {
                return (int)BidList::find()->where(['product_id' => $product_id])->count();
            });
            $bidding['bidder']          = BidList::getDb()->cache(function ($db) use ($product_id) {
                return (int)BidList::find()->where(['product_id' => $product_id])->groupBy('user_id')->count();
            });
            $bidding['last_bid']        = !empty($winner) ? Yii::$app->general->convert_currency($winner->price) : Yii::$app->general->convert_currency($get_product->price);
            $bidding['last_bid_']       = !empty($winner) ? $winner->price : $get_product->price;

            if (!$want_history) {
                return ['status' => true, 'data' => $bidding, 'message' => 'Data Successfully get.'];
            }

            // bid history data
            $BidData    = $this->bid_history_query($product_id, $page, $search);
            if (empty($BidData['status'])) {
                return $BidData;
            }

            return ['status' => true, 'data' => ['product_detail' => $product_data, 'bidding' => $bidding, 'bid_list' => $BidData['data']], 'message' => 'Data Successfully get.'];
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage(), 'data' =>  Product::PAGINATION_ARRAY);
        }
    }

    public function bid_history_query($product_id, $page, $search)
    {
        try {
            $bid_history = $models = $bid_detail = [];
            $bid_history    = BidList::getDb()->cache(function ($db) use ($product_id) {
                return BidList::find()->joinWith(['user'])->where(['product_id' => $product_id])->orderBy(['price' => SORT_DESC]);
            });

            $pageSize   = Product::BID_PAGE_SIZE;
            $provider   = new ActiveDataProvider([
                'query' => $bid_history,
                'pagination' => [
                    'page'              => $page,
                    'pageParam'         => 'page',
                    'defaultPageSize'   => $pageSize,
                ]
            ]);

            if ($search != '') {
                /*
                $provider->andFilterWhere([
                    'or',
                    ['like', 'title', $search],
                ]);
                */
            }

            $models     = $provider->getModels();

            if (!empty($models)) {

                foreach ($models as $k => $bid_history_data) {
                    $bid_detail[$k]['username']     = Yii::$app->common_user->get_full_name($bid_history_data->user_id);
                    $bid_detail[$k]['bid_price']    = Yii::$app->general->convert_currency($bid_history_data->price);
                    $bid_detail[$k]['bid_price_']   = $bid_history_data->price;
                    $bid_detail[$k]['time']         = Yii::$app->general->timeAgo($bid_history_data->created_at);
                }

                $bid_pagination    = Yii::$app->general->pagination($provider, $pageSize, $page);
                if (empty($bid_pagination['status'])) {
                    return $bid_pagination;
                }

                return ['status' => true, 'data' => ['items' => $bid_detail, 'pagination' => $bid_pagination['pagination']], 'message' => "Data get successfully."];
            } else {
                return ['status' => false, 'message' => "No data found!", 'data' => Product::PAGINATION_ARRAY];
            }
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage(), 'data' =>  Product::PAGINATION_ARRAY);
        }
    }

    public function slider_data($product_id)
    {
        try {
            $product_data     = Product::getDb()->cache(function ($db) use ($product_id) {
                return Product::find()->joinWith(['user'])->where(['product.id' => $product_id, 'is_feature' => Product::IS_FEATURE_YES, 'active' => Product::S_ACTIVE])->one();
            });

            if (!empty($product_data)) {
                $get_main_image = Images::getDb()->cache(function ($db) use ($product_data) {
                    return Images::find()->where(['id' => $product_data->main_image_id, 'image_type' => Images::TYPE_PRODUCT, 'main_image' => Images::IMAGE_MAIN])->one();
                });

                $main_image     = !empty($get_main_image) ? 'MEDIUM_' . $get_main_image->image_name : '';
                $main_image     = Yii::$app->general->get_images_path($main_image, Images::FOLDER_PRODUCT, Images::PLACEHOLDER_FOR_PRODUCT);

                $get_category   = ProductOtherData::getDb()->cache(function ($db) use ($product_data) {
                    return ProductOtherData::find()->select('sub_category_id')->where(['product_id' => $product_data->id])->all();
                });

                $wishlist       = Wishlist::find()->where(['user_id' => $product_data['user']->id, 'product_id' => $product_data->id])->one();

                $product_cate   = Categories::getDb()->cache(function ($db) use ($product_data) {
                    return Categories::findOne($product_data->parent_id);
                });

                $sub_categories = [];
                if (!empty($get_category)) {
                    foreach ($get_category as $sub_cat) {
                        $categories = Categories::getDb()->cache(function ($db) use ($sub_cat) {
                            return Categories::findOne($sub_cat['sub_category_id']);
                        });
                        $p_url  = Url::to(["product/all-product?parent_category=" . $product_cate['title'] . "&sub_category=" . $categories['slug']]);
                        $link   = '<a href="' . $p_url . '">' . $categories['title'] . '</a>';
                        !empty($categories) ? array_push($sub_categories, $link) : '';
                    }
                }

                $product_rating         = $this->get_product_rating($product_data->id);

                $rate                   = !empty($product_rating) ? $product_rating['average_product_rating'] : 0;
                $reviews                = !empty($product_rating) ? $product_rating['product_rating_count'] : 0;

                $data   = [
                    'url'               => Url::to(["/product/product-detail?product_id=" . $product_data->id]),
                    'rate'              => $rate,
                    'review'            => $reviews . ' ' . Yii::$app->general->getPluralPrase('review', $reviews),
                    'wishlist'          => $wishlist,
                    'main_image'        => $main_image,
                    'product_data'      => $product_data,
                    'sub_category'      => $sub_categories,
                    'product_rating'    => $product_rating,
                    'parent_category'   => $product_cate,
                ];

                return ['status' => true, 'data' => $data, 'message' => 'Data Get Successfully'];
            } else {
                return ['status' => false, 'message' => 'No data found!'];
            }
        } catch (\Exception $e) {
            Yii::$app->general->createLogFile($e, 'ProductComponent_');
            return array('status' => false, 'message' => $e->getMessage());
        }
    }
}
