<?php

namespace App\Http\Controllers\Esme;

use App\DataTables\CampaignDatatable;
use App\DataTables\Report2wayDataTable;
use App\DataTables\ResellerReportingDataTable;
use App\DataTables\ResellerSmsLog24DataTable;
use App\DataTables\ResellerSpecifyPeriodDataTable;
use App\DataTables\SmsLog24DataTable;
use App\DataTables\SpecifyPeriodDataTable;
use App\Http\Controllers\Controller;
use App\Report;
use App\Tools\SmsTools;
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_new_24h(ResellerSmsLog24DataTable $dataTable)
    {
        return $dataTable->render('esme.report.sms_log');
    }

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

    public function _2way(Report2wayDataTable $dataTable) {
        return $dataTable->render('esme.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('esme.report_get_reporting');
    }

    public function delete_selection(Request $request) {

    }

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

    public function post_comparison(Request $request) {
        $this->validate($request, [
            'type' => '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'];
        }

        $conn   = DB::connection('kannel');
        $s = 0; $d = 0; $u = 0; $r = 0; $e = 0; $a = 0;
        $s = $conn->select("select username, count(status) as t from logs where username=? and submit_date between ? and ?", [$user->username, $from_date, $to_date]);
        $d = $conn->select("select username, count(status) as t from logs where username=? and (submit_date between ? and ?) and status like '%DELIVRD%'", [$user->username, $from_date, $to_date]);
        $u = $conn->select("select username, count(status) as t from logs where username=? and (submit_date between ? and ?) and status like '%UNDELIV%'", [$user->username, $from_date, $to_date]);
        $r = $conn->select("select username, count(status) as t from logs where username=? and (submit_date between ? and ?) and status like '%REJECTD%'", [$user->username, $from_date, $to_date]);
        $e = $conn->select("select username, count(status) as t from logs where username=? and (submit_date between ? and ?) and status like '%EXPIRED%'", [$user->username, $from_date, $to_date]);
        $a = $s[0]->t - ($d[0]->t + $u[0]->t + $r[0]->t + $e[0]->t);

        $data = [
            'sent'          =>  [
                'count'     => $s[0]->t,
//                'percent'   => @($s[0]->t / $s[0]->t) === false ? 0.00 : round(@($s[0]->t / $s[0]->t) * 100, 2)
            ],

            'delivered'     => [
                'count'     => $d[0]->t,
//                'percent'   => @($d[0]->t / $s[0]->t) === false ? 0.00 : round(@($d[0]->t / $s[0]->t) * 100, 2)
            ],

            'undelivered'   => [
                'count'     => $u[0]->t,
//                'percent'   => @($u[0]->t / $s[0]->t) === false ? 0.00 : round(@($u[0]->t / $s[0]->t) * 100, 2)
            ],

            'rejected'      => [
                'count'     => $r[0]->t,
//                'percent'   => @($r[0]->t / $s[0]->t) === false ? 0.00 : round(@($r[0]->t / $s[0]->t) * 100, 2)
            ],

            'expired'       => [
                'count'     => $e[0]->t,
//                'percent'   => @($e[0]->t / $s[0]->t) === false ? 0.00 : round(@($e[0]->t / $s[0]->t) * 100, 2)
            ],

            'acknowledged'  => [
                'count'     => $a,
//                'percent'   => @($a / $s[0]->t) === false ? 0.00 : round(@($a / $s[0]->t) * 100, 2)
            ]
        ];


        $s = 0; $d = 0; $u = 0; $r = 0; $e = 0; $a = 0;
        $s = $conn->select("select username, count(status) as t from logs where username=? and submit_date between ? and ?", [$user->username, $from_date_2, $to_date_2]);
        $d = $conn->select("select username, count(status) as t from logs where username=? and (submit_date between ? and ?) and status like '%DELIVRD%'", [$user->username, $from_date_2, $to_date_2]);
        $u = $conn->select("select username, count(status) as t from logs where username=? and (submit_date between ? and ?) and status like '%UNDELIV%'", [$user->username, $from_date_2, $to_date_2]);
        $r = $conn->select("select username, count(status) as t from logs where username=? and (submit_date between ? and ?) and status like '%REJECTD%'", [$user->username, $from_date_2, $to_date_2]);
        $e = $conn->select("select username, count(status) as t from logs where username=? and (submit_date between ? and ?) and status like '%EXPIRED%'", [$user->username, $from_date_2, $to_date_2]);
        $a = $s[0]->t - ($d[0]->t + $u[0]->t + $r[0]->t + $e[0]->t);

        $data2 = [
            'sent'          =>  [
                'count'     => $s[0]->t,
//                'percent'   => @($s[0]->t / $s[0]->t) === false ? 0.00 : round(@($s[0]->t / $s[0]->t) * 100, 2)
            ],

            'delivered'     => [
                'count'     => $d[0]->t,
//                'percent'   => @($d[0]->t / $s[0]->t) === false ? 0.00 : round(@($d[0]->t / $s[0]->t) * 100, 2)
            ],

            'undelivered'   => [
                'count'     => $u[0]->t,
//                'percent'   => @($u[0]->t / $s[0]->t) === false ? 0.00 : round(@($u[0]->t / $s[0]->t) * 100, 2)
            ],

            'rejected'      => [
                'count'     => $r[0]->t,
//                'percent'   => @($r[0]->t / $s[0]->t) === false ? 0.00 : round(@($r[0]->t / $s[0]->t) * 100, 2)
            ],

            'expired'       => [
                'count'     => $e[0]->t,
//                'percent'   => @($e[0]->t / $s[0]->t) === false ? 0.00 : round(@($e[0]->t / $s[0]->t) * 100, 2)
            ],

            'acknowledged'  => [
                'count'     => $a,
//                'percent'   => @($a / $s[0]->t) === false ? 0.00 : round(@($a / $s[0]->t) * 100, 2)
            ]
        ];


        $total_sms_delivered = $data['delivered']['count'];
        $total_sms_ack = $data['acknowledged']['count'];
        $total_sms_undelivered = $data['undelivered']['count'];
        $total_sms_expired = $data['expired']['count'];
        $total_sent = $data['sent']['count'];

        $total_sms_delivered_2 = $data2['delivered']['count'];
        $total_sms_ack_2 = $data2['acknowledged']['count'];
        $total_sms_undelivered_2 = $data2['undelivered']['count'];
        $total_sms_expired_2 = $data2['expired']['count'];
        $total_sent_2 = $data2['sent']['count'];

        return view('esme.report.comparison_report', [
            'total_sms' => $date_str1,
            'total_sms_sent' => $total_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_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,

            'total_balance' => SmsTools::round_currency($user->credit->new_bal),
        ]);
    }

    /**
     * @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()->groupBy('name')->get(['id', 'name']);
        $senders = Auth::user()->logs()->groupBy('sender')->get(['id', 'sender']);
        $col_headers = [
            'To', 'Message', 'Campaign Name', 'Status', 'Username', 'From', 'Sent At', 'SMS Count',
        'Network', 'Msg Id', 'Delivered At'];
        return view('esme.report.new_report',[
            'campaigns' => $campaigns,
            'senders' => $senders,
            'col_headers' => $col_headers
        ]);
    }

    public function reporting(Request $request, ResellerReportingDataTable $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('esme.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);
    }

}
