<?php namespace App\Console\Commands;
ini_set('memory_limit', '2048M');
set_time_limit(0);

use Facades\Repositories\UserRepo;
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputArgument;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\View;
use Tobuli\Entities\EmailTemplate;
use Tobuli\Entities\SentCommand;
use Tobuli\Entities\User;
use Tobuli\Helpers\ReportHelper;
use Tobuli\Reports\ReportManager;
use Tobuli\Repositories\Report\ReportRepositoryInterface as Report;
use Tobuli\Repositories\Device\DeviceRepositoryInterface as Device;
use Tobuli\Repositories\Geofence\GeofenceRepositoryInterface as Geofence;
use Tobuli\Repositories\TraccarPosition\TraccarPositionRepositoryInterface as TraccarPosition;
use Tobuli\Repositories\Timezone\TimezoneRepositoryInterface as Timezone;
use Tobuli\Repositories\Event\EventRepositoryInterface as Event;
use Maatwebsite\Excel\Facades\Excel;
use Barryvdh\DomPDF\Facade as PDF;
use Bugsnag\BugsnagLaravel\BugsnagFacade as Bugsnag;

use Facades\Repositories\ReportLogRepo;

use App\Console\ProcessManager;
use Formatter;
use Language;

class ReportsDailyCommand extends Command {

	/**
	 * The console command name.
	 *
	 * @var string
	 */
	protected $name = 'reports:daily';

	/**
	 * The console command description.
	 *
	 * @var string
	 */
	protected $description = 'Command description.';
    /**
     * @var Report
     */
    private $report;
    /**
     * @var Device
     */
    private $device;
    /**
     * @var Geofence
     */
    private $geofence;
    /**
     * @var TraccarPosition
     */
    private $traccarPosition;
    /**
     * @var Timezone
     */
    private $timezone;
    /**
     * @var Event
     */
    private $event;

    private $users = [];

    private $processManager;

    /**
     * @var ReportManager
     */
    private $reportManager;

    /**
     * Create a new command instance.
     *

     */
	public function __construct(Report $report, Device $device, Geofence $geofence, TraccarPosition $traccarPosition, Timezone $timezone, Event $event)
	{
		parent::__construct();
        $this->report = $report;
        $this->device = $device;
        $this->geofence = $geofence;
        $this->traccarPosition = $traccarPosition;
        $this->timezone = $timezone;
        $this->event = $event;

        $this->reportManager = new ReportManager();
    }

	/**
	 * Execute the console command.
	 *
	 * @return mixed
	 */
	public function fire()
	{
        $timeout = config('tobuli.process.reportdaily_timeout');
        $limit = config('tobuli.process.reportdaily_limit');

        $this->processManager = new ProcessManager('reports:daily', $timeout, $limit);

        if ( ! $this->processManager->canProcess())
        {
            echo "Cant process \n";
            return false;
        }

        require_once(base_path('Tobuli/Helpers/Arabic.php'));
        $this->arabic = new \I18N_Arabic('Glyphs');

        @mkdir(storage_path('cache'));
        @chmod(storage_path('cache'), 0777);

        $schedule_type = $this->argument('type');

        if ($schedule_type == 'daily')
            $types = ['daily'];
        else
            $types = ['weekly', 'monthly'];

        foreach ($types as $type)
            $this->proccess($type);

        echo "DONE\n";
	}

	/**
	 * Get the console command arguments.
	 *
	 * @return array
	 */
    protected function getArguments()
    {
        return array(
            array('type', InputArgument::REQUIRED, 'The type')
        );
    }

	/**
	 * Get the console command options.
	 *
	 * @return array
	 */
	protected function getOptions()
	{
		return array();
	}

    public function proccess($schedule_type)
    {
        switch ($schedule_type) {
            case 'daily':
                $field = 'daily_email_sent';
                $date = date('Y-m-d H:i:s', strtotime('+1 day'));
                $next_send_format = '+1 day';
                $date_from_format = '-1 day';
                break;
            case 'weekly':
                $field = 'weekly_email_sent';
                $date = date('Y-m-d H:i:s', strtotime('-6 day', strtotime(date('Y-m-d H:i:s'))));
                $next_send_format = '+7 day';
                $date_from_format = '-7 day';
                break;
            case 'monthly':
                $field = 'monthly_email_sent';
                $date = date('Y-m-d H:i:s', strtotime('last day of 0 month'));
                $next_send_format = 'first day of +1 month';
                $date_from_format = 'first day of -1 month';
                break;
            default:
                return null;
        }



        $reports = \Tobuli\Entities\Report::where($schedule_type, 1)->where($field, '<', $date)->get();

        if (empty($reports))
            return null;

        foreach ($reports as $report) {
            if ( ! $this->processManager->canProcess())
                break;

            if ( ! $this->processManager->lock($report->id))
                continue;

            $still = \Tobuli\Entities\Report::where($schedule_type, 1)->where($field, '<', $date)->find($report->id);

            if (empty($still)) {
                $this->processManager->unlock($report->id);
                continue;
            }

            if (array_key_exists($report->user_id, $this->users))
                $user = $this->users[$report->user_id];
            else
                $user = $this->users[$report->user_id] = UserRepo::find($report->user_id);

            if ($user->isExpired()) {
                continue;
            }

            $zone = empty($user->timezone->zone) ? '+0hours' : $user->timezone->zone;

            $last_send = Formatter::time()->convert($report->{$field});
            $send_time = date('Y-m-d', strtotime($last_send)) .' '. $report->{$schedule_type.'_time'};
            $next_send = date("Y-m-d H:i:s", strtotime(date('Y-m-d H:i:s', strtotime($send_time . $next_send_format))));
            $next_send = Formatter::time()->reverse($next_send);
            $current_time = date("Y-m-d H:i:s");

            /*
            echo "title: {$data['title']}" . PHP_EOL;
            echo "$current_time current_time" . PHP_EOL;
            echo "$last_send last_send" . PHP_EOL;
            echo "$send_time send_time" . PHP_EOL;
            echo "$next_send next_send user time" . PHP_EOL;
            */

            if (strtotime($next_send) > strtotime($current_time))
                continue;

            if (strtotime($report->{$field}) > strtotime($next_send))
                continue;

            $report->update([$field => date('Y-m-d H:i:s')]);

            $data = $report->toArray();

            $data['zone'] = $zone;
            $data['user'] = $user;
            $data['date_from'] = date(
                    'Y-m-d',
                    strtotime(
                        $date_from_format,
                        Formatter::time()->now()
                    )).' '.$data[$schedule_type.'_time'];
            $data['date_to'] = date(
                    'Y-m-d',
                    Formatter::time()->now()).' '.$data[$schedule_type.'_time'];

            if ( $schedule_type == 'daily' && !empty($data['from_format']) && !empty($data['to_format']) ) {
                $now_user_time  = strtotime( date('Y-m-d', Formatter::time()->now()) );
                $timestamp_from = strtotime( $data['from_format'], $now_user_time );
                $timestamp_to   = strtotime( $data['to_format'], $now_user_time );

                if ( $timestamp_from && $timestamp_to ) {
                    $data['date_from'] = date('Y-m-d H:i:s', $timestamp_from);
                    $data['date_to']   = date('Y-m-d H:i:s', $timestamp_to);
                }
            }

            $filename = null;

            try {
                $generator = $this->reportManager->fromEntity($report, $data);
            } catch (\Exception $e) {
                $filename = $this->old($data);
            }

            if ( ! empty($generator) && $generator->isEnabled()) {
                $filename = $generator->save();
            }

            if (empty($filename))
                continue;

            $reportLog = ReportLogRepo::create([
                'user_id' => $report->user_id,
                'email' => $report->email,
                'title' => $report->title . ' ' . $data['date_from'].' - '.$data['date_to'],
                'type' => $report->type,
                'format' => $report->format,
                'size' => filesize($filename),
                'data' => file_get_contents($filename)
            ]);

            $email_template = EmailTemplate::where('name', 'report')->first();

            try {
                $response = sendTemplateEmail($report->email, $email_template, $data, [$filename]);
            } catch (\Exception $e) {
                Bugsnag::notifyException($e);
                $response = false;
            }

            if ($response) {
                if ( $response && !empty($response['status']) )
                    $reportLog->update( ['is_send' => true ] );
                else
                    $reportLog->update( ['error' => empty($response['error']) ? null : $response['error'] ] );
            }

            @unlink($filename);

            $this->processManager->unlock($data['id']);
        }
    }

	protected function old($data)
    {
        $data['unit_of_distance'] = $data['user']->unit_of_distance;
        $data['unit_of_altitude'] = $data['user']->unit_of_altitude;
        $data['lang'] = $data['user']->lang;
        $data['logo'] = 1;
        $data['arabic'] = $this->arabic;

        Language::set($data['user']->lang);

        $types = [
            '1'  => trans('front.general_information'),
            '2'  => trans('front.general_information_merged'),
            '16' => trans('front.general_information_merged_custom'),
            '42' => trans('front.general_information_merged_custom') . ' 2',
            '3'  => trans('front.drives_and_stops'),
            '18' => trans('front.drives_and_stops').' / '.trans('front.geofences'),
            '19' => trans('front.drives_and_stops').' / '.trans('front.drivers'),
            '21' => trans('front.drives_and_stops').' / '.trans('front.drivers') . ' (Business)',
            '22' => trans('front.drives_and_stops').' / '.trans('front.drivers') . ' (Private)',
            '4'  => trans('front.travel_sheet'),
            '5'  => trans('front.overspeeds'),
            '6'  => trans('front.underspeeds'),
            '7'  => trans('front.geofence_in_out'),
            '15' => trans('front.geofence_in_out_24_mode'),
            '20' => trans('front.geofence_in_out').' ('.trans('front.ignition_on_off').')',
            '28' => trans('front.geofence_in_out').' (Shift)',
            '31' => trans('front.geofence_touch_all'),
            '8'  => trans('front.events'),
            '10' => trans('front.fuel_level'),
            '11' => trans('front.fuel_fillings'),
            '12' => trans('front.fuel_thefts'),
            '13' => trans('front.temperature'),
            '14' => trans('front.rag'),
            '23' => trans('front.rag').' / '.trans('front.seatbelt'),
            '24' => 'Birla ' . trans('global.custom'),
            '25' => trans('front.object_history'),
            '26' => trans('front.object_history'),
            '27' => 'Automon ' . trans('global.custom'),
            '29' => trans('front.engine_hours') . ' ' . trans('validation.attributes.daily'),
            '30' => trans('front.ignition_on_off'),
            '32' => trans('front.sent_commands'),
            '33' => trans('front.overspeed_custom'),
            '34' => trans('front.overspeed_custom_summary'),
            '35' => trans('front.installation_all_objects'),
            '36' => trans('front.installation_offline_objects'),
            '37' => trans('front.loading_unloading'),
            '38' => trans('front.offline_objects'),
            '43' => trans('front.routes'),
        ];

        $items = [];

        $report = $this->report->getWithFirst(['devices', 'devices.sensors', 'devices.users', 'geofences'], ['id' => $data['id']]);

        if (empty($report->devices))
            return null;

        if (in_array($data['type'], [21, 22]) && !settings('plugins.business_private_drive.status')) {
            return null;
        }

        if (in_array($data['type'], [35, 36]) && ! settings('plugins.additional_installation_fields.status'))
            return null;

        # Devices
        $devices = $report->devices->filter(function ($device){
            return ! $device->isExpired();
        });

        if (empty($devices))
            return null;

        $geofences = $report->geofences;

        # User geofences
        if ( ! in_array($data['type'], [7,15,20,28,31])) {
            $geofences = $this->geofence->getWhere(['user_id' => $data['user_id']]);
        }

        $reportHelper =  new ReportHelper($data, $geofences);

        foreach ($devices as $device) {
            $timezone = $data['zone'];

            $reportHelper->setData([
                'zone' => $timezone
            ]);
            $date_from = Formatter::time()->reverse($data['date_from']);
            $date_to = Formatter::time()->reverse($data['date_to']);

            if ($data['type'] == 7) { # Geofence in/out
                $items_result = $this->traccarPosition->searchWithSensors($data['user_id'], $device->traccar_device_id, $date_from, $date_to);

                if (!empty($items_result))
                    $items[$device->id] = $reportHelper->generateGeofences($items_result, $date_from, $date_to);

                unset($items_result);
            } elseif ($data['type'] == 8) { # Events
                $items_result = $this->event->getBetween($data['user_id'], $device->id, $date_from, $date_to);
                if (!empty($items_result))
                    $items[$device->id] = $reportHelper->generateEvents($items_result->toArray());

                unset($items_result);
            } elseif ($data['type'] == 14) {
                $items_result = $this->traccarPosition->searchWithSensors($data['user_id'], $device->traccar_device_id, $date_from, $date_to);

                $driver_history = getDevicesDrivers($data['user_id'], $device->id, $date_from, $date_to, '>=', NULL, TRUE);
                $last_dr = getDevicesDrivers($data['user_id'], $device->id, $date_from, NULL, '<=', 1);
                if (!empty($last_dr)) {
                    if (!is_array($driver_history))
                        $driver_history = [];

                    $last_dr = end($last_dr);
                    $driver_history[] = $last_dr;
                }

                $rag_sensors = [];
                foreach ($device->sensors as $key => $sensor) {
                    if ($sensor['type'] == 'harsh_acceleration' || $sensor['type'] == 'harsh_breaking')
                        array_push($rag_sensors, $sensor);
                }

                $items[$device->id] = $reportHelper->generateRag($items_result, $driver_history, $device, $rag_sensors, $date_from, $date_to);
            }
            elseif ($data['type'] == 23) { # RAG Seatbelt
                $items_result = $this->traccarPosition->searchWithSensors($data['user_id'], $device->traccar_device_id, $date_from, $date_to);

                $driver_history = getDevicesDrivers($data['user_id'], $device->id, $date_from, $date_to, '>=', NULL, TRUE);
                $last_dr = getDevicesDrivers($data['user_id'], $device->id, $date_from, NULL, '<=', 1);
                if (!empty($last_dr)) {
                    if (!is_array($driver_history))
                        $driver_history = [];

                    $last_dr = end($last_dr);
                    $driver_history[] = $last_dr;
                }

                $rag_sensors = [];
                foreach ($device->sensors as $key => $sensor) {
                    if (in_array($sensor['type'], ['harsh_acceleration', 'harsh_breaking', 'seatbelt']))
                        array_push($rag_sensors, $sensor);
                }

                $items[$device->id] = $reportHelper->generateRagSeatBelt($items_result, $driver_history, $device, $rag_sensors, $date_from, $date_to);
            }
            elseif ($data['type'] == 15) { # Geofence in/out 24 mode
                $items_result = $this->traccarPosition->searchWithSensors($data['user_id'], $device->traccar_device_id, $date_from, $date_to);

                if (!empty($items_result))
                    $items[$device->id] = $reportHelper->generateGeofences24($items_result, $date_from, $date_to);

                unset($items_result);
            }
            elseif ($data['type'] == 16) {
                $items_result = $this->traccarPosition->searchWithSensors($data['user_id'], $device->traccar_device_id, $date_from, $date_to);

                if (!empty($items_result))
                    $items[$device->id] = $reportHelper->generateGeneralCustom($items_result, $date_from, $date_to, $device, $device->sensors);

                unset($items_result);
            }
            elseif ($data['type'] == 20) {
                $items_result = $this->traccarPosition->searchWithSensors($data['user_id'], $device->traccar_device_id, $date_from, $date_to);

                if (!empty($items_result))
                    $items[$device->id] = $reportHelper->generateGeofencesEngine($items_result, $date_from, $date_to, $device, $device->sensors);

                unset($items_result);
            }
            elseif ($data['type'] == 24) { # Birla Custom
                $items_result = $this->traccarPosition->searchWithSensors($data['user_id'], $device->traccar_device_id, $date_from, $date_to);

                $items[$device->id] = $reportHelper->generateBirlaCustom($items_result, $date_from, $date_to, $device);

                unset($items_result);
            }
            elseif ($data['type'] == 25) { # Object history

                $items[$device->id] = $reportHelper->generateObjectHistory($date_from, $date_to, $device, $data['user']);

                if (empty($data['parameters']))
                    $data['parameters'] = [];

                $data['parameters'] = array_unique($data['parameters'] + $items[$device->id]['parameters']);
            }
            elseif ($data['type'] == 27) { # Automon Custom
                $items_result = $this->traccarPosition->searchWithSensors($data['user_id'], $device->traccar_device_id, $date_from, $date_to);

                $items[$device->id] = $reportHelper->generateAutomonCustom($items_result, $date_from, $date_to, $device);

                unset($items_result);
            }
            elseif ($data['type'] == 28) { # Geofence shift
                $items_result = $this->traccarPosition->searchWithSensors($data['user_id'], $device->traccar_device_id, $date_from, $date_to);

                $items[$device->id] = $reportHelper->generateGeofencesShift($items_result, $date_from, $date_to, $device, $report->parameters);

                unset($items_result);
            }
            elseif ($data['type'] == 29) { # Engine hours 24
                $items_result = $this->traccarPosition->searchWithSensors($data['user_id'], $device->traccar_device_id, $date_from, $date_to);

                $items[$device->id] = $reportHelper->generateEngineHours24($items_result);

                unset($items_result);
            }
            elseif ($data['type'] == 30) { # Ignition on/off
                $items_result = $this->traccarPosition->searchWithSensors(
                    $data['user_id'], $device->traccar_device_id, $date_from, $date_to);

                $driver_history = getDevicesDrivers(
                    $data['user_id'], $device->id, $date_from, $date_to, '>=', null, true);
                $last_driver = getDevicesDrivers(
                    $data['user_id'], $device->id, $date_from, null, '<=', 1);

                if ( ! is_array($driver_history))
                    $driver_history = [];

                if ( ! empty($last_driver))
                    $driver_history[] = end($last_driver);

                if (!empty($items_result))
                    $items[$device->id] = $reportHelper->generateIgnitionOnOff(
                        $items_result, $device, $driver_history);

                unset($items_result);
            }
            elseif ($data['type'] == 31) {
                $items_result = $this->traccarPosition->searchWithSensors(
                    $data['user_id'], $device->traccar_device_id, $date_from, $date_to
                );

                if ( ! empty($items_result))
                    $items[$device->id] = $reportHelper->generateGeofencesTouchAll($items_result);

                unset($items_result);
            }
            elseif ($data['type'] == 32) {
                $items_result = SentCommand::with('user')
                    ->where('device_imei', $device->imei)
                    ->whereBetween('created_at', [$date_from, $date_to])
                    ->get();

                $data['admin_or_manager'] = $data['user']->isAdmin() || $data['user']->isManager();

                if ( ! empty($items_result))
                    $items[$device->id] = $reportHelper->generateSentCommands($data['user'], $items_result);

                unset($items_result);
            } elseif ($data['type'] == 33) {
                $items_result = $this->traccarPosition->searchWithSensors(
                    $data['user_id'], $device->traccar_device_id, $date_from, $date_to
                );

                if ( ! empty($items_result)) {
                    $result = $reportHelper->generateOverspeeds(User::find($data['user_id']), $device, $items_result);
                    $data = array_merge($data, $result['adds']);
                    $items[$device->id] = $result['rows'];
                }

                unset($items_result);

            } elseif ($data['type'] == 34) {
                $items_result = $this->traccarPosition->searchWithSensors(
                    $data['user_id'], $device->traccar_device_id, $date_from, $date_to
                );

                $items[$device->id] = $reportHelper->generateOverspeedsSummary($data['user'], $device, $items_result);

                unset($items_result);

            } elseif ($data['type'] == 37) {
                $items_result = $this->traccarPosition->searchWithSensors(
                    $data['user_id'], $device->traccar_device_id, $date_from, $date_to
                );

                if ( ! empty($items_result)) {
                    $result = $reportHelper->generateLoad($device, $items_result, $data['user']);
                    $data = array_merge($data, $result['adds']);
                    $items[$device->id] = $result['rows'];
                }

                unset($items_result);

            } elseif ($data['type'] == 38) {
                $position = $device->positions()->latest('time')->first();

                $items[$device->id] = $reportHelper->generateOfflineDevices($device, $position);

                unset($position);

            } else {
                $items_result = $this->traccarPosition->searchWithSensors($data['user_id'], $device->traccar_device_id, $date_from, $date_to);

                if (!empty($items_result)) {
                    $engine_status = $device->getEngineStatusFrom($date_from);

                    $sensors = NULL;
                    $driver_history = NULL;
                    if (in_array($data['type'], [1, 2, 3, 4, 5, 6, 10, 11, 12, 13, 18, 19, 21, 22])) {
                        # Odometer
                        if (count($device->sensors)) {
                            foreach ($device->sensors as $key => $sensor) {
                                if ($sensor['type'] == 'odometer') {
                                    if ($sensor['odometer_value_by'] == 'virtual_odometer') {
                                        $result = $this->traccarPosition->sumDistanceHigher($device->traccar_device_id, $date_to)->sum;
                                        if ($sensor['odometer_value_unit'] == 'mi')
                                            $result = kilometersToMiles($result);

                                        $sensor['odometer_value'] = round($sensor['odometer_value'] - $result);
                                    }
                                }
                                $sensors[] = $sensor;
                            }
                        }
                    }
                    if (in_array($data['type'], [1, 2, 3, 4, 10, 11, 12, 13, 14, 18, 19, 21, 22])) {
                        $driver_history = getDevicesDrivers($data['user_id'], $device->id, $date_from, $date_to, '>=', NULL, TRUE);
                        $last_dr = getDevicesDrivers($data['user_id'], $device->id, $date_from, NULL, '<=', 1);
                        if (!empty($last_dr)) {
                            if (!is_array($driver_history))
                                $driver_history = [];

                            $last_dr = end($last_dr);
                            $driver_history[] = $last_dr;
                        }
                    }

                    $items[$device->id] = $reportHelper->generate($items_result, $sensors, $driver_history, $device, $date_from, $date_to, $engine_status);
                }

                unset($items_result);
            }
        }

        unset($reportHelper);

        $arr = [];
        foreach ($devices as $device) {
            $arr[$device->id] = $device->toArray();
        }
        $devices = $arr;
        unset($arr);

        if (in_array($data['type'], [19, 21, 22])) {
            $arr = [
                'items' => [],
                'devices' => $devices,
                'data' => $data
            ];

            foreach ($items as $device_id => $item) {
                foreach ($item->getItems() as $it) {
                    $arr['items'][$it['driver']]['items'][strtotime($it['raw_time'])] = $it + ['device' => $device_id];
                    if (!array_key_exists('total', $arr['items'][$it['driver']])) {
                        $arr['items'][$it['driver']]['total'] = [
                            'drive' => 0,
                            'stop' => 0,
                            'distance' => 0,
                            'fuel' => 0,
                            'engine_work' => 0,
                            'engine_idle' => 0
                        ];
                    }
                    $arr['items'][$it['driver']]['total']['distance'] += $it['distance'];
                    $arr['items'][$it['driver']]['total']['fuel'] += $it['fuel_consumption'];
                    $arr['items'][$it['driver']]['total']['engine_work'] += $it['engine_work'];
                    $arr['items'][$it['driver']]['total']['engine_idle'] += $it['engine_idle'];
                    if ($it['status'] == 1) {
                        $arr['items'][$it['driver']]['total']['drive'] += $it['time_seconds'];
                    }
                    elseif ($it['status'] == 2) {
                        $arr['items'][$it['driver']]['total']['stop'] += $it['time_seconds'];
                    }

                    if ( empty($arr['items'][$it['driver']]['total']['fuel_sensor']) ) {
                        $fuel_sensor_id = null;

                        if (isset($item->fuel_consumption) && is_array($item->fuel_consumption)) {
                            reset($item->fuel_consumption);
                            $fuel_sensor_id = key($item->fuel_consumption);
                        }

                        if ( isset($item->sensors_arr[$fuel_sensor_id]) ) {
                            $arr['items'][$it['driver']]['total']['fuel_sensor'] = $item->sensors_arr[$fuel_sensor_id];
                        }
                    }
                }
            }
            $items = $arr;
        }

        $report_name = mb_convert_encoding(
            $types[$data['type']].'_'.
            $data['date_from'].'_'.
            $data['date_to'].'_'.
            $data['user_id'].'_'.uniqid(), 'ASCII');
        $report_name = strtr($report_name, [
            ' ' => '_',
            '-' => '_',
            ':' => '_',
            '/' => '_'
        ]);

        $path = storage_path('cache');
        $filename = $path.'/'.$report_name;

        if ($data['format'] == 'html') {
            $type = $data['type'] == 13 ? 10 : $data['type'];
            if ($data['type'] == 13 || $data['type'] == 10)
                $data['sensors_var'] = $data['type'] == 13 ? 'temperature_sensors' : 'fuel_tank_sensors';

            $html = View::make('front::Reports.parse.type_'.$type)->with(compact('devices', 'items', 'types', 'data'))->render();
            $filename .= '.html';
            $mime = 'text/html';

            try {
                file_put_contents($filename, $html);
            } catch (\Exception $e) {
                Bugsnag::notifyException($e);
                return null;
            }
        }
        elseif ($data['format'] == 'pdf' || $data['format'] == 'pdf_land') {
            $filename .= '.pdf';
            $mime = 'application/pdf';
            $stop = FALSE;
            $failed = FALSE;
            $change_page_size = ($data['format'] == 'pdf_land');
            $tries = 1;
            while (!$stop && !$failed) {
                try {
                    if ($change_page_size)
                        $pdf = PDF::loadView('front::Reports.parse.type_'.$data['type'], compact('devices', 'items', 'types', 'data'))->setPaper(array(0,0,950,950), 'landscape');
                    else
                        $pdf = PDF::loadView('front::Reports.parse.type_'.$data['type'], compact('devices', 'items', 'types', 'data'));

                    $pdf->save($filename);
                    $stop = TRUE;
                }
                catch (\Exception $e) {
                    if ($e instanceof \DOMPDF_Exception && $e->getMessage() == 'Frame not found in cellmap') {
                        $change_page_size = TRUE;
                    } else {
                        Bugsnag::notifyException($e);
                        Bugsnag::notifyError('reportDaily', 'type: ' . $data['type']);
                    }

                    $tries++;
                    if ($tries > 2)
                        $failed = TRUE;
                    sleep(1);
                }
            }

            if ($failed)
                return null;
        }
        elseif ($data['format'] == 'xls') {
            $filename .= '.xls';
            $mime = 'application/vnd.ms-excel';
            try {
                Excel::create($report_name, function($excel) use ($items, $devices, $types, $data) {
                    $excel->sheet('Report', function($sheet) use ($items, $devices, $types, $data) {
                        $sheet->loadView('front::Reports.parse.type_'.$data['type'], compact('devices', 'items', 'types', 'data'));
                    });
                })->store('xls', $path);
            }
            catch(\Exception $e) {
                Bugsnag::notifyException($e);
                return null;
            }
        }

        return $filename;
    }
}
