<?php
namespace laravelLara\lskllc\Commands;

use App\Events\ChatMessageEvent;
use App\Events\LiveNotification;
use App\Jobs\MailSend;
use Illuminate\Console\Command;
use App\Models\Ticket\Ticket;
use App\Models\User;
use App\Models\CustomerSetting;
use Mail;
use App\Notifications\TicketCreateNotifications;
use \Webklex\IMAP\Facades\Client;
use Illuminate\Support\Facades\Auth;
use File;
use Illuminate\Support\Str;
use App\Models\Ticket\Comment;
use App\Models\CCMAILS;
use App\Models\EmailTemplate;
use App\Models\Holiday;
use Carbon\Carbon;
use Symfony\Component\Mime\Email;
use App\Models\LiveChatCustomers;


class ProcessEmailToTicket extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'process:emailtoticket';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        if (setting('IMAP_STATUS') == 'on') {

            $imap_username = setting('IMAP_USERNAME');
            $client = Client::make([
                'host'          => setting('IMAP_HOST'),
                'port'          => setting('IMAP_PORT'),
                'encryption'    => setting('IMAP_ENCRYPTION'),
                'validate_cert' => true,
                'username'      => setting('IMAP_USERNAME'),
                'password'      => setting('IMAP_PASSWORD'),
                'protocol'      => setting('IMAP_PROTOCOL')
            ]);

            $client->connect();

            $aFolder = $client->getFolders();
            foreach ($aFolder as $folder) {
                foreach ($folder->messages()->unseen()->get() as $message) {
                    $userexits = LiveChatCustomers::where('email', $message->getFrom()[0]->mail)->count();

                    if ($userexits == 1) {
                        $guest = LiveChatCustomers::where('email', $message->getFrom()[0]->mail)->first();
                    } else {
                        if ($message->getFrom()[0]->personal == '') {
                            $guestusername = 'Guest';
                        } else {
                            $guestusername = $message->getFrom()[0]->personal;
                        }
                        $guest = LiveChatCustomers::create([

                            'firstname' => '',
                            'lastname' => '',
                            'username' => $guestusername,
                            'email' => $message->getFrom()[0]->mail,
                            'userType' => 'Guest',
                            'password' => null,
                            'country' => '',
                            'timezone' => 'UTC',
                            'status' => '1',
                            'image' => null,

                        ]);
                        $customersetting = new CustomerSetting();
                        $customersetting->custs_id = $guest->id;
                        $customersetting->save();
                    }

                    $body = $message->getHTMLBody(true);

                    $stripped_body = $message->getTextBody();

                    $today = Carbon::today();
                    $holidays = Holiday::whereDate('startdate', '<=', $today)->whereDate('enddate', '>=', $today)->where('status', '1')->get();

                    $originalMessageId = null;
                    $rawHeaders = $message->header->raw;

                    if (preg_match('/Message-ID:\s*<(.*?)>/i', $rawHeaders, $matches)) {
                        $originalMessageId = $matches[1];
                    }

                    if (preg_match('/Message-ID:\s?<(.+?)>/i', $rawHeaders, $matches)) {
                        $originalMessageId = $matches[1];
                    }

                    if (Str::contains($message->getSubject(), "Delivery Status Notification (Failure)") === true) {
                        $message->setFlag('SEEN');
                    }

                    if (Str::contains($message->getSubject(), "Undeliverable: Invalid") === true) {
                        $message->setFlag('SEEN');
                    }

                    if (Str::contains($message->getSubject(), "Mail delivery failed: returning message to sender") === true) {
                        $message->setFlag('SEEN');
                    }

                    if (strpos(strtolower($message->getSubject()), 're:') === 0 || strpos($message->getSubject(), 'Ats.:') === 0 || strpos($message->getSubject(), '回复:') === 0 || strpos($message->getSubject(), '回覆:') === 0) {
                        if (Str::contains($message->getSubject(), "Re: ") === true) {
                            $explodedsub = explode("Re: ", $message->getSubject());
                        } elseif (Str::contains($message->getSubject(), "Ats.: ") === true) {
                            $explodedsub = explode("Ats.: ", $message->getSubject());
                        } elseif (Str::contains($message->getSubject(), "回复: ") === true) {
                            $explodedsub = explode("回复: ", $message->getSubject());
                        } elseif (Str::contains($message->getSubject(), "回覆: ") === true) {
                            $explodedsub = explode("回覆: ", $message->getSubject());
                        } else {
                            $explodedsub = explode("RE: ", $message->getSubject());
                        }

                        $checktic = Ticket::where('cust_id', $guest->id)->where('subject', $explodedsub[1])->first();

                        if ($checktic != null) {
                            $commentexists = $checktic->comments()->first();
                            if ($commentexists != null) {
                                $dateday = $commentexists->created_at->format("D");
                                $datefullday = $commentexists->created_at->format('l, F j, Y');
                                $dateyahoo = $commentexists->created_at->format('l, j F, Y');
                            } else {
                                $dateday = $checktic->created_at->format("D");
                                $datefullday = $checktic->created_at->format('l, F j, Y');
                                $dateyahoo = $checktic->created_at->format('l, j F, Y');
                            }

                            $url = url('/');
                            $url2 = url('guest/ticket-view/details/');

                            if ($checktic->status == 'Closed') {
                                $ticketData = [
                                    'ticket_id' => $checktic->ticket_id,
                                    'ticket_username' => $checktic->cust->username,
                                    'ticket_title' => $checktic->subject,
                                    'ticket_description' => $checktic->message,
                                    'url' => url('/'),
                                    'ticket_category' => $checktic->category != null ? $checktic->category->name : 'Category not available',
                                    'item_name' => $checktic->item_name != null ? $checktic->item_name : 'Item Name not available',
                                ];

                                try {
                                    $replySubject = 'Re: ' . $message->getSubject();
                                    $emailtemplate = EmailTemplate::where('code', 'send_a_reply_to_the_customer_when_a_customer_responds_to_a_closed_email_ticket')->first();
                                    $body = $emailtemplate->body;

                                    foreach ($ticketData as $key => $value) {
                                        $body = str_replace('{{' . $key . '}}', $value, $body);
                                        $body = str_replace('{{ ' . $key . ' }}', $value, $body);
                                    }


                                    $email = (new Email())->html($body);

                                    Mail::raw('', function ($message) use ($email, $checktic, $imap_username, $replySubject) {
                                        $message->from($imap_username)
                                            ->to($checktic->cust->email)
                                            ->subject($replySubject)
                                            ->getHeaders()->addTextHeader('In-Reply-To', '<' . $checktic->MessageID . '>');

                                        $message->getHeaders()->addTextHeader('References', '<' . $checktic->MessageID . '>');
                                        $message->setBody($email->getBody(), 'text/html');
                                    });
                                } catch (\Exception $e) {
                                }

                                $message->setFlag('SEEN');
                            } else {
                                $sender = $message->header->get('sender')->first();
                                $host = $sender->host;
                                $senderMail = $sender->mail;

                                $year = date('Y', strtotime($message->getDate()));


                                $emailLines = explode("\r\n", $stripped_body);

                                $emailLineByLine = [];

                                foreach ($emailLines as $line) {

                                    $parts = explode("\u{A0}", $line);
                                    $emailLineByLine = array_merge($emailLineByLine, $parts);
                                }


                                if(strpos($emailLineByLine[0],$imap_username) !== false  && strpos($emailLineByLine[0],$year) !== false ){  //web mails

                                    $emailtemplate = EmailTemplate::where('code', 'customer_send_ticket_created')->first();

                                    $body = $emailtemplate->body;

                                    $explodedbody = explode('<p>', $body);
                                    $stripexplodedbody = strip_tags(end($explodedbody));
                                    $stripped_body_exploded = explode($stripexplodedbody, $stripped_body);
                                    $stripped_body_exploded_end = end($stripped_body_exploded);
                                    if (Str::contains($stripped_body_exploded_end, $url2) === true) {
                                        $finalexplode1 = explode($url, $stripped_body_exploded_end);
                                        $finalexplode2 = explode("\r\n", end($finalexplode1));
                                        array_shift($finalexplode2);
                                        $finalcomment = implode("\r\n", $finalexplode2);
                                    } else {
                                        $finalcomment = $stripped_body_exploded_end;
                                    }

                                }else{
                                        if (Str::contains($stripped_body, "\r\n________________________________\r\n") === true) {      //FROM BROWSER OUTLOOK MAIL  or hot mail
                                            $alltimefromtwo = explode("\r\n________________________________\r\n", $stripped_body);
                                            $finalcomment = $alltimefromtwo[0];
                                        }else if (Str::contains($stripped_body, "-----Original Message-----") === true) {
                                                $alltimefromone = explode("-----Original Message-----", $stripped_body);
                                                $finalcomment = $alltimefromone[0];
                                        }elseif (Str::contains($stripped_body, "From: $imap_username [mailto:$imap_username]") === true) {   //NORMAL OUTLOOK MAIL

                                            $alltimefromthree = explode("From: $imap_username [mailto:$imap_username]", $stripped_body);
                                            $finalcomment = $alltimefromthree[0];
                                        }elseif (Str::contains($stripped_body, "Sent from Mailspring (https://getmailspring.com/), the best free email app for work") === true) {   //Mail spring

                                            $fromMailspring = explode("Sent from Mailspring (https://getmailspring.com/), the best free email app for work", $stripped_body);
                                            $finalcomment = $fromMailspring[0];
                                        }
                                        elseif (Str::contains($stripped_body, "[1] $url\r\n") === true) {
                                            $alltimeoutlook = explode("[1] $url\r\n", $stripped_body);
                                            $finalcomment = $alltimeoutlook[1];
                                        }else{              //ZOHO MAIL  //AOL MAIL  //GMAIL

                                            $replyLines = [];
                                            foreach($emailLineByLine as $emailLine){
                                                if((strpos($emailLine,$imap_username) !== false || strpos($emailLine,$senderMail) !== false)  && strpos($emailLine,$year) !== false){

                                                    $parts = preg_split('/\s{2,}/', $emailLine);                          //YAHOO MAIL
                                                    foreach($parts as $part){
                                                        if((strpos($part,$imap_username) !== false || strpos($part,$senderMail) !== false)  && strpos($part,$year) !== false){
                                                                break;
                                                        }else{
                                                            $replyLines[] =  $part;
                                                        }
                                                    }
                                                    break;
                                                }else{

                                                    $replyLines[] =  $emailLine;

                                                }

                                            }

                                            $finalcomment = implode("\r\n",$replyLines);
                                        }

                                }

                                if(strpos($host,'zohomail') !== false ){
                                    if(str_contains($finalcomment,"Sent using \r\n")){
                                        $final = explode("Sent using \r\n",$finalcomment);
                                        $finalcomment = $final[0];
                                    }
                                }

                                if ($checktic->comments()->get() != null) {
                                    $comm = $checktic->comments()->update([
                                        'display' => null
                                    ]);
                                }

                                $comment = new Comment();
                                $comment->ticket_id = $checktic->id;
                                $comment->cust_id = $guest->id;
                                $comment->user_id = null;
                                $comment->display = 1;
                                $comment->comment = $finalcomment;
                                $comment->save();

                                $comment = Comment::find($comment->id);
                                if($guest->file_upload_permission == 1){
                                    $finalfile = [];
                                    $attachedfiles = $message->getAttachments();
                                    foreach ($attachedfiles as $attachedfile) {
                                        array_push($finalfile, $comment->id . "_" . $attachedfile->name);
                                    }
                                    $newArr = implode(",", $finalfile);
                                    $comment->emailcommentfile =  $newArr != "" ? $newArr : null;

                                    $message->getAttachments()->each(function ($oAttachment) use ($message, $comment) {
                                        $provider = storage()->provider;
                                        $upload =  $provider::emailtoticket('uploads/emailtoticketcomment' . '/' . $comment->id . "_" . $oAttachment->name, $oAttachment);
                                    });
                                    $comment->storage_disk = storage()->storage_disk;
                                    $comment->save();
                                }


                                $commentupdate = Comment::find($comment->id);
                                if ($commentupdate->emailcommentfile != null) {
                                    if($guest->file_upload_permission != 1){
                                        $commentupdate->emailcommentfile = 'nopermission';
                                        $commentupdate->update();
                                    }else{
                                        $arraytype = explode(',', $commentupdate->emailcommentfile);
                                        foreach ($arraytype as $arraytypes) {
                                            $file_path = public_path('uploads/emailtoticketcomment/' . $arraytypes);
                                            // $file_size = File::size($file_path) / 1024 / 1024;

                                            if(str_contains($arraytypes,".")){
                                                $attachexten = explode(".", $arraytypes);
                                                $attachextenfinal = $attachexten[1];
                                            }else{
                                                $attachextenfinal = 'notspecifiedimage';
                                            }
                                            $appliexten = explode(",", setting('FILE_UPLOAD_TYPES'));
                                            $appliextenfinal = Str::remove('.', $appliexten);
                                            if (!in_array($attachextenfinal, $appliextenfinal) || File::size($file_path) / 1024 / 1024 > setting('FILE_UPLOAD_MAX') || count($arraytype) > setting('MAX_FILE_UPLOAD')) {
                                                $commentupdate->emailcommentfile = 'mismatch';
                                                $commentupdate->update();
                                                File::delete($file_path);
                                                if (storage()->storage_disk != "public")
                                                    storage()->provider::delete('uploads/emailtoticketcomment/' . $arraytypes);
                                            }
                                            if (storage()->storage_disk != "public")
                                                if (File::exists($file_path)) {
                                                    File::delete($file_path);
                                                }
                                        }
                                    }
                                }

                                $ticket = Ticket::find($checktic->id);
                                $ticket->last_reply = now();

                                if (setting('AUTO_OVERDUE_TICKET') == 'no') {
                                    $ticket->auto_overdue_ticket = null;
                                    $ticket->overduestatus = null;
                                } else {
                                    if (setting('AUTO_OVERDUE_TICKET_TIME') == '0') {
                                        $ticket->auto_overdue_ticket = null;
                                        $ticket->overduestatus = null;
                                    } else {
                                        if ($ticket->status == 'Closed') {
                                            $ticket->auto_overdue_ticket = null;
                                            $ticket->overduestatus = null;
                                        } else {
                                            $ticket->auto_overdue_ticket = now()->addDays(setting('AUTO_OVERDUE_TICKET_TIME'));
                                            $ticket->overduestatus = null;
                                        }
                                    }
                                }

                                if (setting('AUTO_CLOSE_TICKET') == 'no') {
                                    $ticket->auto_close_ticket = null;
                                } else {
                                    if (setting('AUTO_CLOSE_TICKET_TIME') == '0') {
                                        $ticket->auto_close_ticket = null;
                                    } else {
                                        if ($guest->userType == 'livechat') {
                                            $ticket->auto_close_ticket = null;
                                        }
                                    }
                                }

                                if (setting('AUTO_RESPONSETIME_TICKET') == 'no') {
                                    $ticket->auto_replystatus = null;
                                } else {
                                    if (setting('AUTO_RESPONSETIME_TICKET_TIME') == '0') {
                                        $ticket->auto_replystatus = null;
                                    } else {
                                        if ($guest->userType == 'livechat') {
                                            $ticket->auto_replystatus = null;
                                        }
                                    }
                                }
                                if ($comment->cust->userType == 'Guest') {
                                    $username = 'Guest';
                                } else {
                                    $username = $comment->cust->username;
                                }

                                $ticket->replystatus = 'Replied';
                                $ticket->update();

                                $ccemailsend = CCMAILS::where('ticket_id', $ticket->id)->first();

                                $ticketData = [
                                    'ticket_username' => $ticket->cust->username,
                                    'ticket_title' => $ticket->subject,
                                    'ticket_id' => $ticket->ticket_id,
                                    'ticket_status' => $ticket->status,
                                    'comment' => $comment->comment,
                                    'ticket_admin_url' => fetchticketviewurl($ticket),
                                    'ticket_category' => $ticket->category != null ? $ticket->category->name : 'Category not available',
                                    'item_name' => $ticket->item_name != null ? $ticket->item_name : 'Item Name not available',
                                ];

                                try {

                                    $commentData = [
                                        'ticket_id' => $ticket->ticket_id,
                                        'ticket_username' => $ticket->cust->username,
                                        'ticket_title' => $ticket->subject,
                                        'ticket_file_format' => setting('FILE_UPLOAD_TYPES'),
                                        'ticket_file_size' => setting('FILE_UPLOAD_MAX'),
                                        'ticket_file_count' => setting('MAX_FILE_UPLOAD'),
                                        'ticket_description' => $ticket->message,
                                        'ticket_category' => $ticket->category != null ? $ticket->category->name : 'Category not available',
                                        'item_name' => $ticket->item_name != null ? $ticket->item_name : 'Item Name not available',
                                    ];

                                    $replySubject = 'Re: ' . $ticket->subject;
                                    if ($commentupdate->emailcommentfile == 'mismatch' || $commentupdate->emailcommentfile == 'nopermission') {
                                        if($commentupdate->emailcommentfile == 'nopermission'){
                                            $templateCode = 'send_mail_to_customer_when_does_not_has_fileupload_permission';
                                        }else{
                                            $templateCode = 'customer_send_guestticket_created_with_attachment_failed';
                                        }
                                        $emailtemplate = EmailTemplate::where('code', $templateCode)->first();
                                        $body = $emailtemplate->body;

                                        foreach ($commentData as $key => $value) {
                                            $body = str_replace('{{' . $key . '}}', $value, $body);
                                            $body = str_replace('{{ ' . $key . ' }}', $value, $body);
                                        }

                                        $email = (new Email())->html($body);

                                        Mail::raw('', function ($message) use ($email, $ticket, $imap_username, $replySubject) {
                                            $message->from($imap_username)
                                                ->to($ticket->cust->email)
                                                ->subject($replySubject)
                                                ->getHeaders()->addTextHeader('In-Reply-To', '<' . $ticket->MessageID . '>');

                                            $message->getHeaders()->addTextHeader('References', '<' . $ticket->MessageID . '>');
                                            $message->setBody($email->getBody(), 'text/html');
                                        });
                                    }

                                    if ($holidays->isNotEmpty()) {
                                        $emailtemplate = EmailTemplate::where('code', 'customer_send_ticket_created_that_holiday_or_announcement')->first();

                                        $body = $emailtemplate->body;

                                        foreach ($commentData as $key => $value) {
                                            $body = str_replace('{{' . $key . '}}', $value, $body);
                                            $body = str_replace('{{ ' . $key . ' }}', $value, $body);
                                        }


                                        $email = (new Email())->html($body);

                                        Mail::raw('', function ($message) use ($email, $ticket, $imap_username, $replySubject) {
                                            $message->from($imap_username)
                                                ->to($ticket->cust->email)
                                                ->subject($replySubject)
                                                ->getHeaders()->addTextHeader('In-Reply-To', '<' . $ticket->MessageID . '>');

                                            $message->getHeaders()->addTextHeader('References', '<' . $ticket->MessageID . '>');
                                            $message->setBody($email->getBody(), 'text/html');
                                        });
                                    }

                                    if($comment->emailcommentfile == 'mismatch'){
                                        $comment->image_url = null;
                                    }elseif($comment->emailcommentfile == 'nopermission'){
                                        $comment->image_url = null;
                                    }else{
                                        if($comment->emailcommentfile != null){
                                            $emailcommentfiles = explode(',', $comment->emailcommentfile);
                                            $imageurl = [];
                                            foreach($emailcommentfiles as $emailcommentfile){
                                                $provider  = existprovider($comment->storage_disk ?? 'public')->provider;
                                                array_push($imageurl,asset('/uploads/emailtoticketcomment/' . $emailcommentfile));
                                            }
                                            $comment->image_url = $imageurl;
                                        }
                                    }
                                    $comment->profile_bg_color = $ticket->profile_bg_color;

                                    $assigneuser = User::find($ticket->selfassignuser_id);
                                    if($assigneuser != null){
                                        $assigneuser->notify(new TicketCreateNotifications($ticket));
                                        $ticketviewurl = fetchticketviaautoviewurl($ticket,$assigneuser->id);
                                        $ticketData['ticket_admin_url'] = $ticketviewurl;
                                        event(new LiveNotification('You got new reply for the ticket no ' . $ticket->ticket_id,$assigneuser,$ticket,$ticketviewurl));
                                        if($assigneuser->usetting->emailnotifyon == 1){
                                            dispatch((new MailSend($assigneuser->email, 'admin_send_email_ticket_reply', $ticketData)));
                                        }
                                    }

                                    $users = User::get();
                                    foreach($users as $user){
                                        if($user->can('All Tickets') && $user->usetting->emailnotifyon == 1 && $user->id != $ticket->selfassignuser_id){
                                            $user->notify(new TicketCreateNotifications($ticket));
                                            $userticketviewurl = fetchticketviaautoviewurl($ticket,$user->id);
                                            $ticketData['ticket_admin_url'] = $userticketviewurl;
                                            event(new LiveNotification('You got new reply for the ticket no ' . $ticket->ticket_id,$user,$ticket,$userticketviewurl));
                                            dispatch((new MailSend($user->email, 'admin_send_email_ticket_reply', $ticketData)));
                                        }
                                    }

                                    event(new ChatMessageEvent(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,$ticket->id,$ticket->cust->id,$comment,'ticketreply',$ticket->cust->username));
                                } catch (\Exception $e) {
                                }

                                $message->setFlag('SEEN');
                            }
                        } else {
                            try {
                                $replySubject = 'Re: ' . $explodedsub[1];
                                $emailtemplate = EmailTemplate::where('code', 'send_mail_customer_when_a_customer_responds_to_a_restricted_mails')->first();
                                $body = $emailtemplate->body;


                                $email = (new Email())->html($body);

                                Mail::raw('', function ($message) use ($email, $originalMessageId, $guest, $imap_username, $replySubject) {
                                    $message->from($imap_username)
                                        ->to($guest->email)
                                        ->subject($replySubject)
                                        ->getHeaders()->addTextHeader('In-Reply-To', '<' . $originalMessageId . '>');

                                    $message->getHeaders()->addTextHeader('References', '<' . $originalMessageId . '>');
                                    $message->setBody($email->getBody(), 'text/html');
                                });
                            } catch (\Exception $e) {
                            }

                            $message->setFlag('SEEN');
                        }
                    } else {
                        $message->setFlag('SEEN');
                    }

                }
            }

        }
    }
}