<?php

namespace App\Http\Controllers\Customer;

use App\Events\SendMail;
use App\Http\Controllers\Controller;
use App\Models\Contact;
use App\Models\ContactGroup;
use App\Models\CustomerPlan;
use App\Models\Device;
use App\Models\Number;
use App\SmsProvider\SendSMS;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class ComposeController extends Controller
{
    public function index(Request $request)
    {
        $user = auth('customer')->user();
        if ($user->type == 'staff') {
            $user = $user->staff;
        }
        $data['draft'] = $user->drafts()->where('id', $request->draft)->first();
        $data['devices'] = $user->devices()->where('status', 'active')->where('device_type','device')->get();
        $data['wadevices'] = $user->devices()->where('status', 'active')->where('device_type','whatsapp')->get();
        $usersToGroups = [];
        $usersToContacts = [];
        foreach ($user->active_groups as $group) {
            $usersToGroups[] = ['value' => $group->name, 'id' => $group->id, 'type' => 'group'];
        }
        foreach ($user->contacts()->limit(10000)->get() as $contact) {
            $usersToContacts[] = ['value' => isset($contact->first_name) ? $contact->number . ' (' . $contact->first_name . ' ' . $contact->last_name . ')' : $contact->number, 'id' => $contact->id, 'type' => 'contact'];
        }


        $data['users_to_contacts'] = $usersToContacts;
        $data['users_to_groups'] = $usersToGroups;

        return view('customer.smsbox.compose', $data);
    }

    public function sentCompose(Request $request)
    {
        if ($request->device_type == 'whatsapp') {
            $request->validate([
                'device_id' => 'required',
                'to_numbers' => 'required|array',
                'body' => 'required',
            ]);
        } else {
            $request->validate([
                'device_id' => 'required',
                'to_numbers' => 'required|array',
                'body' => 'required',
                'subscriber_id' => 'required',
            ]);
        }
        $customer = auth('customer')->user();
        if ($customer->type == 'staff') {
            $customer = $customer->staff;
        }
        $currentPlan = $customer->currentPlan();
        if (isset($currentPlan->renew_date) && $currentPlan->renew_date < Carbon::now()){
            return back()->with('fail', 'Your Plan has expired');
        }
        $user = $customer;
        $device = $user->activeDevices($request->device_id)->first();
        if (!$device) {
            return back()->with('fail', 'Device has been removed or inactive');
        }

        $sent = $customer->message_logs()->where('type','sent')->whereDate('created_at', Carbon::today())->count();
        $plan = $user->currentPlan();
        if (($sent + count($request->to_numbers)) > $plan->daily_send_limit) {
            return back()->withErrors(['message' => 'Your have extended your daily send limit']);
        }

        $messageFiles = [];
        if ($request->mms_files) {
            foreach ($request->mms_files as $key => $file) {
                $messageFiles[] = $fileName = time() . $key . '.' . $file->extension();
                $file->move(public_path('uploads/'), $fileName);
            }
            $request['message_files'] = json_encode($messageFiles);
        }

        if (isset($request->isSchedule)) {
            $sd = Carbon::createFromTimeString($request->schedule);
            $request['schedule_datetime'] = $sd;
        } else {
            $request['schedule_datetime'] = now();
        }
        $allToNumbers = [];
        $allGroupIds = [];
        $allContactIds = [];

        foreach ($request->to_numbers as $item) {
            $number = (array)json_decode($item);
            if (isset($number['type']) && isset($number['id'])) {
                if ($number['type'] == 'contact') {
                    $allContactIds[] = $number['id'];
                } elseif ($number['type'] == 'group') {
                    $allGroupIds[] = $number['id'];
                }
            } else {
                $allToNumbers[] = $item;
            }
        }

        $contactNumbers = Contact::select('id', 'number')->whereIn('id', $allContactIds)->get();
        $groupNumbers = ContactGroup::with('contact')->whereIn('group_id', $allGroupIds)->get();

        foreach ($contactNumbers as $cn) {
            $allToNumbers[] = trim($cn->number);
        }
        foreach ($groupNumbers as $gn) {
            $allToNumbers[] = trim($gn->contact->number);
        }

        $allToNumbers = array_unique($allToNumbers);

        $request['to_numbers'] = $allToNumbers;
        $request['numbers'] = json_encode(['from' => $device->id, 'to' => $allToNumbers,'subscriber_id'=>$request->subscriber_id]);
        $request['type'] = 'sent';

        $current_plan = $customer->currentPlan();
        if (!$current_plan)
            return back()->with('fail', 'Customer doesn\'t have any plan right now');

        //subtracting one sms TODO:: will need to count text and sub that also calculate today send
        $pre_available_sms = $current_plan->daily_send_limit;
        $new_available_sms = $pre_available_sms - count($allToNumbers);

        //if not enough sms then return
        if ($new_available_sms < 0)
            return redirect()->back()->with('fail', 'Doesn\'t have enough sms');

        $selectedSimData=null;
        if ($request->device_type == 'device') {
            if ($device->sim_info) {
                $simInfo = json_decode($device->sim_info);
                foreach ($simInfo as $item) {
                    $simData = explode(':', $item);
                    if (isset($simData[1]) && $simData[1] == $request->subscriber_id) {
                        $selectedSimData = $item;
                        break;
                    }
                }
            }
            if (!$selectedSimData)  return redirect()->back()->with('fail', 'Invalid SIM info. Please logout from mobile App and scan the QR Code again');
        }else{
            $selectedSimData=$device->id;
        }

        DB::beginTransaction();
        try {
            if ($request->device_type == 'whatsapp') {
                $request['subscriber_id']=0;
            }
            $newMessage = $customer->messages()->create($request->all());

            $sms_queue = [];
            foreach ($request->to_numbers as $to) {
                $to=str_replace('"','',$to);
                $newMessageFiles = null;
                if ($messageFiles) {
                    $newMessageFiles = $messageFiles;

                    array_walk($newMessageFiles, function (&$value, $index) {
                        $value = asset('uploads/' . $value);
                    });
                }
                $sms_queue[] = [
                    'message_id' => $newMessage->id,
                    'subscriber_id' => $request->subscriber_id,
                    'sim_info' => $selectedSimData,
                    'from' => $device->id,
                    'device_unique_id' => $device->device_unique_id,
                    'to' => $to,
                    'schedule_datetime' => $request->schedule_datetime,
                    'body' => $request->body,
                    'created_at' => now(),
                    'updated_at' => now(),
                    'type' => 'sent',
                    'send_type' => $request->device_type == 'whatsapp'?'whatsapp':'device',
                ];

            }

            $customer->sms_queues()->createMany($sms_queue);
            $customer->message_logs()->createMany($sms_queue);

            DB::commit();
            if (!$request->ajax()) {
                return back()->with('success', 'Message queued successfully');
            } else {
                return response()->json(['status' => 'success', 'message' => 'Message queued successfully']);
            }
        } catch (\Exception $ex) {
            Log::error($ex);
            DB::rollBack();
            return back()->with('fail', $ex->getMessage());
        }
    }

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

        $data['queuesList'] =$customer->sms_queues()->whereNotNull('schedule_datetime')->whereNull('delivered_at')->orderBy('created_at', 'desc')->paginate(10);
        return view('customer.smsbox.queue', $data);
    }
    public function overview()
    {
        $user= auth('customer')->user();
        if($user->type=='staff'){
            $user=$user->staff;
        }
        $data['devices']  =$user->devices()->select('id','name','sim_info')->get();
        return view('customer.smsbox.overview',$data);
    }
    public function overview_get_data(Request $request)
    {
        $user = auth('customer')->user();
        if ($user->type == 'staff') {
            $user = $user->staff;
        }

        $overview = $user->message_logs()->orderByDesc('updated_at');

            if ($request->status && $request->type == 'sent'){
                $overview = $overview->where('status', $request->status);
            }
            if ($request->type && $request->type == 'trash') {
                $overview = $overview->onlyTrashed();
            } else if ($request->type) {
                $overview = $overview->where('type', $request->type);
            }
            if($request->type && $request->type=='draft'){
                $overview = $overview->where('type', $request->type);
            }

            if ($request->from_date && $request->to_date) {
               $from_date = new Carbon($request->from_date);
               $to_date = new Carbon($request->to_date);
               $overview = $overview->whereBetween('created_at', [$from_date, $to_date]);
            }

            if($request->select_device && $request->sim_name && $request->type == 'sent'){
                $overview = $overview->where('from',$request->select_device)->where('sim_info',$request->sim_name);
            }


        if ($request->type == 'draft'){
            return datatables()->of($overview)
                ->addColumn('updated_at', function ($q) {
                    return "<a href='" . route('customer.smsbox.compose', ['draft'=>$q->id]) . "'>".formatDate($q->updated_at)."</a>";
                })
                ->addColumn('to', function ($q) {
                    $draftNumbers = json_decode($q->numbers)->to;
                    if ($draftNumbers){
                        $draftNumbers = json_decode($q->numbers)->to;
                        $count=count($draftNumbers);
                        $text=$count>=100?' and more '.($q->contacts()->count()-$count):'';
                        $draftTONumbers = "<div class='show-more' style='max-width: 500px;white-space: pre-wrap'>" . implode(", ", $draftNumbers).$text. " </div>";
                    }else{
                        $draftTONumbers = '';
                    }

                    return $draftTONumbers;
                })
                ->addColumn('from', function ($q) {
                    $draftFromNumbers = json_decode($q->numbers)->from;
                    return $draftFromNumbers;
                })
                ->addColumn('type', function ($q) {
                    $draftType = null;
                    return $draftType;
                })
                ->addColumn('status', function ($q) {
                    $draftStatus = null;
                    return $draftStatus;
                })
                ->addColumn('action', function ($q) {
                    return '<button class="btn btn-sm btn-danger" data-message="Are you sure you want to delete this draft?"
                                        data-action=' . route('customer.smsbox.draft.delete', ['id'=>$q]) . '
                                        data-input={"_method":"post"}
                                        data-toggle="modal" data-target="#modal-confirm">Delete</button>';
                })
                ->rawColumns(['action','updated_at','to'])
                ->toJson();
        }else{
            return datatables()->of($overview)
                ->addColumn('updated_at', function ($q) {
                    return formatDate($q->updated_at);
                })
                ->addColumn('from', function ($q) {
                    if($q->type=='sent'){
                        return $q->send_device->full_name;
                    }
                    $name='';
                    $contact=Contact::where('number',$q->to)->orWhere('number', $q->from)->first();
                    if($contact){
                        $name=' ('.$contact->full_name.')';
                    }
                    return $q->from.$name;
                })
                ->addColumn('to', function ($q) {
                    if($q->type=='inbox'){
                        return $q->received_device->full_name;
                    }
                    $name='';
                    $contact=Contact::where('number',$q->to)->orWhere('number', $q->to)->first();
                    if($contact){
                        $name=' ('.$contact->full_name.')';
                    }
                    return $q->to.$name;
                })
                ->addColumn('body', function ($q) {
                   return "<div class='show-more' style='max-width: 500px;white-space: pre-wrap'>" .$q->body . " </div>";
                })
                ->addColumn('action', function ($q) {
                    return '<button class="btn btn-sm btn-danger" data-message="Are you sure you want to delete this message?"
                                        data-action=' . route('customer.smsbox.overview.data.delete', ['id'=>$q]) . '
                                        data-input={"_method":"delete"}
                                        data-toggle="modal" data-target="#modal-confirm">Delete</button>';
                })
                ->rawColumns(['action','body'])
                ->toJson();
        }

    }

    public function overview_data_delete(Request $request)
    {
        $request->validate([
            'id'=>'required'
        ]);
        $ids=explode(',', $request->id);
        $user = auth('customer')->user();
        if ($user->type == 'staff') {
            $user = $user->staff;
        }

        $messageLogs=$user->message_logs()->whereIn('id',$ids)->get();
        foreach($messageLogs as $log){
            if($log->type=='sent'){
                $user->sms_queues()->where(['message_id'=>$log->message_id,'from'=>$log->from,'to'=>$log->to,'device_unique_id'=>$log->device_unique_id])->delete();
            }
        }

        $user->message_logs()->whereIn('id',$ids)->delete();
        return back()->with('success', 'Message successfully moved to trash');
    }
}
