<?php

namespace App\Http\Controllers;

use App\Events\MessageSent;
use App\Models\Conversation;
use App\Models\Message;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
class MessageController extends Controller
{
    public function getConversations(Request $request)
    {
        $user = Auth::user();
        $userTable = $this->getUserTable();
        
        // Get customer and workspace info
        [$customerId, $workspaceId] = $this->getCustomerAndWorkspaceIdsForChat($user, $userTable);
        
        // Determine user ID and participant type
        $userId = $user->id;
        $participantType = $userTable === 'emp' ? 'emp' : 'user';


        $conversations = Conversation::where(function($query) use ($userId, $participantType) {
            $query->where(function($q) use ($userId, $participantType) {
                $q->where('participant1_id', $userId)
                  ->where('participant1_type', $participantType);
            })->orWhere(function($q) use ($userId, $participantType) {
                $q->where('participant2_id', $userId)
                  ->where('participant2_type', $participantType);
                });
        })
        ->where('customer_id', $customerId)
        ->where('workspace_id', $workspaceId)
        ->where('is_active', true)
        ->with(['participant1', 'participant2', 'lastMessage'])
        ->orderBy('last_message_at', 'desc')
        ->get();


        $conversations = $conversations->map(function ($conversation) use ($userId, $participantType) {
            $otherParticipant = $conversation->getOtherParticipant($userId, $participantType);
            
            
            return [
                'id' => $conversation->id,
                'participant_id' => $otherParticipant->id ?? null,
                'participant_name' => $conversation->getParticipantName($otherParticipant),
                'avatar' => $conversation->getParticipantAvatar($otherParticipant),
                'last_message' => $conversation->lastMessage?->message ?? 'No messages yet',
                'last_message_time' => $conversation->lastMessage?->getRawOriginal('created_at') ? \Carbon\Carbon::parse($conversation->lastMessage->getRawOriginal('created_at'))->format('Y-m-d h:i:s A') : null,
                'unread_count' => $this->getUnreadCount($conversation->id, $userId, $participantType),
            ];
        });

        return response()->json([
            'success' => true,
            'conversations' => $conversations
        ]);
    }

    public function getMessages($conversationId, Request $request)
    {
        $user = Auth::user();
        $userTable = $this->getUserTable();
        $participantType = $userTable === 'emp' ? 'emp' : 'user';

        // Verify user has access to this conversation
        $conversation = Conversation::where('id', $conversationId)
            ->where(function($query) use ($user, $participantType) {
                $query->where(function($q) use ($user, $participantType) {
                    $q->where('participant1_id', $user->id)
                      ->where('participant1_type', $participantType);
                })->orWhere(function($q) use ($user, $participantType) {
                    $q->where('participant2_id', $user->id)
                      ->where('participant2_type', $participantType);
                });
            })
            ->firstOrFail();

        $messages = Message::where('conversation_id', $conversationId)
            ->with(['senderEmployee.empPersonalDetails', 'senderUser'])
            ->orderBy('created_at', 'asc')
            ->get()
            ->map(function ($message) {
                return [
                    'id' => $message->id,
                    'message' => $message->message,
                    'sender_id' => $message->sender_id,
                    'sender_type' => $message->sender_type,
                    'receiver_id' => $message->receiver_id,
                    'receiver_type' => $message->receiver_type,
                    'message_type' => $message->message_type,
                    'attachment_path' => $message->attachment_path,
                    'is_read' => $message->is_read,
                    'created_at' => $message->getRawOriginal('created_at') ? \Carbon\Carbon::parse($message->getRawOriginal('created_at'))->format('Y-m-d h:i:s A') : null,
                    'sender' => [
                        'id' => $message->sender_id,
                        'name' => $message->getSenderName(),
                        'image' => $message->getSenderImage()
                    ]
                ];
            });

        // Mark messages as read
        Message::where('conversation_id', $conversationId)
            ->where('receiver_id', $user->id)
            ->where('receiver_type', $participantType)
            ->where('is_read', false)
            ->update(['is_read' => true]);

        return response()->json([
            'success' => true,
            'messages' => $messages
        ]);
    }

    public function sendMessage(Request $request)
    {
        $user = Auth::user();
        $userTable = $this->getUserTable();
        
        // Validate input
        $validator = Validator::make($request->all(), [
            'message' => 'required|string|max:1000',
            'conversation_id' => 'nullable',
            'message_type' => 'required|in:text,image,file',
            'attachment_path' => 'nullable|string|max:255',
            'receiver_id' => 'required|integer',
            'receiver_type' => 'nullable|in:user,emp'
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'errors' => $validator->errors()
            ], 422);
        }

        // Determine sender/receiver types
        $senderType = $userTable === 'emp' ? 'emp' : 'user';
        $receiverType = $request->receiver_type ?: ($request->receiver_emp_id ? 'emp' : 'user');

        // Get customer and workspace info
        [$customerId, $workspaceId] = $this->getCustomerAndWorkspaceIdsForChat($user, $userTable);

        // Validate that we have valid customer and workspace IDs
        if (!$customerId || !$workspaceId) {
            return response()->json([
                'success' => false,
                'message' => 'Customer or workspace information is missing'
            ], 400);
        }

        // Handle conversation - create new or find existing
        if ($request->conversation_id) {
            // Verify user has access to existing conversation
            $conversation = Conversation::where('id', $request->conversation_id)
                ->where(function($query) use ($user, $senderType) {
                    $query->where(function($q) use ($user, $senderType) {
                        $q->where('participant1_id', $user->id)
                          ->where('participant1_type', $senderType);
                    })->orWhere(function($q) use ($user, $senderType) {
                        $q->where('participant2_id', $user->id)
                          ->where('participant2_type', $senderType);
                    });
                })
                ->where('customer_id', $customerId)
                ->where('workspace_id', $workspaceId)
                ->firstOrFail();
        } else {
            // Create new conversation
            $conversation = $this->findOrCreateConversation($user, $senderType, $request->receiver_id, $receiverType, $customerId, $workspaceId);
        }

        // Create message
        $message = Message::create([
            'sender_id' => $user->id,
            'sender_type' => $senderType,
            'receiver_id' => $request->receiver_id,
            'receiver_type' => $receiverType,
            'message' => $request->message,
            'conversation_id' => $conversation->id,
            'message_type' => $request->message_type,
            'attachment_path' => $request->attachment_path,
            'customer_id' => $customerId,
            'workspace_id' => $workspaceId,
            'is_read' => false,
        ]);

        // Load relationships for broadcasting
        if ($message->sender_type === 'emp') {
            $message->load(['senderEmployee.empPersonalDetails', 'senderEmployee.tierEmpPersonalDetail']);
        } else {
            $message->load('senderUser');
        }

        // Update conversation last message time
        $conversation->update(['last_message_at' => now()]);

        // Broadcast the message
        broadcast(new MessageSent($message));

        return response()->json([
            'success' => true,
            'data' => [
                'id' => $message->id,
                'conversation_id' => $message->conversation_id,
                'created_at' => $message->created_at,
                'message' => [
                    'id' => $message->id,
                    'message' => $message->message,
                    'sender_id' => $message->sender_id,
                    'sender_type' => $message->sender_type,
                    'message_type' => $message->message_type,
                    'created_at' => $message->created_at,
                ]
            ]
        ]);
    }

    public function startConversation(Request $request)
    {
        $user = Auth::user();
        $userTable = $this->getUserTable();
        
        // Validate input
        $validator = Validator::make($request->all(), [
            'receiver_id' => 'required|integer',
            'receiver_type' => 'required|in:user,emp'
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'errors' => $validator->errors()
            ], 422);
        }

        // Determine sender/receiver types
        $senderType = $userTable === 'emp' ? 'emp' : 'user';
        $receiverType = $request->receiver_type;

        // Get customer and workspace info
        [$customerId, $workspaceId] = $this->getCustomerAndWorkspaceIdsForChat($user, $userTable);

        // Validate customer and workspace info
        if (!$customerId || !$workspaceId) {
            return response()->json([
                'success' => false,
                'message' => 'Customer or workspace information is missing. Please ensure your account is properly configured.'
            ], 400);
        }

        // Find or create conversation
        $conversation = $this->findOrCreateConversation($user, $senderType, $request->receiver_id, $receiverType, $customerId, $workspaceId);

        return response()->json([
            'success' => true,
            'data' => [
                'conversation_id' => $conversation->id,
                'participant_id' => $request->receiver_id,
                'participant_type' => $receiverType,
                'created_at' => $conversation->created_at,
            ]
        ]);
    }

    public function getUserTable($user = null)
    {
        if (!$user) {
            $user = Auth::user();
        }
        if ($user instanceof \App\Models\User) {
            return 'customer';
        }
        if ($user instanceof \App\Models\EmpCompanyDetails) {
            return 'emp';
        }
        return 'customer';
    }

    private function getUnreadCount($conversationId, $userId, $userType)
    {
        return Message::where('conversation_id', $conversationId)
            ->where('receiver_id', $userId)
            ->where('receiver_type', $userType)
            ->where('is_read', false)
            ->count();
    }

    private function getCustomerAndWorkspaceIdsForChat($user, $userTable)
    {
        if ($userTable === 'customer') {
            // For customers, user ID is the customer ID
            $customerId = $user->id;
            $workspaceId = $user->current_workspace_id ?? 1;
        } elseif ($userTable === 'emp') {
            // For employees, get from user object or database
            $customerId = $user->customer_id ?? null;
            $workspaceId = $user->workspace_id ?? null;
            
            // If still null, try to get from database
            if (!$customerId || !$workspaceId) {
                $empDetails = \App\Models\EmpCompanyDetails::find($user->id);
                if ($empDetails) {
                    $customerId = $empDetails->customer_id ?? 1;
                    $workspaceId = $empDetails->workspace_id ?? 1;
                } else {
                    // Final fallback
                    $customerId = 1;
                    $workspaceId = 1;
                }
            }
        } else {
            // For regular users (user table), they are customers
            $customerId = $user->id;
            $workspaceId = $user->current_workspace_id ?? 1;
        }

        // Ensure we have valid IDs
        $customerId = $customerId ?? 1;
        $workspaceId = $workspaceId ?? 1;

        return [$customerId, $workspaceId];
    }

    private function findOrCreateConversation($user, $senderType, $receiverId, $receiverType, $customerId, $workspaceId)
    {
        // First, try to find existing conversation
        $conversation = Conversation::where(function($q) use ($user, $senderType, $receiverId, $receiverType) {
                $q->where('participant1_id', $user->id)
                  ->where('participant1_type', $senderType)
                  ->where('participant2_id', $receiverId)
                  ->where('participant2_type', $receiverType);
            })
            ->orWhere(function($q) use ($user, $senderType, $receiverId, $receiverType) {
                $q->where('participant1_id', $receiverId)
                  ->where('participant1_type', $receiverType)
                  ->where('participant2_id', $user->id)
                  ->where('participant2_type', $senderType);
            })
            ->where('customer_id', $customerId)
            ->where('workspace_id', $workspaceId)
            ->where('is_active', true)
            ->first();

        if ($conversation) {
            return $conversation;
        }

        // Create new conversation
        $conversationData = [
            'participant1_id' => $user->id,
            'participant1_type' => $senderType,
            'participant2_id' => $receiverId,
            'participant2_type' => $receiverType,
            'customer_id' => $customerId,
            'workspace_id' => $workspaceId,
            'is_active' => true,
            'last_message_at' => now()
        ];

        return Conversation::create($conversationData);
    }

}
