<?php

namespace App\Http\Controllers\Traits;

use Illuminate\Http\Request;
use App\Http\Controllers\Traits\ValidationTrait;
use App\Http\Controllers\Traits\EmailTrait;
use App\Models\HelpdeskTicket;
use App\Models\HelpdeskConversions;
use App\Models\User;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\View;
use Illuminate\Support\Facades\Log;


trait HelpDeskTrait
{
    use ValidationTrait, EmailTrait;
    public function storeHelpdeskTicket(Request $request)
    {
        $validator = $this->helpdeskValidationRequest($request);
        if ($validator->fails()) {
            return $this->handleValidationFailure($validator);
        }
        $validatedData = $validator->validated();
        // Additional validation for admin-created tickets
        $currentUser = Auth::user();
        $isAdmin = $currentUser->user_type == config('constants.user_types.admin');
        if ($isAdmin) {
            // Validate that admin is providing required user information
            if (empty($request->user_id) || empty($request->email)) {
                return $this->message('User ID and email are required when creating tickets for users.', 422);
            }
            // Validate that the user exists and belongs to the admin's workspace
            $userExists = User::where('id', $request->user_id)
                ->exists();
            if (!$userExists) {
                return $this->message('Invalid user ID or user does not belong to your workspace.', 422);
            }
        }
        $image = $this->handleFileImageUpload($request, 'HelpDesk');
        $image = $image['path'] ?? null;
        $ticket = new HelpdeskTicket();
        $ticket->user_id = $request->user_id;
        $ticket->name = $request->name;
        $ticket->ticket_id = $this->generateTicketId();
        $ticket->email = $request->email;
        $ticket->category = $request->category_id;
        $ticket->subject = $request->subject;
        $ticket->descriptions = $request->descriptions;
        $ticket->status = (int) (
            $request->status === null ||
            $request->status === '' ||
            $request->status === 'null'
            ? 0
            : $request->status
        );
        $ticket->attachments = $image;
        $ticket->note = $request->note;
        $ticket->workspace = $request->workspace;
        $ticket->created_by = Auth::user()->id;
        try {
            $ticket->save();
        } catch (\Exception $e) {
            return $this->message('Failed to create ticket. Please try again.', 500);
        }
        if (!$ticket) {
            return $this->message('Failed to create ticket.');
        }
        // Check if the current user is a customer
        $currentUser = Auth::user();
        $isCustomer = $currentUser->user_type == config('constants.user_types.customer');
        $isAdmin = $currentUser->user_type == config('constants.user_types.admin');
        // Send email notifications based on who created the ticket
        if ($isCustomer) {
            // Customer created ticket - notify admin
            $admin = User::where('user_type', config('constants.user_types.admin'))->first();
            $adminEmail = DB::table('adminsettings')
                ->where('customer_id', $admin->id)
                ->where('key', 'company_company_email')
                ->value('value');
            if ($this->canUserReceiveEmails($adminEmail)) {
                // Load the ticket with its relations
                $newTicket = HelpdeskTicket::with(['conversations.senderUser', 'category'])
                    ->where('id', $ticket->id)
                    ->first();
                // Prepare email parameters for admin notification
                $adminEmailParams = [
                    'to' => $adminEmail,
                    'subject' => 'New Helpdesk Ticket Created: ' . $ticket->ticket_id,
                    'msg' => $this->generateTicketEmailContent($newTicket, 'admin')
                ];
                // Send email notification to admin
                $emailSent = $this->SendInstantEmail($adminEmailParams);
            }
        } elseif ($isAdmin) {
            // Admin created ticket for user - notify the user
            if ($this->canUserReceiveEmails($ticket->email, $ticket->user_id)) {
                // Load the ticket with its relations
                $newTicket = HelpdeskTicket::with(['conversations.senderUser', 'category'])
                    ->where('id', $ticket->id)
                    ->first();

                // Prepare email parameters for user notification
                $userEmailParams = [
                    'to' => $ticket->email,
                    'subject' => 'New Helpdesk Ticket Created for You: ' . $ticket->ticket_id,
                    'msg' => $this->generateTicketEmailContent($newTicket, 'customer', true) // true indicates admin-created ticket
                ];

                // Send email notification to user
                $emailSent = $this->SendInstantEmail($userEmailParams);
            }
        }
        return $this->success($ticket, 'Ticket created successfully');
    }

    public function getCustomerHelpdesk()
    {
        $id = Auth::user()->id;
        $ticket = HelpdeskTicket::with('category')->where('created_by', $id)->get();
        if ($ticket->isEmpty()) {
            return $this->success($ticket, "No Ticket found.");
        }
        return $this->success($ticket, "Ticket list retrieved successfully.");
    }

    public function showHelpdesk($ticket)
    {
        $ticket = HelpdeskTicket::with('conversations.senderUser')->findOrFail($ticket);
        if (!$ticket) {
            return $this->message('Ticket not found');
        }
        return $this->success($ticket, 'Ticket retrieved successfully');
    }

    public function updateHelpdesk($request)
    {
        $validator = $this->helpdeskValidationRequest($request);
        if ($validator->fails()) {
            return $this->handleValidationFailure($validator);
        }
        $ticket = HelpdeskTicket::find($request->id);
        if (!$ticket) {
            return $this->message('Ticket not found');
        }

        // Store original status to check for changes
        $originalStatus = $ticket->status;

        $image = $this->handleFileImageUpload($request, 'HelpDesk');
        $image = $image['path'] ?? null;
        $ticket->user_id = $request->user_id;
        $ticket->name = $request->name;
        // $ticket->ticket_id =$this->generateTicketId();
        $ticket->email = $request->email;
        $ticket->category = $request->category_id;
        $ticket->subject = $request->subject;
        $ticket->descriptions = $request->descriptions;
        $ticket->status = (int) (
            $request->status === null ||
            $request->status === '' ||
            $request->status === 'null'
            ? 0
            : $request->status
        );
        $ticket->attachments = $image;
        $ticket->note = $request->note;
        $ticket->workspace = $request->workspace;
        // $ticket->created_by = Auth::user()->id;
        $ticket->save();

        // Check if status has changed and send email notification
        if ($originalStatus != $ticket->status && $ticket->email) {
            // Get latest ticket data with conversations
            $updatedTicket = HelpdeskTicket::with(['conversations.senderUser', 'category'])
                ->where('id', $ticket->id)
                ->first();

            // Create a system message about status change
            $ticketConversions = new HelpdeskConversions();
            $ticketConversions->ticket_id = $ticket->id;
            $ticketConversions->descriptions = "Ticket status changed from " . $this->getStatusName($originalStatus) . " to " . $this->getStatusName($ticket->status);
            $ticketConversions->sender = Auth::user()->id;
            $ticketConversions->save();

            // Refresh ticket data with the new conversation
            $updatedTicket = HelpdeskTicket::with(['conversations.senderUser', 'category'])
                ->where('id', $ticket->id)
                ->first();

            // Prepare email parameters using same structure as replyHelpdesk
            $customerEmailParams = [
                'to' => $ticket->email,
                'subject' => 'Ticket Status Updated: ' . $ticket->ticket_id,
                'msg' => $this->generateTicketEmailContent($updatedTicket, 'customer')
            ];

            // Send email notification
            $emailSent = $this->SendInstantEmail($customerEmailParams);
            Log::info('Helpdesk Status Update - Email Sent', [
                'success' => $emailSent ? 'Yes' : 'No',
                'to' => $ticket->email,
                'status' => $this->getStatusName($ticket->status),
                'ticket_id' => $ticket->ticket_id
            ]);
        }

        return $this->success($ticket, 'Ticket updated successfully');
    }

    /**
     * Get status name from status code
     * 
     * @param int $status
     * @return string
     */
    private function getStatusName($status)
    {
        switch ($status) {
            case 0:
                return 'Open';
            case 1:
                return 'On Hold';
            case 2:
                return 'Closed';
            default:
                return 'Unknown';
        }
    }

    protected function destroyHelpdesk($category)
    {
        $ticket = HelpdeskTicket::find($category);
        if (!$ticket) {
            return $this->message('Ticket not found');
        }
        $ticket->delete();
        return $this->message('Ticket deleted successfully');
    }


    public function replyHelpdesk($request)
    {

        $validator = $this->replyValidationRequest($request);
        if ($validator->fails()) {
            return $this->handleValidationFailure($validator);
        }
        $ticket = HelpdeskTicket::with(['conversations.senderUser', 'category'])
            ->where('id', $request->ticket_id)
            ->first();
        if (!$ticket) {
            return $this->message('Ticket not found');
        }
        $customerEmail = $ticket->email;
        if (!$customerEmail) {
            return $this->message('Customer email not found');
        }


        // Get admin email from settings
        // First try to get admin email from system-wide settings (no customer_id filter)
        $admin = User::where('user_type', config('constants.user_types.admin'))->first();
        $adminEmail = DB::table('adminsettings')
            ->where('customer_id', $admin->id)
            ->where('key', 'company_company_email')
            ->value('value');



        // Log the emails for debugging
        Log::info('Helpdesk Reply - Emails', [
            'ticket_id' => $ticket->ticket_id,
            'customer_email' => $customerEmail,
            'admin_email' => $adminEmail
        ]);

        // Handle file attachment
        $attachmentPath = null;
        if ($request->hasFile('image')) {
            $attachment = $this->handleFileImageUpload($request, 'HelpDesk');
            $attachmentPath = $attachment['path'] ?? null;
        }

        // Create new conversation record
        $ticketConversions = new HelpdeskConversions();
        $ticketConversions->ticket_id = $request->ticket_id;
        $ticketConversions->descriptions = $request->description;
        $ticketConversions->attachments = $attachmentPath;
        $ticketConversions->sender = Auth::user()->id;
        $ticketConversions->save();
        if (!$ticketConversions) {
            return $this->message('Failed to create Conversation');
        }

        // Refresh ticket data with the new conversation
        $ticket = HelpdeskTicket::with(['conversations.senderUser', 'category'])
            ->where('id', $request->ticket_id)
            ->first();

        // Determine current user type and send emails accordingly
        $currentUser = Auth::user();
        $isAdmin = $currentUser->user_type == config('constants.user_types.admin');
        $isCustomer = $currentUser->user_type == config('constants.user_types.customer');
        // If admin replied, send email to customer
        if ($isAdmin && $customerEmail) {
            $customerEmailParams = [
                'to' => $customerEmail,
                'subject' => 'New Reply to Your Ticket: ' . $ticket->ticket_id,
                'msg' => $this->generateTicketEmailContent($ticket, 'customer')
            ];

            $emailSent = $this->SendInstantEmail($customerEmailParams);
            Log::info('Helpdesk Reply - Customer Email Sent', [
                'success' => $emailSent ? 'Yes' : 'No',
                'to' => $customerEmail
            ]);
        }

        // If customer replied, send email to admin
        if ($isCustomer && $adminEmail) {
            $adminEmailParams = [
                'to' => $adminEmail,
                'subject' => 'New Helpdesk Ticket Reply: ' . $ticket->ticket_id,
                'msg' => $this->generateTicketEmailContent($ticket, 'admin')
            ];

            $emailSent = $this->SendInstantEmail($adminEmailParams);
            Log::info('Helpdesk Reply - Admin Email Sent', [
                'success' => $emailSent ? 'Yes' : 'No',
                'to' => $adminEmail
            ]);
        }

        return $this->success($ticketConversions, 'Conversation added successfully.');
    }

    /**
     * Generate HTML content for ticket email
     * 
     * @param HelpdeskTicket $ticket
     * @param string $recipient (admin or customer)
     * @param bool $adminCreated (indicates if admin created the ticket for user)
     * @return string
     */
    private function generateTicketEmailContent($ticket, $recipient = 'customer', $adminCreated = false)
    {
        $status_config = $this->getHelpdeskStatusConfig($ticket->status);

        // Get last conversation message for context
        $lastConversation = $ticket->conversations->sortByDesc('created_at')->first();
        $lastSender = $lastConversation && $lastConversation->senderUser
            ? $lastConversation->senderUser->name
            : 'Unknown';

        // Customize status message based on recipient, last sender, and creation context
        if ($recipient == 'admin') {
            $status_config['message'] = "Customer {$ticket->name} has added a new message to this ticket.";
            if (
                $lastConversation && $lastConversation->senderUser &&
                $lastConversation->senderUser->user_type == config('constants.user_types.admin')
            ) {
                $status_config['message'] = "Admin {$lastSender} has added a new message to this ticket.";
            }
        } else {
            // For customer recipient
            if ($adminCreated) {
                // Admin created ticket for user
                $status_config['message'] = "A support ticket has been created for you by our support team. Please review the details below.";
            } elseif (
                $lastConversation && $lastConversation->senderUser &&
                $lastConversation->senderUser->user_type == config('constants.user_types.admin')
            ) {
                $status_config['message'] = "Support team member {$lastSender} has responded to your ticket.";
            } else {
                $status_config['message'] = "Your helpdesk ticket has been updated.";
            }
        }

        // Get system date and time format settings
        $systemDateFormat = $this->getHelpdeskSystemDateFormat();
        $systemTimeFormat = $this->getHelpdeskSystemTimeFormat();

        // Format the ticket dates properly
        $formattedTicket = $ticket->toArray();

        // Format conversation dates properly
        $formattedConversations = [];
        foreach ($ticket->conversations as $conversation) {
            $conversationArray = $conversation->toArray();
            $formattedConversations[] = $conversationArray;
        }

        // Return rendered HTML template
        return View::make('Emails.helpdesk-notification', [
            'ticket' => $ticket,
            'formattedTicket' => $formattedTicket,
            'conversations' => $formattedConversations,
            'recipient' => $recipient,
            'status_config' => $status_config,
            'adminCreated' => $adminCreated,
            'subject' => 'Helpdesk Ticket Update: ' . $ticket->ticket_id
        ])->render();
    }

    /**
     * Get system date format from settings
     */
    private function getHelpdeskSystemDateFormat()
    {
        try {
            $user = auth()->user();
            if (!$user) {
                return 'd-m-Y'; // Default format if no user
            }

            // Determine customer_id and workspace_id based on user type
            $customerId = $user->access_role ? $user->customer_id : $user->id;
            $workspaceId = $user->current_workspace_id ?? $user->workspace_id ?? null;

            $setting = \App\Models\Adminsettings::where('customer_id', $customerId)
                ->where('key', 'system_date_format')
                ->when($workspaceId, function ($query) use ($workspaceId) {
                    return $query->where('workspace', $workspaceId);
                })
                ->first();

            if ($setting && $setting->value) {
                // Convert system format to Carbon format
                $formatMap = [
                    'mm-dd-yyyy' => 'm-d-Y',
                    'dd-mm-yyyy' => 'd-m-Y',
                    'yyyy-mm-dd' => 'Y-m-d',
                    'mm/dd/yyyy' => 'm/d/Y',
                    'dd/mm/yyyy' => 'd/m/Y',
                    'yyyy/mm/dd' => 'Y/m/d',
                ];
                return $formatMap[strtolower($setting->value)] ?? 'd-m-Y';
            }
        } catch (\Exception $e) {
            // Log error but continue with default
        }
        return 'd-m-Y'; // Default format
    }

    /**
     * Get system time format from settings
     */
    private function getHelpdeskSystemTimeFormat()
    {
        try {
            $user = auth()->user();
            if (!$user) {
                return 'H:i'; // Default 24-hour format if no user
            }

            // Determine customer_id and workspace_id based on user type
            $customerId = $user->access_role ? $user->customer_id : $user->id;
            $workspaceId = $user->current_workspace_id ?? $user->workspace_id ?? null;

            $setting = \App\Models\Adminsettings::where('customer_id', $customerId)
                ->where('key', 'system_time_format')
                ->when($workspaceId, function ($query) use ($workspaceId) {
                    return $query->where('workspace', $workspaceId);
                })
                ->first();

            if ($setting && $setting->value) {
                // Check if the format contains AM/PM or if user prefers 12-hour format
                $value = strtoupper($setting->value);
                if (
                    str_contains($value, 'AM') || str_contains($value, 'PM') ||
                    str_contains($value, '12') || str_contains($value, 'HOUR')
                ) {
                    return 'g:i A'; // 12-hour format with AM/PM
                }
            }
        } catch (\Exception $e) {
            // Log error but continue with default
        }
        return 'H:i'; // Default 24-hour format
    }

    /**
     * Check if a user can receive emails
     * 
     * @param string $email
     * @param int $userId
     * @return bool
     */
    private function canUserReceiveEmails($email, $userId = null)
    {
        if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
            return false;
        }

        // Check if user has opted out of emails (if you have such functionality)
        if ($userId) {
            // You can add logic here to check user preferences
            // For example: check if user has disabled email notifications
        }

        return true;
    }

    /**
     * Get helpdesk status configuration
     * 
     * @param int $status
     * @return array
     */
    private function getHelpdeskStatusConfig($status)
    {
        $statusConfigs = [
            0 => [
                'status_text' => 'Open',
                'color' => '#059669',
                'background' => '#ecfdf5',
                'icon' => '🔓',
                'message' => 'Your ticket is now open and being reviewed by our support team.'
            ],
            1 => [
                'status_text' => 'On Hold',
                'color' => '#d97706',
                'background' => '#fffbeb',
                'icon' => '⏸️',
                'message' => 'Your ticket is currently on hold. We will resume work on it soon.'
            ],
            2 => [
                'status_text' => 'Closed',
                'color' => '#dc2626',
                'background' => '#fef2f2',
                'icon' => '🔒',
                'message' => 'Your ticket has been resolved and closed. Thank you for using our support system.'
            ]
        ];

        return $statusConfigs[$status] ?? $statusConfigs[0];
    }


    public function downloadHelpdesk($id)
    {
        $attach = HelpdeskTicket::find($id);
        $filePath = public_path($attach->attachments);
        if (!File::exists($filePath)) {
            return $this->message('File not found');
        }
        return response()->download($filePath);
    }
}
