<?php

namespace App\Http\Controllers;

use App\Models\TicketAgent;
use App\Models\User;
use App\Models\Staff;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class TicketAgentController extends Controller
{
    /**
     * Display a listing of agents
     */
    public function index(Request $request)
    {
        $query = TicketAgent::with(['user', 'device'])
            ->where('device_id', session('device_id'));

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

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

        $agents = $query->orderBy('created_at', 'desc')->paginate(20);

        // Get statistics
        $statistics = [
            'total' => TicketAgent::where('device_id', session('device_id'))->count(),
            'online' => TicketAgent::where('device_id', session('device_id'))->online()->count(),
            'available' => TicketAgent::where('device_id', session('device_id'))->available()->count(),
        ];

        return view('support.agents.index', compact('agents', 'statistics'));
    }

    /**
     * Show the form for creating a new agent
     */
    public function create()
    {
        $user = Auth::user();
        $deviceId = session('device_id') ?? $user->devices()->first()?->id;
        
        if (!$deviceId) {
            return redirect()->route('support.agents.index')
                ->with('error', 'Please select a device first.');
        }
        
        // Get users who are not already agents for this device
        $existingAgentUserIds = TicketAgent::where('device_id', $deviceId)->pluck('user_id');
        
        // Get staff members for this device who are not already agents
        $staffMembers = Staff::where('user_id', $user->id)
            ->where('device_id', $deviceId)
            ->where('status', 'active')
            ->whereNotIn('id', function($query) use ($deviceId) {
                $query->select('user_id')
                    ->from('ticket_agents')
                    ->where('device_id', $deviceId);
            })
            ->get();
        
        // For admin, show all users. For regular users, only show themselves
        if ($user->role === 'admin') {
            $availableUsers = User::whereNotIn('id', $existingAgentUserIds)->get();
        } else {
            // Regular users can only add themselves as an agent
            $availableUsers = User::where('id', $user->id)
                ->whereNotIn('id', $existingAgentUserIds)
                ->get();
        }

        return view('support.agents.create', compact('availableUsers', 'staffMembers'));
    }

    /**
     * Store a newly created agent
     */
    public function store(Request $request)
    {
        $user = Auth::user();
        
        $validated = $request->validate([
            'user_id' => 'required|string',
            'role' => 'required|in:agent,supervisor,admin',
            'max_tickets' => 'required|integer|min:1|max:50',
            'auto_assign' => 'nullable',
            'permissions' => 'nullable|array',
        ]);

        // Check if user_id is a staff member (starts with 'staff_')
        $isStaff = str_starts_with($validated['user_id'], 'staff_');
        $actualUserId = null;
        
        if ($isStaff) {
            // Extract staff ID
            $staffId = (int) str_replace('staff_', '', $validated['user_id']);
            $staff = Staff::where('id', $staffId)
                ->where('user_id', $user->id)
                ->firstOrFail();
            
            // Check if staff member already has a user account
            $existingUser = User::where('email', $staff->staff_email)->first();
            
            if ($existingUser) {
                $actualUserId = $existingUser->id;
            } else {
                // Create a user account for the staff member
                $newUser = User::create([
                    'name' => $staff->staff_name,
                    'email' => $staff->staff_email,
                    'phone' => $staff->staff_phone ?? '',
                    'password' => bcrypt(uniqid()), // Random password - staff should reset it
                    'role' => 'user',
                    'status' => 'active',
                    'email_verified_at' => now(),
                    'lang' => 'en',
                ]);
                
                $actualUserId = $newUser->id;
                
                // Link the user to the staff record
                $staff->update(['staff_user_id' => $actualUserId]);
            }
        } else {
            $actualUserId = (int) $validated['user_id'];
        }

        // Non-admin users can only create agents for themselves or their staff
        if ($user->role !== 'admin' && !$isStaff && $actualUserId != $user->id) {
            return back()->with('error', 'You can only add yourself or your staff as agents.');
        }

        // Get device_id from session or user's first device
        $device_id = session('device_id') ?? $user->devices()->first()?->id;
        
        if (!$device_id) {
            return back()->with('error', 'No device found. Please add a device first.');
        }

        $validated['device_id'] = $device_id;
        $validated['user_id'] = $actualUserId;
        $validated['status'] = 'offline';
        $validated['current_tickets'] = 0;
        $validated['auto_assign'] = $request->input('auto_assign') == '1' ? true : false;

        // Check if agent already exists for this device
        $existing = TicketAgent::where('user_id', $validated['user_id'])
            ->where('device_id', $validated['device_id'])
            ->first();

        if ($existing) {
            return back()->with('error', 'This user is already an agent for this device.');
        }

        TicketAgent::create($validated);

        return redirect()->route('support.agents.index')
            ->with('success', 'Agent created successfully.');
    }

    /**
     * Display the specified agent
     */
    public function show($id)
    {
        $agent = TicketAgent::with(['user', 'device', 'activeTickets'])
            ->where('device_id', session('device_id'))
            ->findOrFail($id);

        // Get performance metrics for last 30 days
        $metrics = $agent->getPerformanceMetrics(
            now()->subDays(30),
            now()
        );

        return view('support.agents.show', compact('agent', 'metrics'));
    }

    /**
     * Show the form for editing the specified agent
     */
    public function edit($id)
    {
        $agent = TicketAgent::with('user')
            ->where('device_id', session('device_id'))
            ->findOrFail($id);
        return view('support.agents.edit', compact('agent'));
    }

    /**
     * Update the specified agent
     */
    public function update(Request $request, $id)
    {
        $agent = TicketAgent::where('device_id', session('device_id'))->findOrFail($id);

        $validated = $request->validate([
            'role' => 'required|in:agent,supervisor,admin',
            'max_tickets' => 'required|integer|min:1|max:50',
            'auto_assign' => 'nullable|boolean',
            'permissions' => 'nullable|array',
        ]);

        $validated['auto_assign'] = $request->boolean('auto_assign', false);

        $agent->update($validated);

        return redirect()->route('support.agents.index')
            ->with('success', 'Agent updated successfully.');
    }

    /**
     * Remove the specified agent
     */
    public function destroy($id)
    {
        $agent = TicketAgent::where('device_id', session('device_id'))->findOrFail($id);
        
        // Check if agent has active tickets
        if ($agent->current_tickets > 0) {
            return back()->with('error', 'Cannot delete agent with active tickets. Please reassign tickets first.');
        }

        $agent->delete();

        return redirect()->route('support.agents.index')
            ->with('success', 'Agent deleted successfully.');
    }

    /**
     * Update agent status
     */
    public function updateStatus(Request $request, $id)
    {
        $request->validate([
            'status' => 'required|in:online,offline,busy,away',
        ]);

        $agent = TicketAgent::where('device_id', session('device_id'))->findOrFail($id);
        $agent->updateStatus($request->status);

        return back()->with('success', 'Status updated successfully.');
    }

    /**
     * Get available agents for assignment
     */
    public function getAvailableAgents(Request $request)
    {
        $deviceId = $request->get('device_id', session('device_id'));

        $agents = TicketAgent::available()
            ->forDevice($deviceId)
            ->with('user')
            ->get()
            ->map(function ($agent) {
                return [
                    'id' => $agent->user_id,
                    'name' => $agent->user->name,
                    'current_tickets' => $agent->current_tickets,
                    'max_tickets' => $agent->max_tickets,
                ];
            });

        return response()->json($agents);
    }

    /**
     * Get performance report for agents
     */
    public function getPerformanceReport(Request $request)
    {
        $deviceId = session('device_id');
        $startDate = $request->get('start_date', now()->subDays(30));
        $endDate = $request->get('end_date', now());

        $agents = TicketAgent::forDevice($deviceId)
            ->with('user')
            ->get();

        $report = $agents->map(function ($agent) use ($startDate, $endDate) {
            $metrics = $agent->getPerformanceMetrics($startDate, $endDate);
            return [
                'agent_name' => $agent->user->name,
                'role' => $agent->role,
                'status' => $agent->status,
                'metrics' => $metrics,
            ];
        });

        if ($request->wantsJson()) {
            return response()->json($report);
        }

        return view('support.agents.performance', compact('report', 'startDate', 'endDate'));
    }
}
