<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\View\View;
use Illuminate\Http\RedirectResponse;
use App\Models\SupportTicket;
use App\Models\SupportMessage;
use App\Models\User;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class SupportController extends Controller
{
    /**
     * Get base URL with correct port for image URLs
     */
    private function getBaseUrl(Request $request): string
    {
        $baseUrl = $request->getSchemeAndHttpHost();
        
        // For localhost, ensure port 8000 is included
        if (str_contains($baseUrl, 'localhost')) {
            // Check if port is missing
            $parsed = parse_url($baseUrl);
            if (!isset($parsed['port'])) {
                $baseUrl = 'http://localhost:8000';
            }
        }
        
        return rtrim($baseUrl, '/');
    }
    
    public function index(Request $request): View
    {
        // Get all tickets with user and unread count
        $query = SupportTicket::with(['user'])
            ->withCount([
                'messages as unread_count' => function ($q) {
                    $q->where('is_read', false)
                      ->where('sender_type', 'user'); // Only count user messages as unread for admin
                }
            ]);

        // Filter by status
        if ($request->has('status') && $request->status !== '') {
            $query->where('status', $request->status);
        }

        // Search by User ID
        if ($request->has('search') && $request->search !== '') {
            $search = $request->search;
            $query->whereHas('user', function ($q) use ($search) {
                $q->where('id', 'like', "%{$search}%");
            });
        }

        // Get all tickets, then group by user_id to get latest ticket per user (to avoid duplicates)
        $allTickets = $query->latest('last_message_at')->get();
        
        // Group by user_id and get latest ticket per user
        $tickets = $allTickets->groupBy('user_id')->map(function ($userTickets) {
            // Get the ticket with the most recent last_message_at
            return $userTickets->sortByDesc('last_message_at')->first();
        })->values()->sortByDesc(function ($ticket) {
            return $ticket->last_message_at ? $ticket->last_message_at->timestamp : 0;
        })->values();

        // Get selected ticket if provided
        $selectedTicket = null;
        if ($request->has('ticket_id')) {
            $selectedTicket = SupportTicket::with(['user', 'messages'])->find($request->get('ticket_id'));
            
            // Mark messages as read when ticket is opened
            if ($selectedTicket) {
                SupportMessage::where('ticket_id', $selectedTicket->id)
                    ->where('sender_type', 'user')
                    ->where('is_read', false)
                    ->update(['is_read' => true]);
                    
                // Reload ticket to get updated messages
                $selectedTicket->refresh();
                $selectedTicket->load('messages');
            }
        }

        return view('admin.support.chat', [
            'tickets' => $tickets,
            'selectedTicket' => $selectedTicket,
            'pageTitle' => __('admin.support.chat_title'),
            'title' => 'Customer Service Chat'
        ]);
    }
    
    public function getMessages(Request $request, $id): \Illuminate\Http\JsonResponse
    {
        $ticket = SupportTicket::with(['user', 'messages'])->findOrFail($id);

        // Mark messages as read when admin views
        SupportMessage::where('ticket_id', $ticket->id)
            ->where('sender_type', 'user')
            ->where('is_read', false)
            ->update(['is_read' => true]);

        $ticket->refresh();
        $ticket->load('messages');

        // Get base URL with correct port
        $baseUrl = $this->getBaseUrl($request);

        $messages = $ticket->messages->map(function ($message) use ($baseUrl) {
            $imageUrl = null;
            if ($message->image) {
                // Check if file actually exists before generating URL
                $imagePath = ltrim($message->image, '/');
                $fullPath = storage_path('app/public/' . $imagePath);
                
                // Only include image URL if file exists
                if (file_exists($fullPath)) {
                    if (!str_starts_with($imagePath, 'storage/')) {
                        $imagePath = 'storage/' . $imagePath;
                    }
                    $imageUrl = rtrim($baseUrl, '/') . '/' . $imagePath;
                }
                // If file doesn't exist, imageUrl remains null (won't cause 404 errors)
            }
            
            return [
                'id' => $message->id,
                'sender_type' => $message->sender_type,
                'message' => $message->message,
                'image' => $imageUrl, // null if file doesn't exist
                'created_at' => $message->created_at->toISOString(),
                'time' => $message->created_at->format('H:i'),
            ];
        });

        // Safely get user data with null checking
        $userData = [
            'wallet_address' => 'N/A',
            'id' => null,
        ];
        
        if ($ticket->user) {
            $userData = [
                'wallet_address' => $ticket->user->wallet_address ?? 'N/A',
                'id' => $ticket->user->id ?? null,
            ];
        }
        
        return response()->json([
            'success' => true,
            'ticket' => [
                'id' => $ticket->id,
                'user' => $userData,
                'status' => $ticket->status ?? 'open',
            ],
            'messages' => $messages,
        ]);
    }

    public function show($id): View
    {
        $ticket = SupportTicket::with(['user', 'messages.sender'])->findOrFail($id);

        // Mark messages as read
        SupportMessage::where('ticket_id', $ticket->id)
            ->where('sender_type', '!=', 'admin')
            ->where('is_read', false)
            ->update(['is_read' => true]);

        return view('admin.support.show', [
            'ticket' => $ticket,
            'pageTitle' => 'Ticket #' . $ticket->id,
            'title' => 'Ticket #' . $ticket->id
        ]);
    }

    public function sendMessage(Request $request, $id)
    {
        $request->validate([
            'message' => 'nullable|string|max:5000',
            'image' => 'nullable|image|max:5120',
        ]);

        // Ensure at least message or image is provided
        if (empty($request->message) && !$request->hasFile('image')) {
            if ($request->expectsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Please provide a message or image'
                ], 422);
            }
            return redirect()->back()->with('error', 'Please provide a message or image');
        }

        $ticket = SupportTicket::findOrFail($id);
        
        // Get admin user ID from session (admin auth uses session, not API auth)
        $adminId = $request->session()->get('admin.user_id');
        if (!$adminId) {
            if ($request->expectsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Admin authentication required'
                ], 401);
            }
            return redirect()->back()->with('error', 'Admin authentication required');
        }

        // Handle image upload
        $imagePath = null;
        if ($request->hasFile('image')) {
            try {
                $image = $request->file('image');
                
                // Validate image
                if (!$image->isValid()) {
                    \Illuminate\Support\Facades\Log::error('Admin image upload error: Invalid file');
                    if ($request->expectsJson()) {
                        return response()->json([
                            'success' => false,
                            'message' => 'Invalid image file. Please try again.'
                        ], 422);
                    }
                    return redirect()->back()->with('error', 'Invalid image file. Please try again.');
                }
                
                // Ensure directory exists
                $directory = 'public/support/' . $ticket->id;
                Storage::makeDirectory($directory, 0755, true);
                
                // Generate unique filename
                $uuid = Str::uuid();
                $extension = $image->getClientOriginalExtension();
                $filename = 'support/' . $ticket->id . '/' . $uuid . '.' . $extension;
                
                // Store file using Storage facade directly
                $storedPath = Storage::disk('public')->putFileAs(
                    'support/' . $ticket->id,
                    $image,
                    $uuid . '.' . $extension
                );
                
                // Verify file was stored
                if (!$storedPath || !Storage::disk('public')->exists($storedPath)) {
                    \Illuminate\Support\Facades\Log::error('Admin image upload error: File not stored. Path: ' . ($storedPath ?? 'null'));
                    if ($request->expectsJson()) {
                        return response()->json([
                            'success' => false,
                            'message' => 'Failed to save image. Please try again.'
                        ], 500);
                    }
                    return redirect()->back()->with('error', 'Failed to save image. Please try again.');
                }
                
                // Get relative path for database (without 'public/' prefix)
                $imagePath = $storedPath; // Storage::disk('public') already returns path without 'public/' prefix
                
                // Verify file actually exists on disk
                $fullPath = storage_path('app/public/' . $imagePath);
                if (!file_exists($fullPath)) {
                    \Illuminate\Support\Facades\Log::error('Admin image upload error: File not found on disk. Full path: ' . $fullPath);
                    if ($request->expectsJson()) {
                        return response()->json([
                            'success' => false,
                            'message' => 'Failed to save image. Please try again.'
                        ], 500);
                    }
                    return redirect()->back()->with('error', 'Failed to save image. Please try again.');
                }
                
                \Illuminate\Support\Facades\Log::info('Admin image uploaded successfully: ' . $imagePath . ' | Full path: ' . $fullPath . ' | Size: ' . filesize($fullPath) . ' bytes');
            } catch (\Exception $e) {
                \Illuminate\Support\Facades\Log::error('Admin image upload error: ' . $e->getMessage() . ' | Trace: ' . $e->getTraceAsString());
                if ($request->expectsJson()) {
                    return response()->json([
                        'success' => false,
                        'message' => 'Failed to upload image: ' . $e->getMessage()
                    ], 500);
                }
                return redirect()->back()->with('error', 'Failed to upload image: ' . $e->getMessage());
            }
        }

        // Create admin message
        try {
            $message = SupportMessage::create([
                'ticket_id' => $ticket->id,
                'sender_type' => 'admin',
                'sender_id' => null, // Admins are not in users table, so set to null
                'message' => $request->message,
                'image' => $imagePath,
                'is_read' => false,
            ]);

            // Update ticket
            $ticket->update([
                'last_message_at' => now(),
                'status' => 'pending', // Mark as pending after admin responds
            ]);

            // If AJAX request, return JSON
            if ($request->expectsJson()) {
                // Generate image URL with correct base URL from request
                $baseUrl = $this->getBaseUrl($request);
                
                $imageUrl = null;
                if ($message->image) {
                    $imagePath = ltrim($message->image, '/');
                    if (!str_starts_with($imagePath, 'storage/')) {
                        $imagePath = 'storage/' . $imagePath;
                    }
                    $imageUrl = rtrim($baseUrl, '/') . '/' . $imagePath;
                }
                
                return response()->json([
                    'success' => true,
                    'message' => [
                        'id' => $message->id,
                        'sender_type' => $message->sender_type,
                        'message' => $message->message,
                        'image' => $imageUrl,
                        'created_at' => $message->created_at->toISOString(),
                        'time' => $message->created_at->format('H:i'),
                    ]
                ]);
            }

            return redirect()->back()->with('success', 'Message sent successfully');
        } catch (\Exception $e) {
            \Illuminate\Support\Facades\Log::error('Admin message creation error: ' . $e->getMessage());
            if ($request->expectsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Failed to send message. Please try again.'
                ], 500);
            }
            return redirect()->back()->with('error', 'Failed to send message. Please try again.');
        }
    }

    public function updateStatus(Request $request, $id): RedirectResponse
    {
        $request->validate([
            'status' => 'required|in:open,pending,resolved,closed',
        ]);

        $ticket = SupportTicket::findOrFail($id);
        $ticket->update(['status' => $request->status]);

        return redirect()->back()->with('success', 'Ticket status updated');
    }

    /**
     * Update a support message (admin only)
     */
    public function updateMessage(Request $request, $messageId)
    {
        $message = SupportMessage::findOrFail($messageId);
        
        // Only allow updating admin messages
        if ($message->sender_type !== 'admin') {
            if ($request->expectsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => 'You can only edit admin messages'
                ], 403);
            }
            return redirect()->back()->with('error', 'You can only edit admin messages');
        }

        $request->validate([
            'message' => 'nullable|string|max:5000',
            'image' => 'nullable|image|max:5120',
        ]);

        // Ensure at least message or image is provided
        if (empty($request->message) && !$request->hasFile('image')) {
            if ($request->expectsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Please provide a message or image'
                ], 422);
            }
            return redirect()->back()->with('error', 'Please provide a message or image');
        }

        try {
            // Handle image upload if provided
            $imagePath = $message->image; // Keep existing image if not updating
            if ($request->hasFile('image')) {
                $image = $request->file('image');
                
                if (!$image->isValid()) {
                    if ($request->expectsJson()) {
                        return response()->json([
                            'success' => false,
                            'message' => 'Invalid image file. Please try again.'
                        ], 422);
                    }
                    return redirect()->back()->with('error', 'Invalid image file. Please try again.');
                }
                
                // Delete old image if exists
                if ($message->image) {
                    $oldPath = storage_path('app/public/' . $message->image);
                    if (file_exists($oldPath)) {
                        @unlink($oldPath);
                    }
                }
                
                // Store new image
                $directory = 'public/support/' . $message->ticket_id;
                Storage::makeDirectory($directory, 0755, true);
                
                $uuid = Str::uuid();
                $extension = $image->getClientOriginalExtension();
                
                $storedPath = Storage::disk('public')->putFileAs(
                    'support/' . $message->ticket_id,
                    $image,
                    $uuid . '.' . $extension
                );
                
                if (!$storedPath || !Storage::disk('public')->exists($storedPath)) {
                    if ($request->expectsJson()) {
                        return response()->json([
                            'success' => false,
                            'message' => 'Failed to save image. Please try again.'
                        ], 500);
                    }
                    return redirect()->back()->with('error', 'Failed to save image. Please try again.');
                }
                
                $imagePath = $storedPath;
            }

            // Update message
            $message->update([
                'message' => $request->message ?: null,
                'image' => $imagePath,
            ]);

            if ($request->expectsJson()) {
                $baseUrl = $this->getBaseUrl($request);
                $imageUrl = null;
                if ($message->image) {
                    $imagePath = ltrim($message->image, '/');
                    if (!str_starts_with($imagePath, 'storage/')) {
                        $imagePath = 'storage/' . $imagePath;
                    }
                    $imageUrl = rtrim($baseUrl, '/') . '/' . $imagePath;
                }

                return response()->json([
                    'success' => true,
                    'message' => [
                        'id' => $message->id,
                        'sender_type' => $message->sender_type,
                        'message' => $message->message,
                        'image' => $imageUrl,
                        'created_at' => $message->created_at->toISOString(),
                        'time' => $message->created_at->format('H:i'),
                    ]
                ]);
            }

            return redirect()->back()->with('success', 'Message updated successfully');
        } catch (\Exception $e) {
            \Illuminate\Support\Facades\Log::error('Update message error: ' . $e->getMessage());
            if ($request->expectsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Failed to update message: ' . $e->getMessage()
                ], 500);
            }
            return redirect()->back()->with('error', 'Failed to update message: ' . $e->getMessage());
        }
    }

    /**
     * Delete a support message (admin only)
     */
    public function deleteMessage(Request $request, $messageId)
    {
        $message = SupportMessage::findOrFail($messageId);
        
        // Only allow deleting admin messages
        if ($message->sender_type !== 'admin') {
            if ($request->expectsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => 'You can only delete admin messages'
                ], 403);
            }
            return redirect()->back()->with('error', 'You can only delete admin messages');
        }

        try {
            // Delete image file if exists
            if ($message->image) {
                $imagePath = storage_path('app/public/' . $message->image);
                if (file_exists($imagePath)) {
                    @unlink($imagePath);
                }
            }

            // Delete message
            $message->delete();

            if ($request->expectsJson()) {
                return response()->json([
                    'success' => true,
                    'message' => 'Message deleted successfully'
                ]);
            }

            return redirect()->back()->with('success', 'Message deleted successfully');
        } catch (\Exception $e) {
            \Illuminate\Support\Facades\Log::error('Delete message error: ' . $e->getMessage());
            if ($request->expectsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Failed to delete message: ' . $e->getMessage()
                ], 500);
            }
            return redirect()->back()->with('error', 'Failed to delete message: ' . $e->getMessage());
        }
    }
}
