<?php

namespace App\Http\Controllers;

use App\Models\LiveChat;
use App\Models\LiveChatMessage;
use App\Models\Visitor;
use App\Models\Role;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Stevebauman\Location\Facades\Location;
use App\Notifications\AdminChatNotification;

class LiveChatController extends Controller
{
    /**
     * Initialize chat session for visitor
     */
    public function initChat(Request $request)
    {
        $request->validate([
            'visitor_token' => 'nullable|string',
            'page_url' => 'nullable|string',
            'page_title' => 'nullable|string',
            'referrer' => 'nullable|string',
        ]);

        // Get or create visitor
        $visitor = null;
        if ($request->visitor_token) {
            $visitor = Visitor::where('visitor_token', $request->visitor_token)->first();
        }

        // Create new visitor if not exists
        if (!$visitor) {
            $visitor = Visitor::create([
                'visitor_token' => Visitor::generateToken(),
                'last_active_at' => now(),
                'user_id' => Auth::check() ? Auth::id() : null
            ]);
        } else {
            // Update last active time
            $visitor->last_active_at = now();
            
            // If user is logged in and visitor doesn't have a user_id, associate them
            if (Auth::check() && !$visitor->user_id) {
                $visitor->user_id = Auth::id();
            }
            
            $visitor->save();
        }

        // Get client IP address and location data
        $ip = $request->ip();
        $locationData = Location::get($ip);
        $locationString = null;

        if ($locationData) {
            $locationString = $locationData->cityName . ', ' . $locationData->regionName . ', ' . $locationData->countryName;
        }

        // Return visitor token
        return response()->json([
            'status' => 'success',
            'visitor_token' => $visitor->visitor_token,
            'location' => $locationString
        ]);
    }

    /**
     * Start a new chat
     */
    public function startChat(Request $request)
    {
        $request->validate([
            'visitor_token' => 'required|string',
            'message' => 'required|string',
            'name' => 'nullable|string',
            'email' => 'nullable|email',
            'page_url' => 'nullable|string',
            'page_title' => 'nullable|string',
        ]);

        // Find visitor
        $visitor = Visitor::where('visitor_token', $request->visitor_token)->first();
        if (!$visitor) {
            return response()->json([
                'status' => 'error',
                'message' => 'Invalid visitor token'
            ], 400);
        }

        // Update visitor details if provided
        if ($request->name) {
            $visitor->name = $request->name;
        }
        
        if ($request->email) {
            $visitor->email = $request->email;
        }
        
        $visitor->save();

        // Get IP and location
        $ip = $request->ip();
        $locationData = Location::get($ip);
        $locationString = null;

        if ($locationData) {
            $locationString = $locationData->cityName . ', ' . $locationData->regionName . ', ' . $locationData->countryName;
        }

        // Create new chat
        $chat = LiveChat::create([
            'visitor_id' => $visitor->id,
            'status' => 'active',
            'ip_address' => $ip,
            'user_agent' => $request->header('User-Agent'),
            'location' => $locationString,
            'page_url' => $request->page_url,
            'page_title' => $request->page_title,
            'referrer' => $request->referrer ?? null,
        ]);

        // Create initial message
        $message = LiveChatMessage::create([
            'chat_id' => $chat->id,
            'sender_type' => 'visitor',
            'sender_id' => $visitor->id,
            'message' => $request->message,
        ]);

        // Add a system welcome message
        LiveChatMessage::create([
            'chat_id' => $chat->id,
            'sender_type' => 'system',
            'message' => 'Thank you for reaching out! Our team will be with you shortly.',
        ]);

        // Notify admin users
        $this->notifyAdmins($chat, $visitor, $request->message);

        return response()->json([
            'status' => 'success',
            'chat_id' => $chat->id,
            'messages' => $chat->messages()->orderBy('created_at', 'asc')->get()
        ]);
    }

    /**
     * Get chat history
     */
    public function getChatHistory(Request $request)
    {
        $request->validate([
            'visitor_token' => 'required|string',
        ]);

        // Find visitor
        $visitor = Visitor::where('visitor_token', $request->visitor_token)->first();
        if (!$visitor) {
            return response()->json([
                'status' => 'error',
                'message' => 'Invalid visitor token'
            ], 400);
        }

        // Find active chat
        $chat = LiveChat::where('visitor_id', $visitor->id)
            ->where('status', 'active')
            ->latest()
            ->first();

        if (!$chat) {
            return response()->json([
                'status' => 'success',
                'has_active_chat' => false
            ]);
        }

        // Mark all admin messages as read
        LiveChatMessage::where('chat_id', $chat->id)
            ->where('sender_type', 'admin')
            ->where('has_been_read', false)
            ->update(['has_been_read' => true]);

        return response()->json([
            'status' => 'success',
            'has_active_chat' => true,
            'chat_id' => $chat->id,
            'messages' => $chat->messages()->orderBy('created_at', 'asc')->get(),
            'unread_count' => LiveChatMessage::where('chat_id', $chat->id)
                ->where('sender_type', 'admin')
                ->where('has_been_read', false)
                ->count()
        ]);
    }

    /**
     * Send message as visitor
     */
    public function sendMessage(Request $request)
    {
        $request->validate([
            'visitor_token' => 'required|string',
            'chat_id' => 'required|integer',
            'message' => 'required|string'
        ]);

        // Find visitor
        $visitor = Visitor::where('visitor_token', $request->visitor_token)->first();
        if (!$visitor) {
            return response()->json([
                'status' => 'error',
                'message' => 'Invalid visitor token'
            ], 400);
        }

        // Find chat
        $chat = LiveChat::where('id', $request->chat_id)
            ->where('visitor_id', $visitor->id)
            ->where('status', 'active')
            ->first();

        if (!$chat) {
            return response()->json([
                'status' => 'error',
                'message' => 'Chat not found or not active'
            ], 404);
        }

        // Create message
        $message = LiveChatMessage::create([
            'chat_id' => $chat->id,
            'sender_type' => 'visitor',
            'sender_id' => $visitor->id,
            'message' => $request->message,
        ]);

        // If chat is assigned to an admin, notify them
        if ($chat->is_assigned && $chat->assigned_to) {
            $admin = User::find($chat->assigned_to);
            if ($admin) {
                // Create notification for assigned admin
                $title = 'New Chat Message';
                $content = ($visitor->name ?? 'Visitor') . ' sent a new message';
                $action = '/admin/live-chats/' . $chat->id;
                
                // $admin->pushMessage($title, $content, '', $action);
            }
        } else {
            // Chat isn't assigned, notify all admins
            // $this->notifyAdmins($chat, $visitor, $request->message, false);
        }

        return response()->json([
            'status' => 'success',
            'message' => 'Message sent'
        ]);
    }

    /**
     * Close chat (visitor side)
     */
    public function closeChat(Request $request)
    {
        $request->validate([
            'visitor_token' => 'required|string',
            'chat_id' => 'required|integer'
        ]);

        // Find visitor
        $visitor = Visitor::where('visitor_token', $request->visitor_token)->first();
        if (!$visitor) {
            return response()->json([
                'status' => 'error',
                'message' => 'Invalid visitor token'
            ], 400);
        }

        // Find chat
        $chat = LiveChat::where('id', $request->chat_id)
            ->where('visitor_id', $visitor->id)
            ->where('status', 'active')
            ->first();

        if (!$chat) {
            return response()->json([
                'status' => 'error',
                'message' => 'Chat not found or already closed'
            ], 404);
        }

        // Close chat
        $chat->status = 'closed';
        $chat->save();

        // Add system message
        LiveChatMessage::create([
            'chat_id' => $chat->id,
            'sender_type' => 'system',
            'message' => 'Chat ended by visitor',
        ]);

        return response()->json([
            'status' => 'success',
            'message' => 'Chat closed'
        ]);
    }

    /**
     * Notify admin users about new chat or messages
     */
    private function notifyAdmins($chat, $visitor, $message, $isNewChat = true)
    {
        // Find admin users
        $adminRoles = Role::where('role', 'admin')->get();
        
        foreach ($adminRoles as $adminRole) {
            $admin = User::find($adminRole->user_id);
            
            if ($admin) {
                // Send notification via email 
                $admin->notify(new AdminChatNotification($chat, $visitor, $message, $isNewChat));
                
                // Send push notification
                $title = $isNewChat ? 'New Live Chat' : 'New Chat Message';
                $content = $isNewChat 
                    ? 'New chat initiated by ' . ($visitor->name ?? 'visitor')
                    : 'New message from ' . ($visitor->name ?? 'visitor');
                $action = '/admin/live-chats/' . $chat->id;
                
                $admin->pushMessage($title, $content, '', $action);
            }
        }
    }
} 