<?php
namespace App\Http\Controllers\Ads;


use App\Audience;
use App\EmailJob;
use App\Http\Controllers\Controller;
use App\SmsImage;
use App\Tools\SmsTools;
use App\Tools\TMNTools;
use App\UserJob;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
use Maatwebsite\Excel\Facades\Excel;

// centralized ads system:
// contact damian [adamian@npontu.com] for explanation if any. thanks
class AdvertController extends Controller
{
    private $tool;
    public function __construct()
    {
        $this->tool = new TMNTools();
    }

    // send bulk sms
    public function send_bulk_sms(Request $request)
    {
        $step   = 1;
        $target = Audience::findOrFail($request->route('id'));

        if ($step == 1 && strtoupper($request->getMethod()) == 'GET')
        {
            if ($request->session()->has('bulk_sms_data'))
                $request->session()->forget('bulk_sms_data');
            if ($request->session()->has('alert'))
                $request->session()->forget('alert');
        }

        if (strtoupper($request->method()) == 'POST')
        {
            $_user  = \Auth::user();
            $credit = $_user->credit;
            $step   = $request->get('step', 1);
            if ($step == 1)
            {
                //validate the request
                $this->validate($request, [
                    'sender_id' => 'required|max:11',
                    'schedule_date' => 'present',
                    'message_content' => 'required',
                    'name' => 'required',
                    'image_upload' => 'image'
                ]);

                $highestRow         = 0;
                $processed_msisdn   = [];
                $dupplicated_msisdn = [];
                $price              = 0.0;
                $file               = $this->file($target->people(), 'sms');

                try 
                {
                    Excel::load($file, function ($reader) use (&$highestRow, &$processed_msisdn, &$dupplicated_msisdn, &$price, &$_user)
                    {
                        $objExcel = $reader->getExcel();
                        $sheet = $objExcel->getSheet(0);
                        $highestRow = $sheet->getHighestRow();
                        $highestColumn = $sheet->getHighestColumn();

                        //check for duplicated
                        for ($row = 1; $row <= $highestRow; $row++)
                        {
                            try 
                            {
                                //  Read a row of data into an array
                                $rowData = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row, NULL, TRUE, FALSE);
                                $number = $rowData[0][0];
                                $msisdn = SmsTools::msisdn_prep(preg_replace('/\D/', '', $number));
                                $msisdn = trim($msisdn);
                                // fix issue of incorrect recipients
                                if ($msisdn != null)
                                {
                                    if (in_array($msisdn, $processed_msisdn)) {
                                        array_push($dupplicated_msisdn, $msisdn);
                                        continue;
                                    }
                                    $network = SmsTools::get_msisdn_network($_user, $msisdn);
                                    $price += (float)$network['sms_price'];
                                    array_push($processed_msisdn, $msisdn);
                                }
                            } 
                            catch (\Exception $e) {}
                        }
                    });
                } 
                catch (\Exception $e) 
                {
                    throw $e;
                    return Redirect::back()->withInput()->withErrors(array('file_upload' => 'Error! Your excel file is invalid!'));
                }

                // get data for step 2
                $new_msg_text   = preg_replace(array('/\r\n/'), array("\n"), trim($request->get('message_content', '')));
                $no_chars       = strlen($new_msg_text);
                $no_pages       = SmsTools::no_pages($no_chars);
                $cost           = $no_pages * $price;

                // cost of sending one msg with this no_pages to one person
                $nummsisdn = count($processed_msisdn);
                $tot_cost = $cost;

                $curr_bal       = $credit->new_bal;
                $credit_used    = $credit->credit_used;

                $rem_sms    = floor(@($curr_bal / $cost) === false ? 0 : @($curr_bal / $cost));
                //remaining sms user can send

                $counter    = floor($rem_sms / $no_pages);
                $some_cost  = $cost * $counter;

                $price_per_sms  = $cost;
                $recipients     = $nummsisdn;
                $total_price    = $tot_cost;
                $credit_available = $curr_bal;

                $imgId = null;

                //update image if image exist
                if (!empty($request['image_upload']))
                {
                    if ($request->file('image_upload')->isValid())
                    {
                        $current_filename = $request->file('image_upload')->getClientOriginalName();
                        $fileMimeType = $request->file('image_upload')->getMimeType();

                        $destinationPath = storage_path() . DIRECTORY_SEPARATOR. 'uploads' . DIRECTORY_SEPARATOR;
                        $fileName = $_user->username. '_' . $current_filename;
                        $request->file('image_upload')->move($destinationPath, $fileName);
                        $full_path = $destinationPath . $fileName;
                        while(1)
                        {
                            $imgId = uniqid();
                            if (empty(SmsImage::find($imgId)))
                                break;
                        }
                        $_user->sms_images()->create([
                            'path' => $full_path,
                            'file_name' => $current_filename,
                            'mime_type' => $fileMimeType,
                            'id' => $imgId
                        ]);
                    }
                    else
                    {
                        return Redirect::back()->withInput()->withErrors(['image_upload' => 'Sorry, The file upload failed!']);
                    }
                }

                $msg = $new_msg_text;
                if (!empty($imgId))
                {
                    $sms_msg_url = route('sms_image', ['id'=>$imgId]);
                    $msg = $new_msg_text."\n".$sms_msg_url;
                }

                //store user input in the new session data
                session(['bulk_sms_data' =>
                    [
                        'sender_id'         => $request->get('sender_id'),
                        'message_content'   => $msg,
                        // 'price_per_sms' => $price_per_sms,
                        'recipients'        => $recipients,
                        'total_price'       => $total_price,
                        'credit_available'  => $credit_available,
                        'path'              => $file,
                        'schedule_date'     => Carbon::parse($request->get('schedule_date')),
                        'name'              => $request->get('name'),
                        'duplicated'        => count($dupplicated_msisdn)
                    ]
                ]);
                $step = 2;
            }
            else if ($step == 2) // process for step 2
            {
                //check if next button was pressed
                if($request->has('submit'))
                {
                    $no_chars   = strlen(session('bulk_sms_data')['message_content']);
                    $sender     = session('bulk_sms_data')['sender_id'];
                    $nummsisdn  = session('bulk_sms_data')['recipients'];
                    $msgs       = session('bulk_sms_data')['message_content'];
                    $path       = session('bulk_sms_data')['path'];
                    $name       = session('bulk_sms_data')['name'];
                    $cost       = session('bulk_sms_data')['total_price'];

                    $no_pages = SmsTools::no_pages($no_chars);

                    $price = $credit->price;
                    $tot_cost = $cost;

                    $curr_bal = $credit->new_bal;

                    //remaining sms user can send
                    if (isset(session('bulk_sms_data')['schedule_date'])
                        && !empty(session('bulk_sms_data')['schedule_date']))
                    {
                        $sch_date   = Carbon::parse(session('bulk_sms_data')['schedule_date']);
                        $now        = Carbon::now()->addMinutes(1);
                        $date       = $now->lte($sch_date) ? $sch_date : $now;
                    } 
                    else 
                    {
                        $date = Carbon::now()->addMinutes(1);
                    }

                    if ($curr_bal >= $tot_cost) 
                    {
                        //TODO: Create a job
                        $job = new UserJob([
                            'username' => $_user->username,
                            'sender' => $sender,
                            'message' => $msgs,
                            'sms_count' => $no_pages,
                            'type' => 'bulk',
                            'sched_datetime' => $date,
                            'status' => 'pending',
                            'created_by' => $_user->username,
                            'file_path' => $path,
                            'name' => $name,
                            'total_traffic' => $nummsisdn
                        ]);

                        $_user->jobs()->save($job);

                        //update audit trails
                        $_user->audit_trails()->create([
                            'username' => $_user->username,
                            'date' => Carbon::now()->toDateTimeString(),
                            'activity' => $_user->username.' sent a bulk sms to '.$nummsisdn.' msisdn'
                        ]);

                        //send blast alert
                        $alertThreshold = intval(env('BLAST_ALERT', 1000));
                        if (intval($nummsisdn) >= $alertThreshold) {
                            SmsTools::sendBlastAlert($_user, $nummsisdn);
                        }
                        $request->session()->flash('success', 'Your TARGETED SMS was successfully SENT!');
                    }
                    else
                    {
                        return Redirect::back()->withInput()->withErrors(array('error' => 'Sorry, you don\'t have enough credit to proceed!'));
                    }

                    //reset session
                    $step = 0;
                    $request->session()->forget('bulk_sms_data');
                    if (!$request->session()->has('success') || empty(session('success')))
                        $request->session()->flash('success', 'Your TARGETED SMS was successfully SENT!');
                }
                else // default: back button
                {
                    $step = 1;
                }
            }
        }

        return view('ads/send_bulk_sms', [
            'base' => $this->tool->base(),
            'target' => $target,
            'step' => $step,
        ]);
    }

    // send bulk sms
    public function send_bulk_email(Request $request)
    {
        $step   = 1;
        $target = Audience::findOrFail($request->route('id'));

        if ($step == 1 && strtoupper($request->getMethod()) == 'GET')
        {
            if ($request->session()->has('bulk_email_data'))
                $request->session()->forget('bulk_email_data');
            if ($request->session()->has('alert'))
                $request->session()->forget('alert');
        }

        if (strtoupper($request->method()) == 'POST')
        {
            $_user  = \Auth::user();
            $credit = $_user->credit;
            $step   = $request->get('step', 1);
            
            if ($step == 1) // process for step 1
            {
                //validate the request
                $this->validate($request, [
                    'sender'            => 'required|email',
                    'subject'           => 'required',
                    'schedule_date'     => 'present',
                    'message_content'   => 'required',
                    'name'              => 'required',
                    'image_upload'      => 'image'
                ]);

                $highestRow         = 0;
                $processed_email    = [];
                $dupplicated_msisdn = [];
                $price              = 0.0;
                $file               = $this->file($target->people(), 'email');

                try
                {
                    Excel::load($file, function ($reader) use (&$highestRow, &$processed_email, &$dupplicated_msisdn, &$price, &$_user)
                    {
                        $objExcel       = $reader->getExcel();
                        $sheet          = $objExcel->getSheet(0);
                        $highestRow     = $sheet->getHighestRow();
                        $highestColumn  = $sheet->getHighestColumn();

                        //check for duplicated
                        for ($row = 1; $row <= $highestRow; $row++)
                        {
                            try
                            {
                                //  Read a row of data into an array
                                $rowData = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row, NULL, TRUE, FALSE);
                                $email = $rowData[0][0];
                                $email = trim($email);

                                // fixed issue of incorrect recipients
                                if ($email != null && filter_var($email, FILTER_VALIDATE_EMAIL) !== false)
                                {
                                    if (in_array($email, $processed_email)) {
                                        array_push($dupplicated_msisdn, $email);
                                        continue;
                                    }
                                    $price += $_user->credit->email_price;
                                    array_push($processed_email, $email);
                                }
                            }
                            catch (\Exception $e) {}
                        }
                    });
                }
                catch (\Exception $e)
                {
                    throw $e;
                    return Redirect::back()->withInput()->withErrors(['file_upload' => 'Error! Your excel file is invalid!']);
                }

                // get data for step 2
                $new_msg_text   = $request->get('message_content', '');
                $cost           = $price;

                // cost of sending one msg with this no_pages to one person
                $nummsisdn          = count($processed_email);
                // no of recepients
                $tot_cost           = $cost;
                $curr_bal           = $credit->new_bal;
                $recipients         = $nummsisdn;
                $total_price        = $tot_cost;
                $credit_available   = $curr_bal;
                $imgId              = null;

                //update image if image exist
                if (!empty($request['image_upload']))
                {
                    if ($request->file('image_upload')->isValid())
                    {
                        $current_filename = $request->file('image_upload')->getClientOriginalName();
                        $fileMimeType = $request->file('image_upload')->getMimeType();

                        $destinationPath = storage_path() . DIRECTORY_SEPARATOR. 'uploads' . DIRECTORY_SEPARATOR;
                        $fileName = $_user->username. '_' . $current_filename;
                        $request->file('image_upload')->move($destinationPath, $fileName);
                        $full_path = $destinationPath . $fileName;
                        while(1)
                        {
                            $imgId = uniqid();
                            if (empty(SmsImage::find($imgId)))
                                break;
                        }
                        $_user->sms_images()->create([
                            'path' => $full_path,
                            'file_name' => $current_filename,
                            'mime_type' => $fileMimeType,
                            'id' => $imgId
                        ]);
                    }
                    else
                    {
                        return Redirect::back()->withInput()->withErrors(['image_upload' => 'Sorry, The file upload failed!']);
                    }
                }

                $msg = $new_msg_text;
                if (!empty($imgId))
                {
                    $sms_msg_url = route('sms_image', ['id'=>$imgId]);
                    $msg = $new_msg_text." ".$sms_msg_url;
                }

                //store user input in the new session data
                session(['bulk_email_data'=>[
                    'sender' => $request->get('sender'),
                    'message_content' => $msg,
                    'subject' => $request->get('subject'),
                    'recipients' => $recipients,
                    'total_price' => $total_price,
                    'credit_available' => $credit_available,
                    'path' => $file,
                    'schedule_date' => Carbon::parse($request->get('schedule_date')),
                    'name' => $request->get('name'),
                    'duplicated' => count($dupplicated_msisdn)
                ]]);
                $step = 2;
            }
            else if ($step == 2) // process for step 2
            {
                //check if next button was pressed
                if($request->has('submit'))
                {
                    $sender     = session('bulk_email_data')['sender'];
                    $subject    = session('bulk_email_data')['subject'];
                    $nummsisdn  = session('bulk_email_data')['recipients'];
                    $msgs       = session('bulk_email_data')['message_content'];
                    $path       = session('bulk_email_data')['path'];
                    $name       = session('bulk_email_data')['name'];
                    $cost       = session('bulk_email_data')['total_price'];

                    $tot_cost = $cost;
                    $curr_bal = $credit->new_bal;

                    //remaining sms user can send

                    if (isset(session('bulk_email_data')['schedule_date'])
                        && !empty(session('bulk_email_data')['schedule_date']))
                    {
                        $sch_date = Carbon::parse(session('bulk_email_data')['schedule_date']);
                        $now = Carbon::now()->addMinutes(1);
                        $date = $now->lte($sch_date) ? $sch_date : $now;
                    }
                    else
                    {
                        $date = Carbon::now()->addMinutes(1);
                    }

                    if ($curr_bal >= $tot_cost)
                    {
                        //TODO: Create a job
                        $job = new EmailJob([
                            'username' => $_user->username,
                            'sender' => $sender,
                            'message' => $msgs,
                            'subject' => $subject,
                            'type' => 'bulk',
                            'sched_datetime' => $date,
                            'status' => 'pending',
                            'created_by' => $_user->username,
                            'file_path' => $path,
                            'name' => $name,
                            'total_traffic' => $nummsisdn
                        ]);

                        $_user->jobs()->save($job);

                        //update audit trails
                        $_user->audit_trails()->create([
                            'username' => $_user->username,
                            'date' => Carbon::now()->toDateTimeString(),
                            'activity' => $_user->username.' sent a bulk mail to '.$nummsisdn.' email address(es)'
                        ]);

                        //send blast alert
                        $alertThreshold = intval(env('BLAST_ALERT', 1000));
                        if (intval($nummsisdn) >= $alertThreshold)
                        {
                            SmsTools::sendBlastAlert($_user, $nummsisdn, 'email');
                        }
                        $request->session()->flash('success', 'Your TARGETED EMAILS were successfully SENT!');
                    }
                    else
                    {
                        return Redirect::back()->withInput()->withErrors(array('error' => 'Sorry, you don\'t have enough credit to proceed!'));
                    }

                    //reset session
                    $step = 0;
                    $request->session()->forget('bulk_email_data');
                    if (!$request->session()->has('success') || empty(session('success')))
                        $request->session()->flash('success', 'Your TARGETED EMAILS were successfully SENT!');
                }
                else // default: back button
                {
                    //go back to step 1
                    $step = 1;
                }
            }
        }

        return view('ads/send_bulk_email', [
            'base' => $this->tool->base(),
            'target' => $target,
            'step' => $step,
        ]);
    }


    // create excel file
    private function file(Collection $people, $type = 'sms')
    {
        $_user  = auth()->user();
        $dir    = $type == 'sms' ? 'bulk_sms' : 'bulk_email';
        $path   = storage_path() . DIRECTORY_SEPARATOR. $dir . DIRECTORY_SEPARATOR;
        $name   = $_user->username. '_'. date('YmdHis');

        try
        {
            // excel file
            Excel::create($name, function($excel) use ($type, $people)
            {
                $excel->sheet('Sheet1', function($sheet) use ($type, $people)
                {
                    $sheet->SetCellValue('A1', $type == 'sms' ? 'phone' : 'email');
                    $sheet->SetCellValue('B1', 'name');
                    $row  = 2;
                    $last = $people->last();
                    $people->each(function($person) use (&$type, &$row, &$sheet, $last)
                    {
                        $sheet->SetCellValue('A'.$row, $type == 'sms' ? $person->phone_number : $person->email);
                        $sheet->SetCellValue('B'.$row, $person->first_name);
                        if ($person != $last) $row++;
                    });
                    $sheet->cells('A1:B'.$row, function($cells) {$cells->setFontSize(10);});
                });
            })->store('xlsx', storage_path($dir));
            $file = $path . $name.'.xlsx';
        }
        catch (\Exception $ex){$file = null;};
        return $file;
    }
}