<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

use App\Jobs\MailSend;
use App\Models\CCMAILS;
use App\Models\Subcategorychild;
use App\Models\Ticket\Category;
use App\Models\Ticket\Ticket;
use App\Models\User;
use App\Notifications\TicketCreateNotifications;
use Mail;
use App\Models\CategoryEnvato;
use Carbon\Carbon;
use App\Models\Holiday;
use App\Models\LiveChatCustomers;
use App\Models\EmailTemplate;
use Symfony\Component\Mime\Email;
use Illuminate\Support\Str;
use App\Events\ChatMessageEvent;
use App\Events\LiveNotification;
use App\Models\CampaignUserList;
use Torann\GeoIP\Facades\GeoIP;
use Jenssegers\Agent\Agent;
use App\Models\EmployeeActivity;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Crypt;

class LivechatTicketController extends Controller
{
    public function chataticketcreate(Request $request)
    {
        $categories = CategoryEnvato::where('category_id',$request->category)->first();

        if(setting('ENVATO_ON') == 'on' && $categories != null){
            if($request->envato_id == 'undefined' || $request->envato_id == null || isset($request->envato_id) == false){
                return response()->json(['message' => 'envatoerror', 'error' => lang('Please enter valid purchasecode to create a ticket.', 'alerts')], 500);
            }
        }

        $subcategoriess = Subcategorychild::where('category_id', $request->category)->pluck('subcategory_id')->toArray();
        if($subcategoriess != null && $request->subscategory != null && !in_array($request->subscategory, $subcategoriess)){
            return response()->json(['message' => 'subcaterror', 'error' => lang('Please select correct subcategory to create a ticket.', 'alerts')], 500);
        }

        $this->validate($request, [
            'subject' => 'required|max:255',
            'category' => 'required',
            'message' => 'required',
            'assigneeid' => 'required',
            'email' => 'required|max:255|indisposable|email',
        ]);

        $email = $request->email;
        $completeDomain = substr(strrchr($email, "@"), 1);
        $emaildomainlist = setting('EMAILDOMAIN_LIST');
        $emaildomainlistArray = explode(",", $emaildomainlist);

        if (setting('EMAILDOMAIN_BLOCKTYPE') == 'blockemail') {

            if (setting('EMAILDOMAIN_LIST') == null) {
                $tickets = $this->validateemaildomain($request);

                event(new ChatMessageEvent(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,$tickets->id,$tickets->cust->id,$tickets,'ticketcreate',$tickets->cust->username));

                return response()->json(['description' => $tickets->message, 'subject' => $tickets->subject, 'id' => $tickets->id,'guest' => 'pass', 'data' => $tickets, 'success' => lang('A ticket has been opened with the ticket ID ', 'alerts') . $tickets->ticket_id], 200);

            } else {
                if (in_array($completeDomain, $emaildomainlistArray)) {

                    return response()->json(['message' => 'domainblock', 'error' => lang('Domain is Blocked List', 'alerts')], 500);
                }
                $tickets = $this->validateemaildomain($request);

                event(new ChatMessageEvent(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,$tickets->id,$tickets->cust->id,$tickets,'ticketcreate',$tickets->cust->username));

                return response()->json(['description' => $tickets->message, 'subject' => $tickets->subject, 'id' => $tickets->id,'guest' => 'pass', 'data' => $tickets, 'success' => lang('A ticket has been opened with the ticket ID ', 'alerts') . $tickets->ticket_id], 200);
            }
        }

        if (setting('EMAILDOMAIN_BLOCKTYPE') == 'allowemail') {
            if (setting('EMAILDOMAIN_LIST') == null) {
                $tickets = $this->validateemaildomain($request);

                event(new ChatMessageEvent(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,$tickets->id,$tickets->cust->id,$tickets,'ticketcreate',$tickets->cust->username));

                return response()->json(['guest' => 'pass', 'data' => $tickets, 'success' => lang('A ticket has been opened with the ticket ID', 'alerts') . $tickets->ticket_id], 200);
            } else {
                if (in_array($completeDomain, $emaildomainlistArray)) {

                    $tickets = $this->validateemaildomain($request);

                    event(new ChatMessageEvent(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,$tickets->id,$tickets->cust->id,$tickets,'ticketcreate',$tickets->cust->username));

                    return response()->json(['guest' => 'pass', 'data' => $tickets, 'success' => lang('A ticket has been opened with the ticket ID', 'alerts') . $tickets->ticket_id], 200);
                }
                return response()->json(['message' => 'domainblock', 'error' => lang('Domain is Blocked List', 'alerts')], 500);

            }
        }

    }

    private function validateemaildomain($request)
    {
        $guest = LiveChatCustomers::where('email', $request->email)->first();

        if (!$guest) {
            $custUniqueId = Str::random(9);
            $guest = new LiveChatCustomers();
            $guest->cust_unique_id = $custUniqueId;
            $guest->username = $request->has('customername') ? $request->customername : $custUniqueId;
            $guest->email = $request->email;
            $guest->userType = 'livechat';
            $guest->profile_bg_color = randomColorGenerator(0.5);
            $guest->save();

            CampaignUserList::create([
                'email' => $guest->email,
                'source' => 'Livechat',
                'batchName' => '',
            ]);
        }

        if ($guest) {
            $ticket = Ticket::create([
                'subject' => $request->input('subject'),
                'cust_id' => $guest->id,
                'user_id' => Auth::id(),
                'category_id' => $request->input('category'),
                'message' => $request->input('message'),
                'tickettype' => 'emalitoticket',
                'myassignuser_id' => $request->assigneeid == 'unassign' ? null : Auth::id(),
                'selfassignuser_id' => $request->assigneeid == 'unassign' ? null : $request->assigneeid,
                'MessageID' => str_random(10). 'livachattestingmailid' . str_random(10),
                'status' => 'New',
                'profile_bg_color' => randomColorGenerator(0.5),
            ]);
            $ticket = Ticket::with('users','selfassign')->find($ticket->id);
            $ticket->ticket_id = setting('CUSTOMER_TICKETID') . '-' . $ticket->id;

            $categories = CategoryEnvato::where('category_id',$request->category)->first();
            if($request->input('envato_id') &&  $categories){

                $ticket->purchasecode = encrypt($request->input('envato_id'));
                if($request->input('productname')){
                    $ticket->item_name = $request->input('productname');
                }
            }
            if ($request->input('envato_support')) {

                $ticket->purchasecodesupport = $request->input('envato_support');
            }
            $categoryfind = Category::find($request->category);
            $ticket->priority = $categoryfind->priority;
            if ($request->subscategory) {
                $ticket->subcategory = $request->subscategory;
            }

            // Auto Overdue Ticket
            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;
                    }

                }
            }
            // End Auto Overdue Ticket
            $categories = CategoryEnvato::where('category_id', $request->category)->first();
            if ($request->input('envato_id') &&  $categories) {
                $ticket->purchasecode = encrypt($request->input('envato_id'));
                if ($request->input('productname')) {
                    $ticket->item_name = $request->input('productname');
                }
            }
            if ($request->input('envato_support')) {
                $ticket->purchasecodesupport = $request->input('envato_support');
            }
            $categoryfind = Category::find($request->category);
            $ticket->priority = $request->priority != null ? $request->priority : $categoryfind->priority;
            if ($request->subscategory) {
                $ticket->subcategory = $request->subscategory;
            }
            $ticket->update();

            $ccmails = new CCMAILS();
            $ccmails->ticket_id = $ticket->id;
            $ccmails->ccemails = $request->ccmail;
            $ccmails->save();

            foreach ($request->input('ticket', []) as $file) {
                $provider =  storage()->provider;
                $provider::mediaupload($ticket, 'uploads/livechat/' . $file, 'ticket');
            }

            $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,
                'ticket_description' => $ticket->message,
                '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',
            ];

            $geolocation = GeoIP::getLocation(request()->getClientIp());
            $agent = new Agent();
            $activity = new EmployeeActivity();
            $activity->user_id = Auth::user()->id;
            $activity->activity_type = 'Livechat Ticket Created';
            $activity->ip_address = $geolocation->ip;
            $activity->browser = $agent->browser();
            $activity->device = $agent->device();
            $activity->save();

            $ticket->encrypted_id = Crypt::encrypt($ticket->id);

            try {

                $replySubject = 'Re: ' . $ticket->subject;

                $today = Carbon::today();
                $holidays = Holiday::whereDate('startdate', '<=', $today)->whereDate('enddate', '>=', $today)->where('status','1')->get();
                if ($holidays->isNotEmpty()) {
                    $emailtempcode = 'customer_send_ticket_created_that_holiday_or_announcement';
                } else {
                    $emailtempcode = 'customer_send_ticket_created';
                }

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

                $imap_username = setting('IMAP_USERNAME');


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


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

                    foreach ($ticket->getMedia('ticket') as $commentss) {
                        if (!file_exists('public/temp/')) {
                            mkdir('public/temp/', 0777, true);
                        }
                        $localTempFilePath = 'public/temp/' . $commentss->file_name;
                        $existprovider = existprovider($commentss->disk);
                        if ($existprovider)
                            $contentPath = $existprovider->provider::tempImage($commentss, $localTempFilePath);

                        $message->attach($contentPath);
                        $fileNames[] = $localTempFilePath;
                    }

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

                $assigneuser = User::find($ticket->selfassignuser_id);
                if($assigneuser != null){
                    $assigneuser->notify(new TicketCreateNotifications($ticket));
                    event(new LiveNotification('A new ticket has been created. ticket no. ' . $ticket->ticket_id,$assigneuser,$ticket,fetchticketviewurl($ticket)));
                    if($assigneuser->usetting->emailnotifyon == 1){
                        dispatch((new MailSend($assigneuser->email, 'admin_send_email_ticket_created', $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));
                        event(new LiveNotification('A new ticket has been created. ticket no. ' . $ticket->ticket_id,$user,$ticket,fetchticketviewurl($ticket)));
                        dispatch((new MailSend($user->email, 'admin_send_email_ticket_created', $ticketData)));
                    }
                }


            } catch (\Exception$e) {
                return $ticket;
            }

            return $ticket;
        }
    }
}
