<?php

namespace App\Http\Controllers\Emails;

use App\Http\Controllers\Controller;
use App\Mail\SendEmailFromSystem;
use App\Models\Email;
use App\Models\EmailAttachment;
use App\Models\EmailGroup;
use App\Models\EmailGroupList;
use App\Models\EmailRecipient;
use App\Models\EmailSignature;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;

class EmailController extends Controller
{
    /**Display Email Dashboard**/
    public function dashboard()
    {
        /**Create Variables for the Data**/
        $inbox = EmailRecipient::where('recipient_id', auth()->user()->id)->get()->count();
        $outbox = Email::where('sent_by', auth()->user()->id)->get()->count();
        $draft = 0;
        $trash = 0;
        /**Get total of All the email classes**/
        $totalEmails = $inbox + $outbox + $draft + $trash;
        /**Start to work out Percentages**/
        $inboxPercentage = 0;
        if($inbox > 0){
          $inboxPercentage = round($inbox/$totalEmails*100,2);
        }
        $outboxPercentage = 0;
        if($outbox > 0){
            $outboxPercentage = round($outbox/$totalEmails*100,2);
        }
        $draftPercentage = 0;
        if($draft > 0){
            $draftPercentage = round($draft/$totalEmails*100,2);
        }
        $trashPercentage = 0;
        if($trash > 0){
            $trashPercentage = round($trash/$totalEmails*100,2);
        }
        $data = [
            'inbox' => $inboxPercentage,
            'outbox' => $outboxPercentage,
            'draft' => $draftPercentage,
            'trash' => $trashPercentage,
        ];
        return view('modules.emails', compact('data'));
    }

    /**Display pop-up window to Send a New Email**/
    public function showSendEmailModal($id = null, $module=null)
    {
        $groups = EmailGroup::all();
        $signature = EmailSignature::where('user_id', auth()->user()->id)->first();
        return view('emails.send-email', compact('groups', 'signature'));
    }

    /**Store the Sent Email into the Database**/
    public function storeSendEmailModal(Request $request,$id = null, $module=null){
        $fromAddress = str_replace(' ', '', $request['from']);
        $toAddresses = str_replace(' ', '', $request['to']);
        $ccAddresses = str_replace(' ', '', $request['cc']);
        $bccAddresses = str_replace(' ', '', $request['bcc']);
        $subject = strtoupper($request['subject']);
        $body = $request['message'];
        $user = User::find(auth()->user()->id);

        /**Once we have the Above, we can proceed to send the email**/
        $res = 'empty to';
        if(!empty($toAddresses)){
            $tos = explode(';',$toAddresses);
            $arrLength = count($tos);
            $toAddress = [];
            for($x = 0; $x < $arrLength; $x++){
                /**We try to validate each email before allowing to send Email to it**/
                if(!filter_var($tos[$x], FILTER_VALIDATE_EMAIL)) {
                    return 'The Following To Email is invalid: '.$tos[$x];
                }
                /**Return the Email**/
                $toAddress[] = $tos[$x];
            }
            /**Customize your cc**/
            $ccAddress = [];
            if(!empty($ccAddresses)){
                $ccs = explode(';',$ccAddresses);
                $arrLength = count($ccs);
                for($x = 0; $x < $arrLength; $x++){
                    /**We try to validate each email before allowing to send Email to it**/
                    if(!filter_var($ccs[$x], FILTER_VALIDATE_EMAIL)) {
                        return 'The Following CC Email is invalid: '.$ccs[$x];
                    }
                    /**Return the Email**/
                    $ccAddress[] = $ccs[$x];
                }
            }
            /**Customize your bcc**/
            $bccAddress = [];
            if(!empty($bccAddresses)){
                $bcs = explode(';',$bccAddresses);
                $arrLength = count($bcs);
                for($x = 0; $x < $arrLength; $x++){
                    /**We try to validate each email before allowing to send Email to it**/
                    if(!filter_var($bcs[$x], FILTER_VALIDATE_EMAIL)) {
                        return 'The Following BCC Email is invalid: '.$bcs[$x];
                    }
                    /**Return the Email**/
                    $bccAddress[] = $bcs[$x];
                }
            }

            /**We first store the email into our Database**/
            $newEmail = Email::create([
                'sent_by' => auth()->user()->id,
                'from' => $fromAddress,
                'to' => $toAddresses,
                'cc' => $ccAddresses,
                'bcc' => $bccAddresses,
                'subject' => $subject,
                'body' => $body,
                'created_by' => auth()->user()->id,
            ]);

            /**Proceed to send the email now**/
            $res = 'error';
            if($newEmail){
                /**Manage Uploaded Files**/
                if($request->has('uploaded-file')){
                    foreach ($request->file('uploaded-file') as $key => $value) {
                        $fileDetails = $request->file('uploaded-file')[$key];
                        $filePaths = time().$fileDetails->getClientOriginalName();

                        //store the file now
                        $pathOne = $fileDetails->storeAs('public/docs/emails', $filePaths, 'local');
                        if($pathOne){
                            /**Store the Info into the Documents table **/
                            EmailAttachment::create([
                                'email_id' => $newEmail->id,
                                'path' => $pathOne,
                            ]);
                        }
                    }
                }

                /**From Above, we have our address as an array: We loop through the Address**/
                foreach ($toAddress as $recipient) {
                    Mail::to($recipient)->cc($ccAddress)->bcc($bccAddress)->send(new SendEmailFromSystem($user, $body, $subject, $newEmail));

                    /**We can check to see if the Email Recipient is in our DB**/
                    $recipientInDb = User::where('smtp_email', $recipient)->first();
                    if(!empty($recipientInDb)){
                        /**At this Point we know that the Recipient is in our Database: Store the Record to appear as an inbox**/
                        /**In future we will add the Notification Part to this**/
                        EmailRecipient::create(
                            [
                                'email_id' => $newEmail->id,
                                'recipient_id' => $recipientInDb->id,
                                'to' => $recipient //This will carry the Email itself for the person receiving the Email
                            ]
                        );
                    }
                }
                /**At this Point, if the cc and bcc are in our Database, store the email in the System inbox**/
                //cc
                if($ccAddress != null){
                    foreach ($ccAddress as $ccRecipient) {
                        /**We can check to see if the Email Recipient is in our DB**/
                        $recipientInDb = User::where('smtp_email', $ccRecipient)->first();
                        if(!empty($recipientInDb)){
                            /**At this Point we know that the Recipient is in our Database: Store the Record to appear as an inbox**/
                            /**In future we will add the Notification Part to this**/
                            EmailRecipient::create(
                                [
                                    'email_id' => $newEmail->id,
                                    'recipient_id' => $recipientInDb->id,
                                    'to' => $ccRecipient //This will carry the Email itself for the person cced the Email
                                ]
                            );
                        }
                    }
                }
                //bcc
                if($bccAddress != null){
                    foreach ($bccAddress as $bccRecipient) {
                        /**We can check to see if the Email Recipient is in our DB**/
                        $recipientInDb = User::where('smtp_email', $bccRecipient)->first();
                        if(!empty($recipientInDb)){
                            /**At this Point we know that the Recipient is in our Database: Store the Record to appear as an inbox**/
                            /**In future we will add the Notification Part to this**/
                            EmailRecipient::create(
                                [
                                    'email_id' => $newEmail->id,
                                    'recipient_id' => $recipientInDb->id,
                                    'to' => $bccRecipient //This will carry the Email itself for the person bcced the Email
                                ]
                            );
                        }
                    }
                }
                $res = 'success';
            }
        }
        return $res;
    }

    /**A function to create a New Email Group**/
    public function showEmailGroups()
    {
        $groups = EmailGroup::orderBy('name', 'ASC')->get();
        return view('emails.email-groups', compact('groups'));
    }


    /**Show window to create a new Email Group**/
    public function showCreateNewEmailGroup()
    {
        return view('emails.add-new-email-group');
    }

    /**Store Details for the Entered Email Group**/
    public function storeCreateNewEmailGroup(Request $request){
        $name = $request['name'];
        $details = $request['details'];
        $res = 'error';
        if(!empty($name)){
            if(!empty($details)){
                $res = 'name exists';
                if(!EmailGroup::where('name', $name)->first()){
                    /**We prepare to insert it into the Database**/
                    $insert = EmailGroup::create(
                        [
                           'name' => $name,
                           'details' => $details,
                           'created_by' => auth()->user()->id
                        ]
                    );
                    if($insert){
                        $res = 'success';
                    }
                }
            }
        }
        return $res;
    }

    /**Show window to create a new Email to an Email Group**/
    public function showCreateNewEmailToEmailGroup($id)
    {
        return view('emails.add-new-email-to-email-group', compact('id'));
    }

    /**Store the Entered Email into the database**/
    public function storeCreateNewEmailToEmailGroup($id,Request $request){
        $email = $request['email'];
        $emailType = $request['type'];

        $res = 'error';
        if(!empty($email)){
            $res = 'empty type';
            if(!empty($emailType)){
                $res = 'email exists';
                if(!EmailGroupList::where('group_id', $id)->where('email', $email)->first()){
                    /**We prepare to insert it into the Database**/
                    $insert = EmailGroupList::create(
                        [
                            'group_id' => $id,
                            'email' => $email,
                            'email_type' => $emailType,
                            'created_by' => auth()->user()->id
                        ]
                    );
                    if($insert){
                        $res = 'success';
                    }
                }
            }
        }
        return $res;
    }

    /**Create a Function that will be used to view a List of all emails on an Email Group**/
    public function viewAvailableEmailsOnEmailGroup($id)
    {
        $group = EmailGroup::where('id', $id)->first();

        return view('emails.view-email-group-emails', compact('group'));
    }

    /**Create a Function that will be used to return the List of the Selected Group Email**/
    public function getGroupEmailList($id)
    {
        $group = EmailGroup::find($id);
        $to = "";
        $cc = "";
        $bcc = "";
        if($group != null){
            foreach ($group->groupEmails as $row){
                /**Here, we loop through all the email and make an array of the values**/
                if($row->email_type == 'to'){
                    $to .= $row->email.";";
                }elseif ($row->email_type == 'cc'){
                    $cc .= $row->email.";";
                }elseif ($row->email_type == 'bcc'){
                    $bcc .= $row->email.";";
                }
            }
        }
        /**Form an Array of the three**/
        $data = [
            'to' => rtrim($to, ";"),
            'cc' => rtrim($cc, ";"),
            'bcc' => rtrim($bcc, ";"),
        ];

        /**We trim the last ; from the generated string and return the value**/
        return response()->json($data);
    }

    /**Create a Function that will be used to Display unread Emails Count**/
    public function getUnreadEmails()
    {
        return EmailRecipient::where('recipient_id', auth()->user()->id)->where('read', 0)->get()->count();
    }

    /**Return Page to View your Inbox**/
    public function viewMyEmailInbox()
    {
        $inbox = EmailRecipient::where('recipient_id', auth()->user()->id)->orderBy('created_at', 'desc')->get();

        return view('emails.email-inbox', compact('inbox'));
    }

    /**Get EMail Details to be Displayed in the System**/
    public function getEmailDetails($id)
    {
        /**We first get the Recipients Details**/
        $recipient = EmailRecipient::findOrFail($id);

        $email = Email::findOrFail($recipient->email_id);
        $details = "";
        /**We First Bind the From Details to the Variable**/
        if($email != null){
            /**At this Point, we can mark the Email as Read for this signed in User**/
            if($recipient->read == 0){
                /**We will now mark the Email as read for this specific User**/
                $recipient->update(['read' => 1]);
            }

            /**Prepare to Display your Email to the User**/
            $details .='<div style="margin: 10px">';
            $details .= '<table style="width: 100%; border-collapse: collapse">';
            $details .= '<tr>';
            $details .= '<th>From:</th>';
            $details .= '<th>'.$email->from.'</th>';
            $details .= '</tr>';
            $details .= '<tr>';
            $details .= '<th>To:</th>';
            $details .= '<th>'.$email->to.'</th>';
            $details .= '</tr>';
            /**Check if cc is not Null**/
            if($email->cc != null){
                $details .= '<tr>';
                $details .= '<th>Cc:</th>';
                $details .= '<th>'.$email->cc.'</th>';
                $details .= '</tr>';
            }
            /**Check also if bcc is not Null**/
            if($email->bcc != null){
                $details .= '<tr>';
                $details .= '<th>Bcc:</th>';
                $details .= '<th>'.$email->bcc.'</th>';
                $details .= '</tr>';
            }
            /**Prepare to Display the Subject of the Email**/
            $details .= '<tr>';
            $details .= '<th>SUBJECT:</th>';
            $details .= '<th ><u style="font-size: 18px">'.$email->subject.'</u> <span style="float: right;color: #a29191">'.date(DATE_RFC822, strtotime($email->created_at)).'</span></th>';
            $details .= '</tr>';
            $details .= '</table>';

            /**Prepare to Display any attached Documents**/
            if(count($email->attachments) > 0){
                $details .= '<tr>';
                $details .= '<th><b>Attachments</b>:</th>';
                $details .= '<th><u>';
                foreach ($email->attachments as $attachment){
                    $path = explode('/', $attachment->path);
                    $timeStamped = end($path);
                    $details .= '<a href="'.asset('/storage'.preg_replace('/public/', "", $attachment->path)). '" style="color: #525151" target="_blank">' .substr($timeStamped,10).'</a>;<br>';
                }
                $details .= '</u></th>';
                $details .= '</tr>';
                $details .= '</table>';
            }


            $details .= '<div class="guestDetails_inputDivider"></div>';
            /**Prepare to Display the Body of the Email now**/
            $details .= $email->body;
            $details .= '<div>';
        }
        return $details;
    }

    /**Return Page to View your Inbox**/
    public function viewMyEmailOutbox()
    {
        $outbox = Email::where('sent_by', auth()->user()->id)->orderBy('created_at', 'desc')->get();

        return view('emails.email-outbox', compact('outbox'));
    }

    /**Get EMail Details to be Displayed in the System**/
    public function getEmailOutboxDetails($id)
    {
        $email = Email::findOrFail($id);
        $details = "";
        /**We First Bind the From Details to the Variable**/
        if($email != null){
            /**Prepare to Display your Email to the User**/
            $details .='<div style="margin: 10px">';
            $details .= '<table style="width: 100%; border-collapse: collapse">';
            $details .= '<tr>';
            $details .= '<th>From:</th>';
            $details .= '<th>'.$email->from.'</th>';
            $details .= '</tr>';
            $details .= '<tr>';
            $details .= '<th>To:</th>';
            $details .= '<th>'.$email->to.'</th>';
            $details .= '</tr>';
            /**Check if cc is not Null**/
            if($email->cc != null){
                $details .= '<tr>';
                $details .= '<th>Cc:</th>';
                $details .= '<th>'.$email->cc.'</th>';
                $details .= '</tr>';
            }
            /**Check also if bcc is not Null**/
            if($email->bcc != null){
                $details .= '<tr>';
                $details .= '<th>Bcc:</th>';
                $details .= '<th>'.$email->bcc.'</th>';
                $details .= '</tr>';
            }
            /**Prepare to Display the Subject of the Email**/
            $details .= '<tr>';
            $details .= '<th>SUBJECT:</th>';
            $details .= '<th ><u style="font-size: 18px">'.$email->subject.'</u> <span style="float: right;color: #a29191">'.date(DATE_RFC822, strtotime($email->created_at)).'</span></th>';
            $details .= '</tr>';
            $details .= '</table>';

            /**Prepare to Display any attached Documents**/
            if(count($email->attachments) > 0){
                $details .= '<tr>';
                $details .= '<th><b>Attachments</b>:</th>';
                $details .= '<th><u>';
                foreach ($email->attachments as $attachment){
                    $path = explode('/', $attachment->path);
                    $timeStamped = end($path);
                    $details .= '<a href="'.asset('/storage'.preg_replace('/public/', "", $attachment->path)). '" style="color: #525151" target="_blank">' .substr($timeStamped,10).'</a>;<br>';
                }
                $details .= '</u></th>';
                $details .= '</tr>';
                $details .= '</table>';
            }

            $details .= '<div class="guestDetails_inputDivider"></div>';
            /**Prepare to Display the Body of the Email now**/
            $details .= $email->body;
            $details .= '<div>';
        }
        return $details;
    }

    /**Getting the List of Outbox Emails with the Search Parameters**/
    public function getOutboxEmailsFromSearching($criteria, $parameter)
    {
        $emails = [];
        if($criteria == 'subject'){
            /**We will be searching the Subject Section**/
            $emails = Email::where('subject', 'LIKE', '%'.$parameter.'%')->orderBy('created_at', 'desc')->get();
        }elseif ($criteria == 'body'){
            $emails = Email::where('body', 'LIKE', '%'.$parameter.'%')->orderBy('created_at', 'desc')->get();
        }elseif ($criteria == 'from'){
            $emails = Email::where('from', 'LIKE', '%'.$parameter.'%')->orderBy('created_at', 'desc')->get();
        }elseif ($criteria == 'to'){
            $emails = Email::where('to', 'LIKE', '%'.$parameter.'%')->orderBy('created_at', 'desc')->get();
        }elseif ($criteria == 'cc'){
            $emails = Email::where('cc', 'LIKE', '%'.$parameter.'%')->orderBy('created_at', 'desc')->get();
        }elseif ($criteria == 'bcc'){
            $emails = Email::where('bcc', 'LIKE', '%'.$parameter.'%')->orderBy('created_at', 'desc')->get();
        }
        /**Since we have our Emails now, we prepare to Display the results**/
        $details = "";
        if(count($emails) > 0){
            foreach ($emails as $row){
                $details .= '<div class="display-my-email" onclick="viewEmailDetails('.$row->id.')">';
                $details .= '<ul>';
                $details .= '<li><b>'.substr($row->subject,0, 20).'</b><br></li>';
                $details .= '<li>'.substr($row->body,0, 50).'</li>';
                $details .= ' <li style="text-align: right; margin-right: 5px"><b style="color: #a29191" >'.date(DATE_RFC822, strtotime($row->created_at)).'</b></li>';
                $details .= '</ul>';
                $details .= '<hr>';
                $details .= '</div>';
            }
        }
        return $details;
    }

    /**Getting the List of Inbox Emails with the Search Parameters**/
    public function getInboxEmailsFromSearching($criteria, $parameter)
    {
        $emails = [];
        if($criteria == 'subject'){
            /**We will be searching the Subject Section**/
            $emails = Email::where('subject', 'LIKE', '%'.$parameter.'%')->orderBy('created_at', 'desc')->get();
        }elseif ($criteria == 'body'){
            $emails = Email::where('body', 'LIKE', '%'.$parameter.'%')->orderBy('created_at', 'desc')->get();
        }elseif ($criteria == 'from'){
            $emails = Email::where('from', 'LIKE', '%'.$parameter.'%')->orderBy('created_at', 'desc')->get();
        }elseif ($criteria == 'to'){
            $emails = Email::where('to', 'LIKE', '%'.$parameter.'%')->orderBy('created_at', 'desc')->get();
        }elseif ($criteria == 'cc'){
            $emails = Email::where('cc', 'LIKE', '%'.$parameter.'%')->orderBy('created_at', 'desc')->get();
        }elseif ($criteria == 'bcc'){
            $emails = Email::where('bcc', 'LIKE', '%'.$parameter.'%')->orderBy('created_at', 'desc')->get();
        }
        /**Since we have our Emails now, we prepare to Display the results**/
        $details = "";
        if(count($emails) > 0){
            foreach ($emails as $row){
                /**After looping through, ensure that the email exists under the recipient from the Database**/
                $recipientDetails = EmailRecipient::where('recipient_id', auth()->user()->id)->where('email_id', $row->id)->first();
                if($recipientDetails){
                    if($recipientDetails->read == 1){
                        $details .= '<div class="display-my-email read" onclick="viewEmailDetails('.$row->id.')">';
                    }else{
                        $details .= '<div class="display-my-email not-read" onclick="viewEmailDetails('.$row->id.')">';
                    }
                    $details .= '<ul>';
                    $details .= '<li><b>'.substr($row->subject,0, 20).'</b><br></li>';
                    $details .= '<li>'.substr($row->body,0, 50).'</li>';
                    $details .= ' <li style="text-align: right; margin-right: 5px"><b style="color: #a29191" >'.date(DATE_RFC822, strtotime($row->created_at)).'</b></li>';
                    $details .= '</ul>';
                    $details .= '<hr>';
                    $details .= '</div>';
                }
            }
        }
        return $details;
    }

    /**Updating Email Signature**/
    public function showMyEmailSignature()
    {
        $signature = EmailSignature::where('user_id', auth()->user()->id)->first();
        return view('emails.my-email-signature', compact('signature'));
    }

    /**Function to Store the Signature into the Database**/
    public function storeMyEmailSignature(Request $request)
    {
        $details = $request['signature'];
        $res = 'error';
        if(!empty($details)){
            /**We prepare to store the Signature into the Database**/
            if(!EmailSignature::where('user_id', auth()->user()->id)->first()){
                /**Here, we create the Signature**/
                $storeSignature = EmailSignature::create(
                    [
                        'user_id' => auth()->user()->id,
                        'signature' => $details
                    ]
                );
            }else{
                $storeSignature = EmailSignature::where('user_id', auth()->user()->id)->update(
                    [
                        'user_id' => auth()->user()->id,
                        'signature' => $details
                    ]
                );
            }

            if($storeSignature){
                $res = 'success';
            }
        }
        return $res;
    }

}
