<?php

namespace App\Http\Controllers;

use App\Mail\Tickets\{Created,Closed};

use App\Models\{Tickets, Departments, User, Responses};
use Illuminate\Http\Request;

use Illuminate\Support\Facades\{Auth, Mail};
use Illuminate\Support\{Str,Carbon};

class TicketsController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        if (!Auth::guest() && auth()->user()->can('view tickets')) {

            if(auth()->user()->hasanyrole('superadmin','admin','employee'))
            {
                $count_open = Tickets::where('status', '!=' , 'closed')->count();
                $high_priority = Tickets::where('status', '!=' , 'closed')->where(function($query) { $query->where('priority', '=', 'high')->orWhere('priority', '=', 'emergency'); })->count();
                $all_count = Tickets::count();

                return view('tickets.index',[
                    'open_count' => $count_open,
                    'high_priority' => $high_priority,
                    'all_count' => $all_count,
                ]);
            } elseif(!auth()->user()->hasanyrole('admin','employee')) {
                $count_open = Tickets::where('status', '!=', 'closed')->where('user_id', '=', Auth::user()->id)->count();
                $all_closed = Tickets::where('status', '=', 'closed')->where('user_id', '=', Auth::user()->id)->count();
                $all_tickets = Tickets::where('user_id', '=', Auth::user()->id)->count();
                
                return view('tickets.index',[
                    'open_count' => $count_open,
                    'all_closed' => $all_closed,
                    'all_count' => $all_tickets,
                ]);
            }
        } else {
            return view('tickets.public');
        }
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create(Request $request, string $departmentSlug)
    {
        if (Auth::check()) {
            
            if (Auth::user()->hasAnyRole('superadmin','admin','employee')) {
                $department = Departments::where('slug', '=', $departmentSlug)->first();
            } else {
                $department = Departments::where('slug', '=', $departmentSlug)->where('is_disabled', '!=', '1')->first(); 
            }

            if ($department) {
                return view('tickets.open', [
                    'department_id' => $department->id,
                    'department' => $department,
                ]);
            } else {
                return view('departments.index');
            }
        } else {
            $department = Departments::where('slug', '=', $departmentSlug)->where('is_public', '!=', '2')->where('is_disabled', '!=', '1')->first();
            if ($department) {
                return view('tickets.open', [
                    'department_id' => $department->id,
                    'department' => $department,
                ]);
            } else {
                return redirect()->route('departments');
            }
        }
    }

    /**
     * Store a newly created resource in storage.
     */
    public static function store($ticket)
    {
        if($ticket['customer_id'] != false)
        {
            $create_ticket = Tickets::create([
                'user_id' => $ticket['customer_id'] ?? Auth::user()->id,
                'subject' => $ticket['subject'],
                'message' => $ticket['message'],
                'status' => 'open',
                'priority' => $ticket['priority'],
                'cc' => $ticket['cc'] ?? '',
                'assigned' => Auth::user()->account_manager ?? '0',
                'department_id' => $ticket['department_id'],
                'public_hash' => $ticket['public_hash'],
                'public_name' => $ticket['public_name'] ?? null,
                'public_email' => $ticket['public_email'] ?? null,
                'rating' => '0',
                'ip_address' => app('request')->ip(),
                'organize' => 'ticket',
                'date_closed' => null,
                'updated_by_client_at' => Carbon::now(),
                'created_at' => Carbon::now(),
                'updated_at' => null,
                'first_employee_reply' => null,
            ]);
        } else {
            $create_ticket = Tickets::create([
                'user_id' => Auth::user()->id ?? '0',
                'subject' => $ticket['subject'],
                'message' => $ticket['message'],
                'status' => 'open',
                'priority' => $ticket['priority'],
                'cc' => $ticket['cc'] ?? '',
                'assigned' => Auth::user()->account_manager ?? '0',
                'department_id' => $ticket['department_id'],
                'public_hash' => $ticket['public_hash'],
                'public_name' => $ticket['public_name'] ?? null,
                'public_email' => $ticket['public_email'] ?? null,
                'rating' => '0',
                'ip_address' => app('request')->ip(),
                'organize' => 'ticket',
                'date_closed' => null,
                'updated_by_client_at' => Carbon::now(),
                'created_at' => Carbon::now(),
                'updated_at' => null,
                'first_employee_reply' => null,
            ]);
        }

        // Grabs all the ticket details into an array for the email.
        $grab_ticket = Tickets::where('id', '=', $create_ticket->id)->get()->toArray();

        if($ticket['customer_id'] != false)
        {
            $user = User::where('id', '=', $ticket['customer_id'])->first();
            $user_email = $user->email;
        } else {
            $user_email = Auth::check() ? Auth::user()->email : $grab_ticket[0]['public_email'];
        }

        if(config("mail.enabled") == 'true')
        {
            // Grab the ticket information
            $grab_ticket = Tickets::where('id', '=', $create_ticket->id)->get()->toArray();

             // Grab the Customers email from the Ticket
             $customer_email = User::select('email')->where('id', '=', $grab_ticket[0]['user_id'])->first();

             // Defines the email address for the user, logged in or the public email address
             $user_email = $customer_email ?? $grab_ticket[0]['public_email'];

            if(Auth::check() && !Auth::user()->hasAnyRole('superadmin', 'admin', 'employee'))
            {
                // Send email to customer & Agents
                $employees = User::select('email')->role('superadmin')->role('admin')->role('employee')->pluck('email')->toArray();

                if (isset($ticket['cc']) && $ticket['cc'] != '') {
                    Mail::to($user_email)->cc($ticket['cc'])->bcc($employees)->send(new Created($grab_ticket[0],
                        $ticket['public_hash']));
                } else {
                    Mail::to($user_email)->bcc($employees)->send(new Created($grab_ticket[0], $ticket['public_hash']));
                }
            } else {
                if (isset($ticket['cc']) && $ticket['cc'] != '') {
                    Mail::to($user_email)->cc($ticket['cc'])->send(new Created($grab_ticket[0], $ticket['public_hash']));
                } else {
                    Mail::to($user_email)->send(new Created($grab_ticket[0]));
                }
            }
        }

        return $create_ticket->id;
    }

    /**
     * Display the specified resource.
     */
    public static function show(string $ticketId)
    {
        $check_ticket = Tickets::where('tickets.id', '=', $ticketId)
            ->where('tickets.user_id', '=', Auth::user()->id)
            ->first();

        if ($check_ticket != null or Auth::user()->hasAnyRole('superadmin', 'admin','employee')) {
            $ticket = Tickets::where('tickets.id', '=', $ticketId)
                ->leftJoin('users', 'tickets.user_id', '=', 'users.id')
                ->leftJoin('departments', 'tickets.department_id', '=', 'departments.id')
                ->select('tickets.*', 'departments.*', 'users.*')
                ->selectRaw('users.company as company_name, users.name as client_name, tickets.id as ticket_id, departments.id as department_unique_id, tickets.created_at as ticket_created')
                ->first();

            // Load attachments for the initial ticket
            $ticketAttachments = \App\Models\Attachment::where('ticket_id', $ticketId)
                ->whereNull('response_id')
                ->get();

            return view('tickets.view_ticket', [
                'ticket' => $ticket,
                'ticketAttachments' => $ticketAttachments,
                'ip_address' => app('request')->ip(),
            ]);
        } else {
            // Not the customer's ticket and not an Agent. Need to do Error Handling here.
            return view('dashboard');
        }
    }

    public function assigned()
    {
        if (!auth()->user()->can('view assigned tickets')) {
            return redirect()->route('dashboard');
        }

        return view('tickets.assigned');
    }

    /**
     * Display the specified resource for the public.
     */
    public function public(Request $request, string $ticketId, string $ticketHash)
    {

            $ticket = Tickets::where('tickets.id', '=', $ticketId)
            ->leftJoin('users', 'tickets.user_id', '=', 'users.id')
            ->leftJoin('departments', 'tickets.department_id', '=', 'departments.id')
            ->where('tickets.public_hash', '=', $ticketHash)
            ->select('tickets.*', 'departments.*', 'users.*')
            ->selectRaw('users.company as company_name, users.name as client_name, tickets.id as ticket_id, departments.id as department_id, tickets.created_at as ticket_created')->firstOrFail();

            if ($ticket) {
                // Load attachments for the initial ticket
                $ticketAttachments = \App\Models\Attachment::where('ticket_id', $ticketId)
                    ->whereNull('response_id')
                    ->get();

                return view('tickets.view_ticket', [
                    'ticket' => $ticket,
                    'ticketAttachments' => $ticketAttachments,
                ]);
            } else {
                return view('dashboard');
            }
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(Tickets $tickets)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, Tickets $tickets)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     */
    public static function destroy($ticket)
    {
        Tickets::where('id', '=', $ticket['ticket_number'])
                ->update([
                    'status' => 'closed',
                    'date_closed' => Carbon::now(),
                ]);
        if(Auth::guest())
        {
            Responses::create([
                'user_id' => '0',
                'content' => "This ticket has been closed by a guest.",
                'ticket_number' => $ticket['ticket_number'],
                'is_note' => '2',
                'employee_response' => '0',
                'ip_address' => app('request')->ip(),
                'created_at' => Carbon::now(),
                'updated_at' => null,
            ]);
        } elseif(Auth::user()->id){
            if(Auth::user()->hasAnyRole('superadmin', 'admin', 'employee'))
            {
                $content = "This ticket has been closed by " . Auth::user()->name . ". If you need any more assistance, simply submit a response and we'll get back to you shortly.";
                Responses::create([
                    'user_id' => '0',
                    'content' => $content,
                    'ticket_number' => $ticket['ticket_number'],
                    'is_note' => '2',
                    'employee_response' => '1',
                    'ip_address' => app('request')->ip(),
                    'created_at' => Carbon::now(),
                    'updated_at' => null,
                ]);
            } else {
                $content = "This ticket has been closed. If you need any more assistance, simply submit a response and we'll get back to you shortly.";
                Responses::create([
                    'user_id' => '0',
                    'content' => $content,
                    'ticket_number' => $ticket['ticket_number'],
                    'is_note' => '2',
                    'employee_response' => '0',
                    'ip_address' => app('request')->ip(),
                    'created_at' => Carbon::now(),
                    'updated_at' => null,
                ]);
            }
        }

        if(config("mail.enabled") == 'true')
        {
            // Grab the ticket information
            $grab_ticket = Tickets::where('id', '=', $ticket['ticket_number'])->get()->toArray();

             // Grab the Customers email from the Ticket
             $customer_email = User::select('email')->where('id', '=', $grab_ticket[0]['user_id'])->first();

             // Defines the email address for the user, logged in or the public email address
             $user_email = $customer_email ?? $grab_ticket[0]['public_email'];

            // Send email to customer & Agents
            $employees = User::select('email')->role('admin')->role('employee')->pluck('email')->toArray();

            if(Auth::check() && !Auth::user()->hasAnyRole('superadmin', 'admin', 'employee'))
            {
                Mail::to($user_email)->bcc($employees)->send(new Closed($grab_ticket[0]));
            } else {
                Mail::to($user_email)->send(new Closed($grab_ticket[0]));
            }
        }
    }
}