<?php

namespace App\Http\Controllers;

use App\Models\User;
use App\Models\Visit;
use App\Models\Client;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Schema;
use Spatie\Permission\Models\Role;

class LiveTrackingController extends Controller
{
    public function index()
    {
        $user = Auth::user();
        
        // Get active visits based on user role
        $query = Visit::with(['employee', 'client']);
        
        if ($user->isSupervisor()) {
            // Supervisor sees visits of their subordinates
            $subordinateIds = $user->subordinates()->pluck('id');
            $query->whereIn('employee_id', $subordinateIds);
        } elseif ($user->isEmployee()) {
            // Employee sees only their own visits
            $query->where('employee_id', $user->id);
        }
        
        $activeVisits = $query->where('status', 'in_progress')->get();
        
        // Get active employees based on role
        $employeeQuery = User::role('employee')->where('status', 'active');
        
        if ($user->isSupervisor()) {
            $employeeQuery->where('supervisor_id', $user->id);
        } elseif ($user->isEmployee()) {
            $employeeQuery->where('id', $user->id);
        }
        
        $activeEmployees = $employeeQuery->whereHas('visits', function($query) {
            $query->where('status', 'in_progress');
        })->with(['currentVisit'])->get();
        
        return view('live-tracking.index', compact('activeVisits', 'activeEmployees'));
    }

    public function map()
    {
        $user = Auth::user();
        
        // Get active visits based on user role
        $visitQuery = Visit::where('status', 'in_progress')
            ->with(['employee', 'client']);
            
        if ($user->isSupervisor()) {
            $subordinateIds = $user->subordinates()->pluck('id');
            $visitQuery->whereIn('employee_id', $subordinateIds);
        } elseif ($user->isEmployee()) {
            $visitQuery->where('employee_id', $user->id);
        }
        
        $activeVisits = $visitQuery->get();
        
        // Get clients based on role
        $clientQuery = Client::query();
        
        if (!$user->isAdmin()) {
            // Non-admins see only clients they have visited
            $clientQuery->whereHas('visits', function($query) use ($user) {
                $query->where('employee_id', $user->id);
                if ($user->isSupervisor()) {
                    $subordinateIds = $user->subordinates()->pluck('id');
                    $query->orWhereIn('employee_id', $subordinateIds);
                }
            });
        }
        
        $clients = $clientQuery->get();
        
        return view('live-tracking.map', compact('activeVisits', 'clients'));
    }

    public function employees()
    {
        $user = Auth::user();
        
        // Get employees based on user role
        $employeeQuery = User::role('employee')->where('status', 'active');
        
        if ($user->isSupervisor()) {
            $employeeQuery->where('supervisor_id', $user->id);
        } elseif ($user->isEmployee()) {
            $employeeQuery->where('id', $user->id);
        }
        
        $employees = $employeeQuery->with(['department', 'currentVisit'])->get();
        
        return view('live-tracking.employees', compact('employees'));
    }

    public function getEmployeeLocation($employeeId)
    {
        $user = Auth::user();
        
        // Check if user has permission to view this employee's location
        if (!$this->canViewEmployee($user, $employeeId)) {
            return response()->json([
                'success' => false,
                'message' => 'Unauthorized to view this employee location'
            ], 403);
        }
        
        $employee = User::findOrFail($employeeId);
        
        // Get the latest location from visits
        $latestVisit = Visit::where('employee_id', $employeeId)
            ->where('status', 'in_progress')
            ->latest()
            ->first();
        
        if ($latestVisit && $latestVisit->current_latitude && $latestVisit->current_longitude) {
            return response()->json([
                'success' => true,
                'employee' => [
                    'id' => $employee->id,
                    'name' => $employee->name,
                    'employee_id' => $employee->employee_id,
                ],
                'location' => [
                    'latitude' => $latestVisit->current_latitude,
                    'longitude' => $latestVisit->current_longitude,
                    'address' => $latestVisit->current_address,
                    'updated_at' => $latestVisit->updated_at->format('Y-m-d H:i:s'),
                ],
                'visit' => [
                    'id' => $latestVisit->id,
                    'client_name' => $latestVisit->client->name ?? 'N/A',
                    'status' => $latestVisit->status,
                ]
            ]);
        }
        
        return response()->json([
            'success' => false,
            'message' => 'No active location found for this employee'
        ]);
    }

    public function getEmployeeRoute($employeeId)
    {
        $user = Auth::user();
        
        // Check if user has permission to view this employee's route
        if (!$this->canViewEmployee($user, $employeeId)) {
            return response()->json([
                'success' => false,
                'message' => 'Unauthorized to view this employee route'
            ], 403);
        }
        
        $employee = User::findOrFail($employeeId);
        
        // Get route history from visit checkpoints
        $visit = Visit::where('employee_id', $employeeId)
            ->where('status', 'in_progress')
            ->latest()
            ->first();
        
        if ($visit && $visit->checkpoints) {
            $checkpoints = json_decode($visit->checkpoints, true);
            
            return response()->json([
                'success' => true,
                'employee' => [
                    'id' => $employee->id,
                    'name' => $employee->name,
                ],
                'route' => $checkpoints,
                'visit' => [
                    'id' => $visit->id,
                    'start_location' => [
                        'latitude' => $visit->start_latitude,
                        'longitude' => $visit->start_longitude,
                    ],
                    'destination' => [
                        'latitude' => $visit->destination_latitude,
                        'longitude' => $visit->destination_longitude,
                    ]
                ]
            ]);
        }
        
        return response()->json([
            'success' => false,
            'message' => 'No route history found'
        ]);
    }

    public function getActiveEmployees()
    {
        $user = Auth::user();
        
        // Get employees based on user role
        $employeeQuery = User::role('employee')
            ->where('status', 'active')
            ->whereHas('visits', function($query) {
                $query->where('status', 'in_progress');
            });
        
        if ($user->isSupervisor()) {
            $employeeQuery->where('supervisor_id', $user->id);
        } elseif ($user->isEmployee()) {
            $employeeQuery->where('id', $user->id);
        }
        
        $activeEmployees = $employeeQuery->with(['visits' => function($query) {
            $query->where('status', 'in_progress')->with('client');
        }])->get();
        
        $formattedData = $activeEmployees->map(function($employee) {
            $visit = $employee->visits->first();
            return [
                'id' => $employee->id,
                'name' => $employee->name,
                'employee_id' => $employee->employee_id,
                'phone' => $employee->phone,
                'department' => $employee->department->name ?? 'N/A',
                'latitude' => $visit->current_latitude ?? null,
                'longitude' => $visit->current_longitude ?? null,
                'address' => $visit->current_address ?? 'Location not available',
                'last_update' => $visit ? $visit->updated_at->diffForHumans() : 'Never',
                'visit' => $visit ? [
                    'id' => $visit->id,
                    'client' => $visit->client->name ?? 'N/A',
                    'status' => $visit->status,
                    'started_at' => $visit->started_at ? $visit->started_at->format('H:i') : 'N/A'
                ] : null
            ];
        });
        
        return response()->json([
            'success' => true,
            'employees' => $formattedData,
            'count' => $activeEmployees->count()
        ]);
    }

    public function history($employeeId)
    {
        $user = Auth::user();
        
        // Check if user has permission to view this employee's history
        if (!$this->canViewEmployee($user, $employeeId)) {
            abort(403, 'Unauthorized to view this employee history');
        }
        
        $employee = User::findOrFail($employeeId);
        
        $visits = Visit::where('employee_id', $employeeId)
            ->whereIn('status', ['completed', 'in_progress'])
            ->with('client')
            ->orderBy('created_at', 'desc')
            ->paginate(20);
        
        return view('live-tracking.history', compact('employee', 'visits'));
    }

    public function alerts()
    {
        $user = Auth::user();
        
        // Get visits that are overdue based on role
        $query = Visit::where('status', 'in_progress');
        
        if ($user->isSupervisor()) {
            $subordinateIds = $user->subordinates()->pluck('id');
            $query->whereIn('employee_id', $subordinateIds);
        } elseif ($user->isEmployee()) {
            $query->where('employee_id', $user->id);
        }
        
        if (Schema::hasColumn('visits', 'scheduled_end')) {
            $query->where(function($q) {
                $q->where('scheduled_end', '<', now())
                  ->orWhere('last_location_update', '<', now()->subMinutes(30));
            });
        } else {
            $query->where('last_location_update', '<', now()->subMinutes(30));
        }
        
        $alerts = $query->with(['employee', 'client'])->get();
        
        return view('live-tracking.alerts', compact('alerts'));
    }
    
    /**
     * Check if user can view employee data
     */
    private function canViewEmployee($user, $employeeId)
    {
        if ($user->isAdmin()) {
            return true;
        }
        
        if ($user->isSupervisor()) {
            $subordinateIds = $user->subordinates()->pluck('id')->toArray();
            return in_array($employeeId, $subordinateIds) || $user->id == $employeeId;
        }
        
        if ($user->isEmployee()) {
            return $user->id == $employeeId;
        }
        
        return false;
    }
}