<?php

namespace App\Http\Controllers\Customer;

use App\Http\Controllers\Controller;
use App\Models\Contact;
use App\Models\Exception;
use App\Models\Label;
use App\Models\MessageLog;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class ChatController extends Controller
{
    public function index()
    {
        $customer = auth('customer')->user();
        if($customer->type=='staff'){
            $customer=$customer->staff;
        }

        $no_of_data = 20;
        $from_numbers = $customer->message_logs()->select('from AS to', DB::raw('MAX(updated_at) as created_at'))->where('type', 'inbox')->orderByDesc('created_at')->groupBy('from')->limit($no_of_data)->get();

        $data['to_numbers'] = $from_numbers->sortByDesc('created_at')->pluck('to')->unique();
        $createdAt=[];
        foreach ($from_numbers as $number){
            $createdAt[$number->to]=$number->created_at;
        }
        $data['devices'] = $customer->devices()->where('status', 'active')->where('device_type', 'device')->get();
        $data['chat_responses'] = $customer->chat_responses()->where('status', 'active')->get();
        $data['labels']=$customer->labels()->where('status','active')->get();
        $data['createdAt']=$createdAt;
        return view('customer.chat.index', $data);
    }
    public function get_numbers(Request $request)
    {

        $page_no = $request->page;
        if(!$page_no) abort(404);

        $no_of_data = 20;
        $offset = ($page_no * $no_of_data) - $no_of_data;

        $customer = auth('customer')->user();
        if($customer->type=='staff'){
            $customer=$customer->staff;
        }

        $devices= $customer->devices()->where('status', 'active')->where('device_type', 'device')->pluck('device_unique_id');

        $search = $request->search;
        $all_inbox_messages = $customer->message_logs()->select('from AS to','body', DB::raw('MAX(updated_at) as created_at'),DB::raw('MAX(id) as id'))->where('type', 'inbox')->whereIn('device_unique_id', $devices)->groupBy('from');
        $all_sent_messages = $customer->message_logs()->select('to','body', DB::raw('MAX(updated_at) as created_at'),DB::raw('MAX(id) as id'))->where('type', 'sent')->whereIn('device_unique_id', $devices)->groupBy('to');

        if ($request->type=='old'){
            $all_inbox_messages = $all_inbox_messages->orderBy('created_at','asc');
            $all_sent_messages = $all_sent_messages->orderBy('created_at','asc');
        }else{
            $all_inbox_messages = $all_inbox_messages->orderByDesc('created_at');
            $all_sent_messages = $all_sent_messages->orderByDesc('created_at');
        }
        if ($search){
            $contacts = Contact::where('number', 'like', '%' . $search . '%')->orWhere('first_name', 'like', '%' . $search . '%')->orWhere('last_name', 'like', '%' . $search . '%')->pluck('number');
            $all_inbox_messages = $all_inbox_messages->whereIn('from', $contacts)->where('type','inbox');
            $all_sent_messages = $all_sent_messages->whereIn('to', $contacts)->where('type','sent');
        }

        if($request->date){
            $dates = explode('-',$request->date);
                $fromDate = isset($dates) && isset($dates["0"]) ? str_replace(' ', '', $dates["0"]) : now();
                $toDate = isset($dates) && isset($dates["1"]) ? str_replace(' ', '', $dates["1"]) : now();
                $fromDate = new \DateTime($fromDate);
                $toDate = new \DateTime($toDate);
            if($fromDate != $toDate) {
                $all_inbox_messages = $all_inbox_messages->whereBetween('updated_at', [$fromDate, $toDate]);
                $all_sent_messages = $all_sent_messages->whereBetween('updated_at', [$fromDate, $toDate]);
            }
        }
        if($request->label_id){

            $label = Label::where('id', $request->label_id)->first();
            if (!$label){
                return response()->json(['status'=>'failed','message'=>'Invalid Label']);
            }
            $contacts = $customer->contacts()->where('label_id', $label->id)->pluck('number')->unique();
            $all_inbox_messages = $all_inbox_messages->whereIn('from', $contacts);
            $all_sent_messages = $all_sent_messages->whereIn('to', $contacts);
        }

        $all_sent_messages = $all_sent_messages->limit($no_of_data)->offset($offset)->get();
        $all_inbox_messages = $all_inbox_messages->limit($no_of_data)->offset($offset)->get();
        $from_numbers=collect([]);

        $allNumbers=[];
        foreach ($all_sent_messages as $item){
            if(!isset($allNumbers[$item->to])) {
                $from_numbers->push(['to'=>$item->to,'created_at'=>$item->created_at]);
                $allNumbers[$item->to] = [
                    'to' => $item->to,
                    'body' => $item->body,
                    'id' => $item->id,
                    'created_at' => $item->created_at,
                ];
            }
        }
        foreach ($all_inbox_messages as $item){
            if(!isset($allNumbers[$item->to])) {
                $from_numbers->push(['to'=>$item->to,'created_at'=>$item->created_at]);
                $allNumbers[$item->to] = [
                    'to' => $item->to,
                    'body' => $item->body,
                    'id' => $item->id,
                    'created_at' => $item->created_at,
                ];
            }
        }

        $from_numbers=$from_numbers->sortByDesc('created_at')->pluck('to')->toArray();
        $createdAt=[];
        foreach ($allNumbers as $number){
                $createdAt[$number['to']] = $number['created_at'];
        }
        $allChats = $customer->message_logs()->whereIn('to', $from_numbers)
            ->orWhereIn('from',$from_numbers)
            ->orderByDesc('created_at')
            ->get(['body', 'to', 'from', 'created_at', 'updated_at']);

        $find_chat=[];

        foreach ($allChats as $key=>$chat){
            $find_chat[$chat->from]=$chat->body;
        }
        foreach ($allChats as $key=>$chat){
            $find_chat[$chat->to]=$chat->body;
        }

        $numbersArray=[];
        foreach ($from_numbers as $number){
            $numbersArray[]= '+'.str_replace('+','',$number);
        }
        $findContacts = $customer->contacts()->whereIn('number', $from_numbers)->orWhereIn('number', $numbersArray)->orderBy('created_at')->get();
        $findContact=[];
        foreach ($findContacts as $contact) {
            $findContact[$contact->number] = [
                'label' => isset($contact->label) ? ucfirst(mb_strimwidth($contact->label->title, 0, 7, '..')) : '',
                'color' => isset($contact->label) ? $contact->label->color : '',
                'full_name' => isset($contact->full_name)?$contact->full_name:''
            ];
        }

        $data=[];
        foreach($from_numbers as $key=>$from_number){
            $data[$key]['full_name']= isset($findContact[$from_number]) && isset($findContact[$from_number]['full_name'])?$findContact[$from_number]['full_name']:'';
            $data[$key]['number']=$from_number;
            $data[$key]['created_at']=isset($createdAt) && isset($createdAt[$from_number])?formatDate($createdAt[$from_number]):'';
            $data[$key]['label']= isset($findContact[$from_number]) && isset($findContact[$from_number]['label'])?$findContact[$from_number]['label']:'';
            $data[$key]['color']=  isset($findContact[$from_number]) && isset($findContact[$from_number]['color'])?$findContact[$from_number]['color']:'';
            $data[$key]['body']=isset($find_chat[$from_number])?$find_chat[$from_number]:'';
        }

        $labels=$customer->labels()->where('status','active')->get();

        if($from_numbers && count($from_numbers) > 0){
            return response()->json(['status'=>'success','data'=>['numbers'=>$data,'labels'=>$labels,'page'=>$page_no+1]]);
        }else{
            return response()->json(['status'=>'success','data'=>['numbers'=>[],'page'=>'end']]);
        }
    }

    public function label_update(Request $request)
    {
        $request->validate([
            'number' => 'required',
            'label' => 'required'
        ]);

        $contact = Contact::where('number', $request->number)->orWhere('number', str_replace('+', '', $request->number))->first();
        $customer = auth('customer')->user();
        if($customer->type=='staff'){
            $customer=$customer->staff;
        }
        if(!$contact){
            return response()->json(['status' => 'failed']);
        }
        $label = $customer->labels()->where('id', $request->label)->where('status','active')->first();
        if(!$label){
            return response()->json(['status' => 'failed','message'=>'This is not a valid label']);
        }
        $contact->label_id = $label->id;
        $contact->update();

        return response()->json(['status' => 'success', 'message' => 'Label successfully updated']);
    }


    public function get_data(Request $request)
    {
        $customer = auth('customer')->user();
        if($customer->type=='staff'){
            $customer=$customer->staff;
        }

        $no_of_data = 20;
        $chats = $customer->message_logs()->where('to', $request->number)->orWhere('from',$request->number)->orderByDesc('updated_at')->limit($no_of_data)->get(['body', 'to', 'from','type', 'created_at', 'updated_at'])->toArray();

        $contact_id = $customer->contacts()->where('number', $request->number)->first();

        if($contact_id){
            $address = isset($contact_id->address)?$contact_id->address:'';
            $zillowUrl='https://www.zillow.com/homes/recently_sold/'.str_replace(' ','-', $contact_id->address);
            $exception = Exception::where('number', $contact_id->number)->orWhere('number', str_replace('+', '', $contact_id->number))->first();
            $label = $customer->labels()->where('id', $contact_id->label_id)->where('status','active')->first();
            return response()->json(['status' => 'success', 'data' => ['zillow_url'=>$zillowUrl,'address'=>$address,'number'=>$exception,'id' => $contact_id->id,'color'=>isset($label)?$label->color:'' ,'label' => isset($label)?$label->id:'','name'=>$contact_id->full_name,'messages' => $chats,'page'=>count($chats)<$no_of_data?'end':2]]);
        }
        return response()->json(['status' => 'success', 'data' => ['id' => null, 'label' => null, 'messages' => $chats,'page'=>count($chats)<$no_of_data?'end':2]]);
    }

    public function get_chats(Request $request){
        $chats_no = $request->chats;
        if(!$chats_no) abort(404);
        $customer = auth('customer')->user();
        if($customer->type=='staff'){
            $customer=$customer->staff;
        }

        $no_of_data = 20;
        $offset = ($chats_no * $no_of_data) - $no_of_data;

        $chats = $customer->message_logs()->where('to', $request->number)->orWhere('from',$request->number)->orderByDesc('updated_at')->offset($offset)->limit($no_of_data)->get(['body', 'to', 'from','type', 'created_at', 'updated_at'])->toArray();

        if($chats){
                return response()->json(['status' => 'success', 'data' => ['messages' => $chats,'page'=>count($chats)<$no_of_data?'end':$chats_no+1]]);
        }else{
            return response()->json(['status' => 'success', 'data' => ['messages' => [],'page'=>'end']]);
        }
    }

    public function exception(Request $request){
        $customer = auth('customer')->user();
        if($customer->type=='staff'){
            $customer=$customer->staff;
        }

        $label = $customer->labels()->where('title', 'new')->first();
        if (!$label) {
            $label = new Label();
            $label->title = 'new';
            $label->status = 'active';
            $label->customer_id = $customer->id;
            $label->color = 'red';
            $label->save();
        }

        if ($request->check_add_contact){
            $contact = new Contact();
            $contact->customer_id = $customer->id;
            $contact->number = $request->number;
            $contact->label_id = $label->id;
            $contact->save();
        }
        if ($request->type=='add') {
            $exception = new Exception();
            $exception->number = $request->number;
            $exception->customer_id = $customer->id;
            $exception->save();
            return response()->json(['status' => 'success','type'=>$request->type]);
        }elseif ($request->type=='delete'){
            $exception = Exception::where('number',$request->number)->orWhere('number', str_replace('+', '', $request->number))->where('customer_id', auth('customer')->user()->id)->first();
            if($exception){
                $exception->delete();
            }
            return response()->json(['status' => 'success','type'=>$request->type]);
        }

    }

    public function addNewContact(Request $request){
        $customer = auth('customer')->user();
        if($customer->type=='staff'){
            $customer=$customer->staff;
        }

        $label = $customer->labels()->where('id', $request->label)->where('status','active')->first();
        if(!$label){
            return response()->json(['status' => 'failed','message'=>'This is not a valid label']);
        }
        $preContact = Contact::where('number', $request->number)->orWhere('number', str_replace('+', '', $request->number))->first();
        if ($preContact) {
            $preContact->label_id = $label->id;
            $preContact->save();
            return response()->json(['status' => 'success', 'message' => 'Contact Successfully added']);
        }
            $contact = new Contact();
            $contact->customer_id = $customer->id;
            $contact->number = $request->number;
            $contact->label_id = $label->id;
            $contact->save();
        return response()->json(['status'=>'success','message'=>'Contact Successfully added']);
    }

    public function sendContactInfo(Request $request){
        if (!$request->number || !$request->url){
            return response()->json(['status'=>'failed', 'message'=>'Invalid Request']);
        }
        $requestNumber= '+'.str_replace('+','',trim($request->number));

        $contact = Contact::select('first_name', 'last_name', 'number', 'email', 'label_id', 'city', 'state', 'zip_code', 'note', 'address', 'company')
            ->where('number', $requestNumber)->first();
        if (!$contact) {
            return response()->json(['status' => 'failed', 'message' => 'Invalid number']);
        }
        $message_logs = MessageLog::select('to','from','body','type','status', 'created_at', 'updated_at')->where('to', $contact->number)->orWhere('from', $contact->number)->orderByDesc('updated_at')->get();

        $contactData=[
            'first_name'=>$contact->first_name,
            'last_name'=>$contact->last_name,
            'number'=>$contact->number,
            'email'=>$contact->email,
            'city'=>$contact->city,
            'state'=>$contact->state,
            'zip_code'=>$contact->zip_code,
            'address'=>$contact->address,
            'note'=>$contact->note,
            'company'=>$contact->company,
            'label'=>null
        ];
        if (isset($contact->label)){
            $contactData['label']=[
                'title'=>$contact->label->title,
                'color'=>$contact->label->color,
            ];
        }
        $messageData=[];
        foreach($message_logs as $key=>$message_log){
            $messageData[$key]['from']=$message_log->from;
            $messageData[$key]['to']=$message_log->to;
            $messageData[$key]['body']=$message_log->body;
            $messageData[$key]['type']=$message_log->type;
            $messageData[$key]['status']=$message_log->status;
            $messageData[$key]['created_at']=$message_log->created_at->toDateTimeString();
            $messageData[$key]['updated_at']=$message_log->updated_at->toDateTimeString();
        }

        $data=[
            'contact'  =>$contactData,
            'messages'  =>$messageData,
        ];

        $client=new \GuzzleHttp\Client(['verify' => false ]);
        if ($request->url_method=='post'){
            $client->post($request->url,[
                'form_params'=>$data
            ]);
        }else {
            $client->get($request->url, [
                'query' => $data
            ]);
        }
        return response()->json(['status'=>'success']);
    }
    // public function wadevice (){
    //     $customer = auth('customer')->user();
    //     if($customer->type=='staff'){
    //         $customer=$customer->staff;
    //     }

    //     $no_of_data = 20;
    //     $from_numbers = $customer->message_logs()->select('from AS to', DB::raw('MAX(updated_at) as created_at'))->where('type', 'inbox')->orderByDesc('created_at')->groupBy('from')->limit($no_of_data)->get();

    //     $data['to_numbers'] = $from_numbers->sortByDesc('created_at')->pluck('to')->unique();
    //     $createdAt=[];
    //     foreach ($from_numbers as $number){
    //         $createdAt[$number->to]=$number->created_at;
    //     }
    //     $data['devices'] = $customer->devices()->where('status', 'active')->where('device_type', 'whatsapp')->get();
    //     $data['chat_responses'] = $customer->chat_responses()->where('status', 'active')->get();
    //     $data['labels']=$customer->labels()->where('status','active')->get();
    //     $data['createdAt']=$createdAt;
    //     return view('customer.wa_chat.index',$data);
    // }
}
