<?php

namespace App\Http\Controllers\User;

use App\Helpers\ChatMessenger;
use App\Http\Controllers\Controller;
use App\Models\GiftCardAmount;
use App\Models\GiftCards;
use App\Models\Merchant;
use App\Models\TradeGiftCard;
use App\Models\TradeRequests;
use App\Models\TradingCardDetails;
use App\Models\User;
use Chatify\Facades\ChatifyMessenger as Chatify;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Str;


class TradeGiftController extends Controller
{
    //
    public $chat;
    protected $perPage = 30;

    public function __construct()
    {
        $this->chat = new ChatMessenger();
    }
    public function SellGiftCard(){
        $giftCards = GiftCards::all();
        return view('user.giftcard.sell_index', compact('giftCards'));
    }

    public function getGiftCardAmount($gid){
        $giftAmount = GiftCardAmount::where('card_id',$gid)->pluck('id','amount');
        return response()->json($giftAmount);
    }

    public function getRate($ref){
        $giftAmount =GiftCardAmount::where('id', $ref)->select('id', 'rate', 'amount')->first();
        return response()->json($giftAmount);
    }

    public function saveTrade(Request $request){
        $request->validate([
            'giftCardID'=>'required',
            'qty'=>'required',
            'amount'=>'required'
        ],[
            'giftCardID.required' => 'Please Add the giftcard you want to trade',
            'qty.required' => 'Please enter the quantity.',
            'amount.required' => 'Please enter the amount.'
        ]);
       // try{
            $giftCardId = $request->giftCardID;
            $rateID = $request->amount;
            $totalTrade = count($rateID);
            $tQty = $request->qty;
            $tCurrency = $request->currency;
            if($totalTrade>0){//which mean thier data in giftcardid
                //run check for the rate
                //create Trading
                $refNo = 'R2T-'.time();
                $tradingModel = new TradeGiftCard();
                $tradingModel->user_id=auth()->user()->id;
                $tradingModel->trade_status="Pending";
                $tradingModel->reference_no = $refNo;
                $tradingModel->save();

              //  $selectedGiftCard = GiftCardAmount::whereIn('id',$rateID)->get();
$totalAmount = 0;
$totalRfbonus = 0;
$tradeDescription = "";
                for($i=0;$i<$totalTrade;$i++){
                    $getRate =  GiftCardAmount::where('id',$rateID[$i])->first();
                    if(!(empty($getRate))){
                        $qty = $tQty[$i];
                        $currency = $tCurrency[$i];

                        for($x=0;$x<$qty;$x++) {
                            $tradeModel = new TradingCardDetails();
                            $tradeModel->card_id = $getRate->card_id;;
                            $tradeModel->trading_id = $tradingModel->id;
                            $tradeModel->currency = $currency;
                            $tradeModel->rate = $getRate->rate;
                            $tradeModel->amount = $getRate->amount;
                            $tradeModel->total_amount = $getRate->rate * $getRate->amount;
                            $tradeModel->refer_bonus = $getRate->refer_bonus;
                            $tradeModel->created_by= Auth()->user()->id;
                            $tradeModel->trading_status = 'Pending';

                            if(!empty(Auth()->user()->refer_by))
                                $tradeModel->referer_user_id=Auth()->user()->refer_by;
                            if($tradeModel->save()){
                                $totalAmount+=$tradeModel->total_amount;
                                $totalRfbonus+=$tradeModel->refer_bonus;

                            }

                        }
                        $tradeDescription.=$currency.$tradeModel->amount.' '.$getRate->giftCard->card_name.' x ' .$qty .', ';
                    }

                }
                $tradingModel->trade_descriptions= $tradeDescription;
                $tradingModel->total_amount = $totalAmount;
                $tradingModel->refer_bonus = $totalRfbonus;
               if( $tradingModel->save()) {
                   return $tradingModel->reference_no;
                  // return redirect()->route('user.merchant',['reference'=>$tradingModel->reference_no]);
               }

            }

      /*  }catch (\Throwable $th){
            return response()->json($th->getMessage());
        }
      */


    }

    public function listMerchant(Request $request){
        $merchants = Merchant::all();
        $tradeId = $request->reference;
        return view('user.giftcard.list_merchant',compact('merchants','tradeId'));
    }

    public function sendTradeRequest(Request $request){
        $merchantId = $request->merchantId;
        $tradeId = $request->tradeRef;
        $userId = auth()->user()->id;
        $checkMerchant = DB::table('merchants')->where('access_key',$merchantId)->first();
        if(empty($checkMerchant)){
            return Response::json(
                ['message'=>'Invalid Merchant Please Try Again']
            );
        }
        $checkTrade = DB::table('trade_gift_cards')->where([['reference_no',$tradeId],['user_id',$userId]])->first();
        if(empty($checkTrade)){
            return Response::json(
                ['message'=>'Invalid Trade Please Try Again']
            );
        }
        $checkifExit = TradeRequests::select('id','trade_id')->where('trade_id',$checkTrade->id)->where('request_by',$userId)->where('send_to',$checkMerchant->id)->first();
        if(empty($checkifExit)) {
            $tradeRequest = new TradeRequests();
            $tradeRequest->trade_id = $checkTrade->id;
            $tradeRequest->request_by = $userId;
            $tradeRequest->send_to = $checkMerchant->id;
            $tradeRequest->request_status = 'Pending';
            $tradeRequest->request_status_at = now()->toDateTimeString();

            if ($tradeRequest->save()) {
                // dd($tradeRequest);
                $data = ['requestId' => $tradeRequest->id, 'tradeId' => $tradeRequest->trade_id];
                $this->chat->push('notify' . $checkMerchant->access_key, 'trade-request', $data);

                return Response::json([
                    'message' => 'success',
                    'requestId' => $tradeRequest->id, 'tradeId' => $tradeRequest->trade_id
                ]);
            }
        }else{
            $checkifExit->request_count= $checkifExit->request_count+1;
            $checkifExit->save();
            return Response::json([
                'message' => 'success',
                'requestId' => $checkifExit->id, 'tradeId' => $checkifExit->trade_id
            ]);
        }
    }



    public function tradeChat(){
        $messenger_color = Auth::user()->messenger_color;
        $tradeDetails=null;
        $tradeRequest = TradeRequests::where('request_by',Auth()->user()->id)->get();
        $users = TradeRequests::join('merchants','trade_requests.send_to', '=', 'merchants.id')
            ->where('trade_requests.request_by',Auth()->user()->id)
            ->select('merchants.name','merchants.active_status','merchants.avatar','merchants.email','trade_requests.*')
            //->orderBy('max_created_at', 'desc')
            //->groupBy('trade_requests.id')
            ->paginate(10);
        $usersList = $users->items();

        if (count($usersList) > 0) {
            $contacts = '';
            foreach ($usersList as $user) {

                $contacts .= $this->chat->getContactItemUser($user);
              //  dd($contacts);
            }


        } else {
            $contacts = '<p class="message-hint center-el"><span>Your contact list is empty</span></p>';
        }

        return view('user.giftcard.chat.pages.app', [
            'id' => $id ?? 0,
            'messengerColor' => $messenger_color ? $messenger_color : Chatify::getFallbackColor(),
            'dark_mode' => Auth::user()->dark_mode < 1 ? 'light' : 'dark',
            'tradeDetails'=>null,'tradeRequest'=>$tradeRequest, 'contacts'=>$contacts
        ]);
    }
    public function trading($id)
    {

        $tradeRequest = TradeRequests::where('id',$id)->where('request_by',Auth::user()->id)->first();
       if(empty($tradeRequest)){
           abort(404, 'Item not found');
       }
      //  $fetch = Merchant::where('id', $tradeRequest->request_by)->first();
       // $tradeRequest = TradeRequests::where('id',$id)->where('request_id',Auth::user()->id)->first();
        $tradeDetails = TradingCardDetails::where('trading_id',$tradeRequest->trade_id);
        $messenger_color = Auth::user()->messenger_color;
        $users = TradeRequests::join('merchants','trade_requests.send_to', '=', 'merchants.id')
            ->where('trade_requests.request_by',Auth()->user()->id)->where('trade_requests.request_status')
            ->select('merchants.name','merchants.active_status','merchants.avatar','merchants.email','trade_requests.*')
            //->orderBy('max_created_at', 'desc')
            //->groupBy('trade_requests.id')
            ->paginate(10);
        $usersList = $users->items();

        if (count($usersList) > 0) {
            $contacts = '';
            foreach ($usersList as $user) {

                $contacts .= $this->chat->getContactItemUser($user);
                //  dd($contacts);
            }


        } else {
            $contacts = '<p class="message-hint center-el"><span>Your contact list is empty</span></p>';
        }

        //  echo $id;
        // dd($tradeDetails->get());
        return view('user.giftcard.chat.pages.app', [
            'id' => $id ?? 0,
            'tradeRequest'=>$tradeRequest,
            'tradeDetails'=>$tradeDetails->get(),
            'messengerColor' => $messenger_color ? $messenger_color : Chatify::getFallbackColor(),
            'dark_mode' => Auth::user()->dark_mode < 1 ? 'light' : 'dark','contacts'=>$contacts,
            'clientId'=>Auth::user()->getMerchantAccessKey($tradeRequest->send_to)
        ]);
    }

    /**
     * Get contacts list
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function getTradingList(Request $request)
    {
        //return 'hello';
        // get all users that received/sent message from/to [Auth user]
        /*  $users = TradingMessage::join('users',  function ($join) {
              $join->on('ch_messages.from_id', '=', 'users.id')
                  ->orOn('ch_messages.to_id', '=', 'users.id');
          })
              ->where(function ($q) {
                  $q->where('ch_messages.from_id', Auth::user()->id)
                      ->orWhere('ch_messages.to_id', Auth::user()->id);
              })
              ->where('users.id','!=',Auth::user()->id)
              ->select('users.*',DB::raw('MAX(ch_messages.created_at) max_created_at'))
              ->orderBy('max_created_at', 'desc')
              ->groupBy('users.id')
              ->paginate($request->per_page ?? $this->perPage);
  */
        $chat= new ChatMessenger();
        $users = TradeRequests::join('merchants','trade_requests.send_to', '=', 'merchants.id')
            ->where('trade_requests.request_by',Auth()->user()->id)
            ->select('merchants.name','merchants.active_status','merchants.avatar','trade_requests.*')
            //->orderBy('max_created_at', 'desc')
            //->groupBy('trade_requests.id')
            ->paginate($request->per_page);
        $usersList = $users->items();

        if (count($usersList) > 0) {
            $contacts = '';
            foreach ($usersList as $user) {
                $contacts .= $chat->getContactItemUser($user);
            }
        } else {
            $contacts = '<p class="message-hint center-el"><span>Your contact list is empty</span></p>';
        }

        return Response::json([
            'contacts' => $contacts,
            'total' => $users->total() ?? 0,
            'last_page' => $users->lastPage() ?? 1,
        ], 200);
    }


    /**
     * Fetch data (user, favorite.. etc).
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function tradeRequestDetails(Request $request)
    {
        $id = $request['id'];
        $tradeRequest = TradeRequests::where('id',$id)->where('request_by',Auth::user()->id)->first();

        $fetch = Merchant::where('id', $tradeRequest->send_to)->first();
       // $tradeRequest = TradeRequests::where('id',$id)->where('request_by',Auth::user()->id)->first();
        $tradeDetails = TradingCardDetails::where('trading_id',$tradeRequest->trade_id);
        if($fetch){
            $userAvatar = $this->chat->getUserWithAvatar($fetch)->avatar;
        }
        $tradeDetailsList=null;
        if($tradeDetails->get()){

            $tradeDetailsList .= view('user.giftcard.chat.layouts._trade_details', [
                'user' => $fetch,
                'tradeRequest'=>$tradeRequest,
                'tradeDetails'=>$tradeDetails->get()
            ]);
        }

//dd($tradeDetails->get());
        return Response::json([
            'favorite' => 1,
            'fetch' => $fetch ?? null,
            'user_avatar' => $userAvatar ?? null,
            'tradeRequestDetails'=>$tradeDetailsList
        ]);
    }

    /**
     * fetch [user/group] messages from database
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function fetchTradingConversation(Request $request)
    {
        $id = $request['id'];
        $chat = new ChatMessenger();
        $query = $chat->fetchMessagesQuery($id)->latest();
        $messages = $query->paginate($request->per_page ?? $this->perPage);
        $totalMessages = $messages->total();
        $lastPage = $messages->lastPage();
        $response = [
            'total' => $totalMessages,
            'last_page' => $lastPage,
            'last_message_id' => collect($messages->items())->last()->id ?? null,
            'messages' => '',
        ];

        // if there is no messages yet.
        if ($totalMessages < 1) {
            $response['messages'] ='<p class="message-hint center-el"><span>Say \'hi\' and start messaging</span></p>';
            return Response::json($response);
        }
        if (count($messages->items()) < 1) {
            $response['messages'] = '';
            return Response::json($response);
        }
        $allMessages = null;
        foreach ($messages->reverse() as $message) {
            $allMessages .= $chat->messageCardUser(
                $chat->parseMessage($message)
            );
        }
        $response['messages'] = $allMessages;
        return Response::json($response);
    }

    /**
     * Get shared photos
     *
     * @param Request $request
     * @return JsonResponse|void
     */
    public function sharedPhotos(Request $request)
    {
        $id = $request['user_id'];
        $shared = $this->chat->getSharedPhotos($id);
        $sharedPhotos = null;

        // shared with its template
        for ($i = 0; $i < count($shared); $i++) {
            $sharedPhotos .= view('user.giftcard.chat.layouts.listItem', [
                'get' => 'sharedPhoto',
                'image' => $this->chat->getAttachmentUrl($shared[$i]),
            ])->render();
        }
        // send the response
        return Response::json([
            'shared' => count($shared) > 0 ? $sharedPhotos : '<p class="message-hint"><span>Nothing shared yet</span></p>',
        ], 200);
    }


    /**
     * Send a message to database
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function sendMessage(Request $request)
    {
        $id = $request['id'];
        $tradeRequest = TradeRequests::where('id',$id)->where('request_by',Auth()->user()->id)->first();

      //  $chat = new ChatMessenger();
        // default variables
        $error = (object)[
            'status' => 0,
            'message' => null
        ];
        $attachment = null;
        $attachment_title = null;
        if($tradeRequest) {
            // if there is attachment [file]
            if ($request->hasFile('file')) {
                // allowed extensions
                $allowed_images = $this->chat->getAllowedImages();
                $allowed_files = $this->chat->getAllowedFiles();
                $allowed = array_merge($allowed_images, $allowed_files);

                $file = $request->file('file');
                // check file size
                if ($file->getSize() < $this->chat->getMaxUploadSize()) {
                    if (in_array(strtolower($file->extension()), $allowed)) {
                        // get attachment name
                        $attachment_title = $file->getClientOriginalName();
                        // upload attachment and store the new name
                        $attachment = Str::uuid() . "." . $file->extension();
                        $file->storeAs(config('chatify.attachments.folder'), $attachment, config('chatify.storage_disk_name'));

                    } else {
                        $error->status = 1;
                        $error->message = "File extension not allowed!";
                    }
                } else {
                    $error->status = 1;
                    $error->message = "File size you are trying to upload is too large!";
                }
            }

            if (!$error->status) {
                $message = $this->chat->newMessage([
                    'from_id' => Auth::user()->id,
                    'trading_id' => $tradeRequest->trade_id,
                    'request_id' => $tradeRequest->id,
                    'to_id' => $tradeRequest->send_to,
                    'body' => htmlentities(trim($request['message']), ENT_QUOTES, 'UTF-8'),
                    'attachment' => ($attachment) ? json_encode((object)[
                        'new_name' => $attachment,
                        'old_name' => htmlentities(trim($attachment_title), ENT_QUOTES, 'UTF-8'),
                    ]) : null,
                ]);
                $messageData = $this->chat->parseMessage($message);
                if (Auth::user()->id != $tradeRequest->send_to) {
                    $this->chat->push("private-chatify." . Auth()->user()->getMerchantAccessKey($tradeRequest->send_to), 'messaging', [
                        'from_id' => Auth::user()->access_key,
                        'request_id' => $request['id'],
                        'to_id' => Auth::user()->getMerchantAccessKey($tradeRequest->send_to),
                        'message' => $this->chat->messageCardUser($messageData, true)
                    ]);
                }
            }

            // send the response
            return Response::json([
                'status' => '200',
                'error' => $error,
                'message' => $this->chat->messageCardUser(@$messageData),
                'tempID' => $request['temporaryMsgId'],
            ]);
        }else{
            $error->status = 1;
            $error->message = "Invalid Trade!";

            return Response::json([
                'status' => '200',
                'error' => $error,
                'message' => $this->chat->messageCardUser([]),
                'tempID' => $request['temporaryMsgId'],
            ]);
        }
    }

    /**
     * Make messages as seen
     *
     * @param Request $request
     * @return JsonResponse|void
     */
    public function seen(Request $request)
    {
       // $chat = new ChatMessenger();

        // make as seen
        $seen = $this->chat->makeSeen($request['id']);
        // send the response
        return Response::json([
            'status' => $seen,
        ], 200);
    }

    /**
     * Update user's list item data
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function updateTradeList(Request $request)
    {

        $id =$request['user_id'];
        // Get user data
        $user =  TradeRequests::join('merchants','trade_requests.request_by', '=', 'merchants.id')
            ->where('trade_requests.id',$id)
            ->select('merchants.name','merchants.active_status','merchants.avatar','trade_requests.*')->first();

        if(!$user){
            return Response::json([
                'message' => 'User not found!',
            ], 401);
        }
        $contactItem = $this->chat->getContactItemUser($user);

        // send the response
        return Response::json([
            'contactItem' => $contactItem,
        ], 200);
    }

    /**
     * Set user's active status
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function setActiveStatus(Request $request)
    {
        $activeStatus = $request['status'] > 0 ? 1 : 0;
        $status = User::where('id', Auth::user()->id)->update(['active_status' => $activeStatus]);
        return Response::json([
            'status' => $status,
        ], 200);
    }



    /**
     * This method to make a links for the attachments
     * to be downloadable.
     *
     * @param string $fileName
     * @return \Symfony\Component\HttpFoundation\StreamedResponse|void
     */
    public function download($fileName)
    {
        $filePath = config('chatify.attachments.folder') . '/' . $fileName;
        if ($this->chat->storage()->exists($filePath)) {
            return $this->chat->storage()->download($filePath);
        }
        return abort(404, "Sorry, File does not exist in our server or may have been deleted!");
    }


    public function myTrades(){

       $trades= TradeGiftCard::where('user_id',auth()->id())->latest()->paginate(15);
       return view('user.giftcard.my_trades', compact('trades'));

    }

    public function tradeTransactions(){
        $txnTrades = TradingCardDetails::where('created_by',auth()->id())->latest()->paginate(20);
        return view('user.giftcard.transaction',compact('txnTrades'));
    }










}
