<?php

namespace App\Http\Controllers;

use App\Country;
use App\DataTables\CampaignDatatable;
use App\DataTables\EmailLog24DataTable;
use App\DataTables\EmailLog24DataTable_DELIVERED;
use App\DataTables\EmailLog24DataTable_FAILED;
use App\DataTables\EmailLog24DataTable_REJECTED;
use App\DataTables\InvoiceDataTable;
use App\DataTables\Report2wayDataTable;
use App\DataTables\ReportingDataTable;
use App\DataTables\SmsLog24DataTable;
use App\DataTables\SmsLogDelivered24DataTable;
use App\DataTables\SmsLogExpired24DataTable;
use App\DataTables\SmsLogUndeliverd24DataTable;
use App\DataTables\SmsLogUndelivered24DataTable;
use App\DataTables\SmsStanbicBulkDataTable;
use App\DataTables\SmsStanbicEbankingDataTable;
use App\DataTables\SmsStanbicOtpDataTable;
use App\DataTables\SmsStanbicTransDataTable;
use App\DataTables\SpecifyEmailPeriodDataTable;
use App\DataTables\SpecifyPeriodDataTable;
use App\DataTables\VoiceLog24DataTable;
use App\Log;
use App\Network;
use App\Report;
use Carbon\Carbon;
use Illuminate\Http\Request;

use App\Http\Requests;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Session;

class ReportController extends Controller
{
    public function get_sms_log_24h(SmsLog24DataTable $dataTable)
    {
        return $dataTable->render('report.sms_log_24h');
    }

    public function get_stanbic_otp_report(SmsStanbicOtpDataTable $dataTable)
    {
        return $dataTable->render('report.stanbic_otp');
    }

    public function get_stanbic_ebanking_report(SmsStanbicEbankingDataTable $dataTable)
    {
        return $dataTable->render('report.stanbic_ebanking');
    }

    public function get_stanbic_transactional_report(SmsStanbicTransDataTable $dataTable)
    {
        return $dataTable->render('report.stanbic_transactional');
    }

    public function get_stanbic_bulksms_report(SmsStanbicBulkDataTable $dataTable)
    {
        return $dataTable->render('report.stanbic_bulksms');
    }

    public function get_sms_undelivered_log_24h(SmsLogUndelivered24DataTable $dataTable)
    {
        return $dataTable->render('report.sms_log_undelivered_24h');
    }

    public function get_sms_delivered_log_24h(SmsLogDelivered24DataTable $dataTable)
    {
        return $dataTable->render('report.sms_log_delivered_24h');
    }

    public function get_sms_expired_log_24h(SmsLogExpired24DataTable $dataTable)
    {
        return $dataTable->render('report.sms_log_expired_24h');
    }

    public function get_email_log_24h(EmailLog24DataTable $dataTable)
    {
        return $dataTable->render('report.email_log_24h');
    }

    public function get_email_log_24h_sent(EmailLog24DataTable $dataTable)
    {
        return $dataTable->render('report.email_log_24h_sent');
    }

    public function get_email_log_24h_delivered(EmailLog24DataTable_DELIVERED $dataTable)
    {
        return $dataTable->render('report.email_log_24h_delivered');
    }

    public function get_email_log_24h_failed(EmailLog24DataTable_FAILED $dataTable)
    {
        return $dataTable->render('report.email_log_24h_failed');
    }

    public function get_email_log_24h_rejected(EmailLog24DataTable_REJECTED $dataTable)
    {
        return $dataTable->render('report.email_log_24h_rejected');
    }

    public function get_voice_log_24h(VoiceLog24DataTable $dataTable)
    {
        return $dataTable->render('report.voice_log_24h');
    }

    public function get_specify_period(SpecifyPeriodDataTable $dataTable)
    {
        return $dataTable->render('report.specify_period');
    }

    public function get_specify_period_email(SpecifyEmailPeriodDataTable $dataTable)
    {
        return $dataTable->render('report.specify_period_email');
    }

    public function _2way(Report2wayDataTable $dataTable) {
        return $dataTable->render('report.report2way');
    }

    public function post_report(Request $request) {
        $this->validate($request, [
            'name' => 'required',
            'filter_by' => 'required',
            'from_date' => 'required',
            'to_date' => 'required',
            'headers' => 'required'
        ]);

        $inputs = $request->except(['headers', 'to_date', 'from_date']);
        $inputs['status'] = 'pending';
        $inputs['expiry_date'] = Carbon::now()->addDays(3);
        $from = Carbon::parse($request['from_date']);
        $to = Carbon::parse($request['to_date']);
        if($from->gt($to)) {
            return Redirect::back()->withInput()->withErrors(array('error' => 'Invalid date range'));
        }
        $inputs['from_date'] = $from->toDateString();
        $inputs['to_date'] = $to->toDateString();

        $inputs['headers'] = implode(',', $request['headers']);

        //save report
        $request->user()->reports()->create($inputs);

        Session::flash('success', 'Your report is being processed!');
        return redirect()->route('report_get_reporting');
    }

    public function delete_selection(Request $request) {

    }

    public function getOperators($country) {
        return Country::findOrFail($country)->networks()->orderBy('nice_name', 'asc')->get(['id','nice_name']);
    }

    public function comparison() {
        return view('report.comparison');
    }

    public function invoice(Request $request, InvoiceDataTable $dataTable) {
        if($request->method()=='GET' && empty($request['draw'])) {
            $countries = Country::orderBy('name', 'asc')->get(['id', 'name']);
            return view('report.invoice', ['countries' => $countries]);
        } else {
            $temp = $request['operator'];
            return $dataTable->forInputs($request->all())->render('report.post_invoice', [
                'from_date' => $request['from_date'],
                'to_date' => $request['to_date'],
                'country' => $request['country'],
                'operator' => is_array($temp) ? implode(',', $temp) : $temp,
            ]);
        }
    }


//    public function post_invoice() {

//    }

    public function post_comparison(Request $request) {
        $this->validate($request, [
            'type' => 'required',
            'service' => 'required',
        ]);

        $user = $request->user();
        $date = Carbon::now();
        $from_date = Carbon::parse($date->toDateString());
        $to_date = clone $from_date;
        $to_date = Carbon::parse($to_date->addDays(1)->addSeconds(-1));

        $from_date_2 = $from_date->copy();
        $to_date_2 = $to_date->copy();
        $date_str1 = '';
        $date_str2 = '';

        $type = $request['type'];
        if($type=='years') {
            $from_date->setDate($request['year1'], 1, 1);
            $to_date = clone $from_date;
            $to_date = $to_date->addYears(1)->addSeconds(-1);

            $from_date_2->setDate($request['year2'], 1, 1);
            $to_date_2 = clone $from_date_2;
            $to_date_2 = $to_date_2->addYears(1)->addSeconds(-1);

            $date_str1 = 'Year '.$request['year1'];
            $date_str2 = 'Year '.$request['year2'];
        }
        else if($type=='months') {
            $from_date->setDate($request['year1'], $request['month1'], 1);
            $to_date = $from_date->copy()->addMonth()->addSeconds(-1);

            $from_date_2->setDate($request['year2'], $request['month2'], 1);
            $to_date_2 = $from_date_2->copy()->addMonth()->addSeconds(-1);

            $date_str1 = $from_date->format('F'). ' '.$request['year1'];
            $date_str2 = $from_date_2->format('F'). ' '.$request['year2'];
        }
        else if($type=='days') {
            $from_date->setDate($request['year1'], $request['month1'], $request['day1']);
            $to_date = $from_date->copy()->addDay()->addSeconds(-1);

            $from_date_2->setDate($request['year2'], $request['month2'], $request['day2']);
            $to_date_2 = $from_date_2->copy()->addDay()->addSeconds(-1);

            $date_str1 = $request['day1'].' '.$from_date->format('F'). ' '.$request['year1'];
            $date_str2 = $request['day2'].' '.$from_date_2->format('F'). ' '.$request['year2'];
        }
        else if($type=='weeks') {

            $to_date = $this->get_end_of_week($request['year1'], $request['month1'], $request['week1']);
            $from_date = $this->get_start_of_week($to_date);

            $to_date_2 = $this->get_end_of_week($request['year2'], $request['month2'], $request['week2']);
            $from_date_2 = $this->get_start_of_week($to_date_2);

            $date_str1 = 'Week '.$request['week1'].', '.$from_date->format('F'). ' '.$request['year1'];
            $date_str2 = 'Week '.$request['week2'].', '.$from_date_2->format('F'). ' '.$request['year2'];
        }

        $is_sms = strcasecmp($request['service'], 'email')!==0;

        if($is_sms) {
            $data = DB::select('select `status`, count(*) as total from `sms_log`
                            where `user_id`=? AND (`submit_date` between ? and ?)
                            GROUP BY `status`', [
                Auth::user()->id,
                $from_date->toDateTimeString(),
                $to_date->toDateTimeString()
            ]);
        } else {
            $data = DB::select('select `status`, count(*) as total from `email_logs`
                            where `user_id`=? AND (`submit_date` between ? and ?)
                            GROUP BY `status`', [
                Auth::user()->id,
                $from_date->toDateTimeString(),
                $to_date->toDateTimeString()
            ]);
        }

        $tempArray = [];
        foreach ($data as $dat) {
            $status = strtoupper($dat->status);
            $total = $dat->total;
            $tempArray["{$status}"] = $total;
        }

        if($is_sms) {
            $data2 = DB::select('select `status`, count(*) as total from `sms_log`
                            where `user_id`=? AND (`submit_date` between ? and ?)
                            GROUP BY `status`', [
                Auth::user()->id,
                $from_date_2->toDateTimeString(),
                $to_date_2->toDateTimeString()
            ]);
        } else {
            $data2 = DB::select('select `status`, count(*) as total from `email_logs`
                            where `user_id`=? AND (`submit_date` between ? and ?)
                            GROUP BY `status`', [
                Auth::user()->id,
                $from_date_2->toDateTimeString(),
                $to_date_2->toDateTimeString()
            ]);
        }

        $tempArray2 = [];
        foreach ($data2 as $dat) {
            $status = strtoupper($dat->status);
            $total = $dat->total;
            $tempArray2["{$status}"] = $total;
        }

        if($is_sms) {
            $total_sms_sent = $user->sms_log()->whereBetween('submit_date', [
                $from_date->toDateTimeString(),
                $to_date->toDateTimeString()
            ])->count();

            $total_sms_sent_2 = $user->sms_log()->whereBetween('submit_date', [
                $from_date_2->toDateTimeString(),
                $to_date_2->toDateTimeString()
            ])->count();

            $total_sms_delivered = isset($tempArray['DELIVRD']) ? $tempArray['DELIVRD'] : 0;
            $total_sms_ack = isset($tempArray['ACK/']) ? $tempArray['ACK/'] : 0;
            $total_sms_undelivered = isset($tempArray['UNDELIV']) ? $tempArray['UNDELIV'] : 0;
            $total_sms_expired = isset($tempArray['EXPIRED']) ? $tempArray['EXPIRED'] : 0;

            $total_sms_delivered_2 = isset($tempArray2['DELIVRD']) ? $tempArray2['DELIVRD'] : 0;
            $total_sms_ack_2 = isset($tempArray2['ACK/']) ? $tempArray2['ACK/'] : 0;
            $total_sms_undelivered_2 = isset($tempArray2['UNDELIV']) ? $tempArray2['UNDELIV'] : 0;
            $total_sms_expired_2 = isset($tempArray2['EXPIRED']) ? $tempArray2['EXPIRED'] : 0;
        } else {
            $total_sms_sent = $user->email_logs()->whereBetween('submit_date', [
                $from_date->toDateTimeString(),
                $to_date->toDateTimeString()
            ])->count();

            $total_sms_sent_2 = $user->email_logs()->whereBetween('submit_date', [
                $from_date_2->toDateTimeString(),
                $to_date_2->toDateTimeString()
            ])->count();

            //1
            $total_sms_delivered = $total_sms_ack = $total_sms_undelivered = $total_sms_expired =0;

            $total_sms_delivered += isset($tempArray['DELIVERED']) ? $tempArray['DELIVERED']: 0;
            $total_sms_delivered += isset($tempArray['OPENED']) ? $tempArray['OPENED']: 0;
            $total_sms_delivered += isset($tempArray['COMPLAINED']) ? $tempArray['COMPLAINED']: 0;
            $total_sms_ack += isset($tempArray['SENT']) ? $tempArray['SENT'] : 0;
            $total_sms_ack += isset($tempArray['ACCEPTED']) ? $tempArray['ACCEPTED'] : 0;
            $total_sms_undelivered += isset($tempArray['REJECTED']) ? $tempArray['REJECTED'] : 0;
            $total_sms_expired += isset($tempArray['FAILED']) ? $tempArray['FAILED'] : 0;

            //2
            $total_sms_delivered_2 = $total_sms_ack_2 = $total_sms_undelivered_2 = $total_sms_expired_2 =0;

            $total_sms_delivered_2 += isset($tempArray2['DELIVERED']) ? $tempArray2['DELIVERED']: 0;
            $total_sms_delivered_2 += isset($tempArray2['OPENED']) ? $tempArray2['OPENED']: 0;
            $total_sms_delivered_2 += isset($tempArray2['COMPLAINED']) ? $tempArray2['COMPLAINED']: 0;
            $total_sms_ack_2 += isset($tempArray2['SENT']) ? $tempArray2['SENT'] : 0;
            $total_sms_ack_2 += isset($tempArray2['ACCEPTED']) ? $tempArray2['ACCEPTED'] : 0;
            $total_sms_undelivered_2 += isset($tempArray2['REJECTED']) ? $tempArray2['REJECTED'] : 0;
            $total_sms_expired_2 += isset($tempArray2['FAILED']) ? $tempArray2['FAILED'] : 0;

        }

        return view('report.comparison_report', [
            'total_sms' => $date_str1,
            'total_sms_sent' => $total_sms_sent,
            'total_sms_delivered' => $total_sms_delivered,
            'total_sms_ack' => $total_sms_ack,
            'total_sms_undelivered' => $total_sms_undelivered,
            'total_sms_expired' => $total_sms_expired,

            'total_sms_2' => $date_str2,
            'total_sms_sent_2' => $total_sms_sent_2,
            'total_sms_delivered_2' => $total_sms_delivered_2,
            'total_sms_ack_2' => $total_sms_ack_2,
            'total_sms_undelivered_2' => $total_sms_undelivered_2,
            'total_sms_expired_2' => $total_sms_expired_2,
        ]);
    }

    /**
     * @param $year
     * @param $month
     * @param $week
     * @return static
     * @throws \Exception
     */
    private function get_end_of_week($year, $month, $week)
    {
        $week_number = (int)$week;
        if($week_number <1 || $week_number>5) {
            throw new \Exception('Invalid week number');
        }
        $max_day = $week_number * 7;
        if($max_day > 30) {
            $date = Carbon::create($year, $month, 30, 23, 59, 59);
            if($date->copy()->addDay()->month == $date->month)
                $date = $date->addDay();
        } else {
            $date = Carbon::create($year, $month, $max_day, 23, 59, 59);

            while (!$date->isSunday()) {
                $date = $date->addDays(-1);
            }
        }
        return $date;
    }

    private function get_start_of_week(Carbon $endDate)
    {
        $date = $endDate->copy();
        if($date->day -6 < 1) {
            $date->day = 1;
        } else {
            while (!$date->isMonday()) {
                $date = $date->addDays(-1);
            }
        }
        $date->setTime(0, 0, 0);
        return $date;
    }

    public function new_report() {
        //get all campaigns
        $campaigns = Auth::user()->jobs()->distinct()->take(500)->get(['name']);
        $senders = Auth::user()->sms_log()->distinct()->take(500)->get(['sender']);
        $col_headers = [
            'To', 'Message', 'Campaign Name', 'Status',
            'Username', 'From', 'Sent At', 'SMS Count',
            'Network', 'Msg Id', 'Delivered At'
        ];
        return view('report.new_report',[
            'campaigns' => $campaigns,
            'senders' => $senders,
            'col_headers' => $col_headers
        ]);
    }

    public function reporting(Request $request, ReportingDataTable $dataTable) {
        if($request->method()=='POST') {
            $selection = $request->get('selection');
            $deleted = 0;

            if(!empty($selection)) {
                DB::beginTransaction();
                foreach ($selection as $sel) {
                    $contactToDel = $request->user()->reports()->find($sel);
                    if(!empty($contactToDel)) {
                        $contactToDel->delete();
                        $deleted++;
                    }
                }
                DB::commit();
            }
            Session::flash('success', $deleted. ' report(s) was successfully deleted!');
        }
        return $dataTable->render('report.reporting');
    }

    public function delete_report($id) {
        $report = Report::findOrFail($id);
        $report->delete();
        Session::flash('success', 'Your report '.$report->name.' was successfully deleted!');
        return redirect()->back();
    }

    public function download_report($id) {
        $report = Report::findOrFail($id);
        $path = $report->path;
        if(!empty($path) && file_exists($path))
            return response()->download($path);
        else
            abort(404);
    }

    public function testCode() {

        $message = 'Your OTP for Once-Off Payment is 45736 .Help: 233302815789 .Helpline: + 233 302 815 789';
        $my_msg = str_replace('GHS ', 'GHS', $message);
        $my_msg = str_replace('ghs ', 'ghs', $my_msg);
        $words = explode(' ', $my_msg);

        $new_words = [];
        for ($i = 0; $i < count($words); $i++) {

            $word = trim($words[$i]);
            $word = strtoupper($word);
            if (str_contains($word, 'GHS')) {
                echo $word. ' -  with GHS';
                echo '<br>';
                $word = str_replace('GHS', '', $word);
                $new_chars = [];
                foreach (str_split($word) as $char) {
                    if (is_numeric($char) && $char !='233302815789') {
                        $new_chars[] = '#';
                    } else {
                        $new_chars[] = $char;
                    }
                }
                $new_word = 'GHS' . implode('', $new_chars);
                $new_words[] = $new_word;
            } else{
                if (is_numeric($word) && $word !='233302815789' && $word !='233' && $word !='302' && $word !='815' && $word !='789') {
                  $harshWord= '';
                    $count=0;
                        while($count<strlen($word)){
                        $harshWord=$harshWord.'#';
                            $count++;
                    }
                    $new_words[] = $harshWord;
                } else {
                    $new_words[] = $word;
                }
            }
        }

        return implode(' ', $new_words);

        return  view('test', [
            'ret' =>$new_words
        ]);
    }
}
