<?php

class cfe_file_reports_utils
{
    public $reportGenerator = null;
    public $filename = null;
    public $attachedFiles = [];
    public $deleteAttachedAfterSend = true;
    public $storeDir; // default path to store files
    public $truncateWarning = null;
    public $reportTimeZone = null;
    public $report_id = null; // store report id, we need this to get correct report from core and distinguish between hardcoded and advanced reports
    public $restClient = null;
    public $email = null;
    public $cf_pdf = null;
    public $cf_csv = null;
    public $report_model = null;
    public $advancedreports_model = null;

    public function __construct()
    {
        $CI = &get_instance();

        $CI->load->library('email');
        $this->email = $CI->email;

        $this->storeDir = get_tmpdir();

        $CI->load->library('cf_pdf');
        $CI->load->library('cf_csv');

        $this->cf_pdf = $CI->cf_pdf;
        $this->cf_csv = $CI->cf_csv;

        $CI->load->model(['report_model', 'advancedreports_model']);
        $this->report_model = $CI->report_model;
        $this->advancedreports_model = $CI->advancedreports_model;
    }

    public function setFilename($filename)
    {
        $this->filename = $this->storeDir . $filename;
    }

    public function getFilename()
    {
        return $this->filename;
    }

    public function setStoreDir($dir)
    {
        if (!empty($dir)) {
            $this->storeDir = $dir;
        }
    }

    public function setRestClient($client)
    {
        $this->restClient = $client;
    }

    public function setDeleteAttachedAfterSend($param = false)
    {
        $this->deleteAttachedAfterSend = $param;
    }

    public function setReportId($report_id)
    {
        $this->report_id = $report_id;
    }

    /**
     *
     * @param type $timeZone - GMT is default, because for the CLI we don't have user time
     */
    public function setReportTimeZone($timeZone = 'gmt')
    {
        $this->reportTimeZone = $timeZone;
    }

    /**
     *
     * @param type $report_format - pdf or csv
     * @param type $report_type   - system name of report, for normal reprts - this will be set from core, for advanced repotr, by user
     * @param type $report_title  - report title
     */
    public function setReportGenerator($report_format, $report_id, $report_title)
    {
        $this->setReportId($report_id);
    }

    /**
     * Checks if the tmp directory exist and is writable
     * @throws Exception if not writable
     */
    public function checkTempDir()
    {
        if (empty($this->storeDir)) {
            log_message('error', 'Please make sure  that the name of saving directory is set');
            throw new Exception('Please make sure  that the name of saving directory is set');
        }

        if (!file_exists($this->storeDir)) {
            if (!mkdir($this->storeDir, 0777)) {
                log_message('error', 'Please make sure the tmp directory in web root is present');
                throw new Exception(sprintf('%s directory in web root not found.', $this->storeDir));
            }
        }

        if (!is_writable($this->storeDir)) {
            log_message('error', 'Please make sure the tmp directory in web root is writeable');
            throw new Exception(sprintf(' %s directory in web root is not writable.', $this->storeDir));
        }
    }

    public function checkIfExistAndWritable($dir)
    {
        if (empty($dir)) {
            $message = "ERROR: Please make sure that the $dir is exist";
            log_message('error', $message);
            throw new Exception($message);
        }

        if (!file_exists($dir)) {
            if (!mkdir($dir, 0777)) {
                $message = "ERROR: Please make sure the $dir directory in web root is present";
                log_message('error', $message);
                throw new Exception($message);
            }
        }

        if (!is_writable($dir)) {
            $message = "Please make sure the $dir directory in web root is writeable";
            log_message('error', $message);
            throw new Exception($message);
        }
    }

    public function generateDoc($filename)
    {
        return;
    }

    public function attachFiles($filename)
    {
        $this->email->attach($filename);
        $this->attachedFiles[] = $this->filename;
    }

    /**
     * @param $to
     * @param $from
     * @param $subject
     * @param $message
     * @param array $filesToAttach
     * @return array
     * @throws Exception
     */
    public function emailReport($to, $from, $subject, $message, $filesToAttach = [])
    {
        if (trim($to) === '') {
            throw new Exception('"To" email address is empty.');
        }

        if (trim($from) === '') {
            throw new Exception('"From" email address is empty.');
        }

        // attachment name
        // encode data (puts attachment in proper format)
        $this->email->from($from);
        $this->email->to($to);

        $this->email->subject($subject);
        $this->email->message($message);

        if (count($filesToAttach) > 0) {
            foreach ($filesToAttach as $key => $attachment) {
                $this->email->attach($attachment);
            }
        }

        if (!$this->email->send()) {
            log_message('debug', 'Something went wrong while sending mail. ' . $this->email->print_debugger());
            throw new Exception('Something went wrong while sending mail.');
        }

        $msg = 'Mail has been sent to the given address.';

        if ($this->truncateWarning) {
            $msg .= $msg . '<p class="warning>' . $this->truncateWarning . '</p>';
        }

        $retData = ['message' => $msg];

        if ($this->deleteAttachedAfterSend === true) {
            $files = (array) $this->attachedFiles;

            foreach ($files as $item => $file) {
                @unlink($file);
            }
        }

        return $retData;
    }

    public function generateReports($username, $report_type, $params)
    {
        switch ($report_type) {
            case 'advancedreports':
                $sqlString = trim($params['query']);
                if ($sqlString == '') {
                    throw new Exception('SQL query string is empty');
                }

                return $this->rpt_advancedReport($username, $sqlString, $params);
                break;
        }
    }

    public function rpt_advancedReport($username, $sqlString, $params)
    {
        try {
            $jsondata = $this->advancedreports_model->createReportJob($username, $sqlString, $params);
            return $jsondata;
        } catch (Exception $e) {
            throw new Exception($e->getMessage());
        }
    }
}
