<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Attendance;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use App\Services\ExifService;
use App\Services\GeofencingService;
use Illuminate\Support\Facades\Log;
use App\Traits\AttendanceDataTransformer;

class AttendanceController extends Controller
{
    use AttendanceDataTransformer;
    /**
     * Display a listing of the resource (Admin only).
     */
    public function index(Request $request)
    {
        $this->authorize('viewAny', Attendance::class);
        
        $user = Auth::user();
        $query = Attendance::with(['user', 'user.staffProfile']);
        
        // Filter by date range if provided
        if ($request->filled('start_date')) {
            $query->whereDate('date', '>=', $request->start_date);
        }
        if ($request->filled('end_date')) {
            $query->whereDate('date', '<=', $request->end_date);
        }
        
        // Admin can filter by user
        if ($request->filled('user_id')) {
            $query->where('user_id', $request->user_id);
        }
        $users = User::role('Staff')->get();
        
        $attendances = $query->latest('date')->paginate(15);
        
        return view('attendance.index', compact('attendances', 'users'));
    }

    /**
     * Display map view of attendance with locations (Admin only).
     */
    public function map(Request $request)
    {
        $this->authorize('viewAny', Attendance::class);
        
        $query = Attendance::with(['user', 'user.staffProfile'])
                          ->whereNotNull('latitude')
                          ->whereNotNull('longitude');
        
        // Filter by date range if provided
        if ($request->filled('start_date')) {
            $query->whereDate('date', '>=', $request->start_date);
        }
        if ($request->filled('end_date')) {
            $query->whereDate('date', '<=', $request->end_date);
        }
        
        // Admin can filter by user
        if ($request->filled('user_id')) {
            $query->where('user_id', $request->user_id);
        }
        
        $users = User::role('Staff')->get();
        $attendances = $query->latest('date')->get();
        
        return view('attendance.map', compact('attendances', 'users'));
    }
    
    /**
     * Display staff user's own attendance records.
     */
    public function staffAttendance()
    {
        $user = Auth::user();
        
        // Get user's attendance records for the current month
        $attendances = Attendance::where('user_id', $user->id)
                                ->whereMonth('date', now()->month)
                                ->whereYear('date', now()->year)
                                ->orderBy('date', 'desc')
                                ->get();
        
        return view('attendance.staff', compact('attendances', 'user'));
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        $this->authorize('create', Attendance::class);
        
        $users = User::role('Staff')->get();
        
        return view('attendance.create', compact('users'));
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        $this->authorize('create', Attendance::class);
        
        $validated = $request->validate([
            'user_id' => 'required|exists:users,id',
            'date' => 'required|date',
            'status' => 'required|in:present,absent,late,half_day',
            'notes' => 'nullable|string|max:500',
        ]);
        
        // Check if attendance already exists for this user and date
        $existingAttendance = Attendance::where('user_id', $validated['user_id'])
                                      ->whereDate('date', $validated['date'])
                                      ->first();
        
        if ($existingAttendance) {
            return back()->withErrors(['date' => 'Attendance for this user on this date already exists.']);
        }
        
        // Check if the date is a working day (Monday to Saturday)
        if (!Attendance::isWorkingDay(Carbon::parse($validated['date']))) {
            return back()->withErrors(['date' => 'Cannot mark attendance for non-working days (Sundays).']);
        }
        
        Attendance::create([
            'user_id' => $validated['user_id'],
            'date' => $validated['date'],
            'status' => $validated['status'],
            'notes' => $validated['notes'],
        ]);
        
        return redirect()->route('attendance.index')
                        ->with('success', 'Attendance recorded successfully.');
    }

    /**
     * Display the specified resource.
     */
    public function show(Attendance $attendance, Request $request)
    {
        $this->authorize('view', $attendance);
        
        $attendance->load('user.staffProfile.department');
        
        // Get month and year from request or default to attendance record's month
        $month = $request->get('month', $attendance->date->month);
        $year = $request->get('year', $attendance->date->year);
        
        // Validate month and year
        $month = max(1, min(12, (int)$month));
        $year = max(2020, min(2030, (int)$year));
        
        // Create Carbon instance for the first day of the month
        $startDate = Carbon::create($year, $month, 1);
        $endDate = $startDate->copy()->endOfMonth();
        
        // Get attendance records for the month
        $monthlyAttendances = Attendance::where('user_id', $attendance->user_id)
                                ->whereBetween('date', [$startDate, $endDate])
                                ->get()
                                ->keyBy(function($item) {
                                    return $item->date->format('Y-m-d');
                                });
        
        // Calculate calendar data
        $calendarData = [];
        $firstDayOfWeek = $startDate->dayOfWeek; // 0 = Sunday, 1 = Monday, etc.
        $daysInMonth = $startDate->daysInMonth;
        
        // Add empty cells for days before the first day of the month
        for ($i = 0; $i < $firstDayOfWeek; $i++) {
            $calendarData[] = null;
        }
        
        // Add days of the month
        for ($day = 1; $day <= $daysInMonth; $day++) {
            $date = Carbon::create($year, $month, $day);
            $dateString = $date->format('Y-m-d');
            
            $calendarData[] = [
                'day' => $day,
                'date' => $date,
                'is_weekend' => $date->dayOfWeek === 0, // Sunday
                'is_today' => $date->isToday(),
                'attendance' => $monthlyAttendances->get($dateString)
            ];
        }
        
        // Calculate summary statistics
        $workingDays = $monthlyAttendances->filter(function($att) {
            return !$att->date->isSunday();
        });
        
        $summary = [
            'total_working_days' => $workingDays->count(),
            'present_days' => $monthlyAttendances->where('status', 'present')->count(),
            'late_days' => $monthlyAttendances->where('status', 'late')->count(),
            'absent_days' => $monthlyAttendances->where('status', 'absent')->count(),
            'half_days' => $monthlyAttendances->where('status', 'half_day')->count(),
        ];
        
        $summary['attendance_percentage'] = $summary['total_working_days'] > 0 
            ? round(($summary['present_days'] / $summary['total_working_days']) * 100, 2) 
            : 0;
        
        return view('attendance.show', compact('attendance', 'calendarData', 'summary', 'month', 'year'));
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(Attendance $attendance)
    {
        $this->authorize('update', $attendance);
        
        $users = User::role('Staff')->get();
        
        return view('attendance.edit', compact('attendance', 'users'));
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, Attendance $attendance)
    {
        $this->authorize('update', $attendance);
        
        $validated = $request->validate([
            'user_id' => 'required|exists:users,id',
            'date' => 'required|date',
            'status' => 'required|in:present,absent,late,half_day',
            'notes' => 'nullable|string|max:500',
        ]);
        
        // Check if attendance already exists for this user and date (excluding current record)
        $existingAttendance = Attendance::where('user_id', $validated['user_id'])
                                      ->whereDate('date', $validated['date'])
                                      ->where('id', '!=', $attendance->id)
                                      ->first();
        
        if ($existingAttendance) {
            return back()->withErrors(['date' => 'Attendance for this user on this date already exists.']);
        }
        
        // Check if the date is a working day (Monday to Saturday)
        if (!Attendance::isWorkingDay(Carbon::parse($validated['date']))) {
            return back()->withErrors(['date' => 'Cannot mark attendance for non-working days (Sundays).']);
        }
        
        $attendance->update([
            'user_id' => $validated['user_id'],
            'date' => $validated['date'],
            'status' => $validated['status'],
            'notes' => $validated['notes'],
        ]);
        
        return redirect()->route('attendance.show', $attendance)
                        ->with('success', 'Attendance updated successfully.');
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(Attendance $attendance)
    {
        $this->authorize('delete', $attendance);
        
        $attendance->delete();
        
        return redirect()->route('attendance.index')
                        ->with('success', 'Attendance deleted successfully.');
    }
    
    /**
     * Mark attendance for current user (simplified)
     */
    public function markAttendance(Request $request)
    {
        $user = Auth::user();
        $today = Carbon::today();
        
        // Check if it's a working day
        if (!Attendance::isWorkingDay($today)) {
            return back()->withErrors(['message' => 'Cannot mark attendance on non-working days (Sundays).']);
        }
        
        // Check if user already marked attendance today
        $existingAttendance = Attendance::where('user_id', $user->id)
                                      ->whereDate('date', $today)
                                      ->first();
        
        if ($existingAttendance) {
            return back()->withErrors(['message' => 'You have already marked attendance today.']);
        }
        
        $validated = $request->validate([
            'status' => 'required|in:present,late,half_day',
            'notes' => 'nullable|string|max:500',
        ]);
        
        Attendance::create([
            'user_id' => $user->id,
            'date' => $today,
            'status' => $validated['status'],
            'notes' => $validated['notes'],
        ]);
        
        return back()->with('success', 'Attendance marked successfully.');
    }
    
    /**
     * Quick update attendance status (for admin use)
     */
    public function quickUpdate(Request $request)
    {
        $this->authorize('create', Attendance::class);
        
        $validated = $request->validate([
            'user_id' => 'required|exists:users,id',
            'date' => 'required|date',
            'status' => 'required|in:present,absent,late,half_day',
            'notes' => 'nullable|string|max:500',
        ]);
        
        // Check if the date is a working day (Monday to Saturday)
        if (!Attendance::isWorkingDay(Carbon::parse($validated['date']))) {
            return response()->json(['error' => 'Cannot mark attendance for non-working days (Sundays).'], 400);
        }
        
        $attendance = Attendance::where('user_id', $validated['user_id'])
                               ->whereDate('date', $validated['date'])
                               ->first();
        
        if ($attendance) {
            $attendance->update([
                'status' => $validated['status'],
                'notes' => $validated['notes'] ?? $attendance->notes,
            ]);
            $message = 'Attendance updated successfully.';
        } else {
            Attendance::create([
                'user_id' => $validated['user_id'],
                'date' => $validated['date'],
                'status' => $validated['status'],
                'notes' => $validated['notes'] ?? 'Admin created',
            ]);
            $message = 'Attendance created successfully.';
        }
        
        return response()->json(['success' => $message]);
    }
    
    /**
     * Generate attendance report
     */
    public function report(Request $request)
    {
        $this->authorize('viewAny', Attendance::class);
        
        $validated = $request->validate([
            'start_date' => 'required|date',
            'end_date' => 'required|date|after_or_equal:start_date',
            'user_id' => 'nullable|exists:users,id',
        ]);
        
        $query = Attendance::with(['user', 'user.staffProfile'])
                          ->whereBetween('date', [$validated['start_date'], $validated['end_date']]);
        
        if ($validated['user_id']) {
            $query->where('user_id', $validated['user_id']);
        }
        
        $attendances = $query->orderBy('date', 'desc')->get();
        
        // Calculate summary statistics
        $summary = [
            'total_days' => $attendances->count(),
            'present_days' => $attendances->where('status', 'present')->count(),
            'late_days' => $attendances->where('status', 'late')->count(),
            'absent_days' => $attendances->where('status', 'absent')->count(),
            'half_days' => $attendances->where('status', 'half_day')->count(),
        ];
        
        $users = User::role('Staff')->get();
        
        return view('attendance.report', compact('attendances', 'summary', 'users', 'validated'));
    }

    /**
     * Display calendar view for a specific user's attendance
     */

    // API Methods for Mobile App
    
    /**
     * API: Get attendance records
     */
    public function apiIndex(Request $request)
    {
        $user = $request->user();
        
        if ($user->hasRole('Admin')) {
            $query = Attendance::with(['user', 'user.staffProfile']);
            
            // Filter by date range if provided
            if ($request->filled('start_date')) {
                $query->whereDate('date', '>=', $request->start_date);
            }
            if ($request->filled('end_date')) {
                $query->whereDate('date', '<=', $request->end_date);
            }
            
            // Admin can filter by user
            if ($request->filled('user_id')) {
                $query->where('user_id', $request->user_id);
            }
            
            $attendances = $query->latest('date')->paginate(15);
            $transformedData = $this->transformAttendanceCollection($attendances->items());
            
            return response()->json([
                'data' => $transformedData,
                'current_page' => $attendances->currentPage(),
                'last_page' => $attendances->lastPage(),
                'per_page' => $attendances->perPage(),
                'total' => $attendances->total(),
            ]);
        } else {
            // Staff can only see their own attendance
            $query = Attendance::where('user_id', $user->id);
            
            if ($request->filled('month')) {
                $query->whereMonth('date', $request->month);
            }
            if ($request->filled('year')) {
                $query->whereYear('date', $request->year);
            }
            
            $attendances = $query->latest('date')->get();
            $transformedData = $this->transformAttendanceCollection($attendances);
            
            // For staff users, return direct array format
            return response()->json($transformedData);
        }
    }
    
    /**
     * API: Create attendance record
     */
    public function apiStore(Request $request)
    {
        $user = $request->user();
        
        $validated = $request->validate([
            'user_id' => $user->hasRole('Admin') ? 'required|exists:users,id' : 'nullable',
            'date' => 'required|date',
            'status' => 'required|in:present,absent,late,half_day',
            'notes' => 'nullable|string|max:500',
            'check_in' => 'nullable|date_format:H:i',
            'check_out' => 'nullable|date_format:H:i',
        ]);
        
        // If staff, force user_id to be their own
        if (!$user->hasRole('Admin')) {
            $validated['user_id'] = $user->id;
        }
        
        // Check if attendance already exists for this date
        $existingAttendance = Attendance::where('user_id', $validated['user_id'])
                                      ->whereDate('date', $validated['date'])
                                      ->first();
        
        if ($existingAttendance) {
            return response()->json(['error' => 'Attendance already marked for this date.'], 422);
        }
        
        // Check if the date is a working day
        if (!Attendance::isWorkingDay(Carbon::parse($validated['date']))) {
            return response()->json(['error' => 'Cannot mark attendance for non-working days (Sundays).'], 422);
        }
        
        $attendance = Attendance::create($validated);
        
        return response()->json([
            'message' => 'Attendance marked successfully.',
            'attendance' => $attendance->load('user')
        ], 201);
    }
    
    /**
     * API: Get specific attendance record
     */
    public function apiShow(Request $request, $id)
    {
        $user = $request->user();
        $attendance = Attendance::with(['user', 'user.staffProfile'])->findOrFail($id);
        
        // Staff can only view their own attendance
        if (!$user->hasRole('Admin') && $attendance->user_id !== $user->id) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }
        
        return response()->json($attendance);
    }
    
    /**
     * API: Update attendance record
     */
    public function apiUpdate(Request $request, $id)
    {
        $user = $request->user();
        $attendance = Attendance::findOrFail($id);
        
        // Staff can only update their own attendance
        if (!$user->hasRole('Admin') && $attendance->user_id !== $user->id) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }
        
        $validated = $request->validate([
            'status' => 'sometimes|in:present,absent,late,half_day',
            'notes' => 'nullable|string|max:500',
            'check_in' => 'nullable|date_format:H:i',
            'check_out' => 'nullable|date_format:H:i',
        ]);
        
        $attendance->update($validated);
        
        return response()->json([
            'message' => 'Attendance updated successfully.',
            'attendance' => $attendance->fresh()->load('user')
        ]);
    }
    
    /**
     * API: Delete attendance record
     */
    public function apiDestroy(Request $request, $id)
    {
        $user = $request->user();
        
        // Only admin can delete attendance
        if (!$user->hasRole('Admin')) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }
        
        $attendance = Attendance::findOrFail($id);
        $attendance->delete();
        
        return response()->json(['message' => 'Attendance deleted successfully.']);
    }
    
    /**
     * API: Get attendance statistics
     */
    public function apiStats(Request $request)
    {
        $user = $request->user();
        $month = $request->get('month', Carbon::now()->month);
        $year = $request->get('year', Carbon::now()->year);
        
        if ($user->hasRole('Admin')) {
            $userId = $request->get('user_id');
            $query = Attendance::query();
            
            if ($userId) {
                $query->where('user_id', $userId);
            }
        } else {
            $query = Attendance::where('user_id', $user->id);
        }
        
        $attendances = $query->whereYear('date', $year)
                           ->whereMonth('date', $month)
                           ->get();
        
        $stats = [
            'total_days' => $attendances->count(),
            'present_days' => $attendances->where('status', 'present')->count(),
            'late_days' => $attendances->where('status', 'late')->count(),
            'absent_days' => $attendances->where('status', 'absent')->count(),
            'half_days' => $attendances->where('status', 'half_day')->count(),
            'attendance_percentage' => $attendances->count() > 0 ? 
                round(($attendances->whereIn('status', ['present', 'late', 'half_day'])->count() / $attendances->count()) * 100, 2) : 0
        ];
        
        return response()->json($stats);
    }
    
    /**
     * API: Get today's attendance
     */
    public function apiToday(Request $request)
    {
        $user = $request->user();
        $today = Carbon::today();
        
        $attendance = Attendance::where('user_id', $user->id)
                               ->whereDate('date', $today)
                               ->first();
        
        // Transform data to mobile-friendly format
        $transformedAttendance = null;
        if ($attendance) {
            $transformedAttendance = $this->transformAttendanceData($attendance);
        }
        
        return response()->json([
            'attendance' => $transformedAttendance,
            'canMark' => !$attendance && Attendance::isWorkingDay($today),
            'isWorkingDay' => Attendance::isWorkingDay($today),
            'todayDate' => $today->format('Y-m-d')
        ]);
    }
    
    /**
     * API: Mark attendance for today
     */
    public function apiMarkAttendance(Request $request)
    {
        $user = $request->user();
        $today = Carbon::today();
        
        // Check if already marked
        $existingAttendance = Attendance::where('user_id', $user->id)
                                      ->whereDate('date', $today)
                                      ->first();
        
        if ($existingAttendance) {
            return response()->json(['error' => 'Attendance already marked for today.'], 422);
        }
        
        // Check if today is a working day
        if (!Attendance::isWorkingDay($today)) {
            return response()->json(['error' => 'Cannot mark attendance for non-working days.'], 422);
        }
        
        $validated = $request->validate([
            'status' => 'required|in:present,late',
            'notes' => 'nullable|string|max:500',
            'check_in' => 'nullable|date_format:H:i',
            'selfie' => 'required|image|mimes:jpeg,png,jpg|max:2048',
            'latitude' => 'required|numeric|between:-90,90',
            'longitude' => 'required|numeric|between:-180,180',
            'location_address' => 'nullable|string|max:255',
            'device_info' => 'nullable|array',
        ]);
        
        // Validate location using geofencing
        $locationValidation = GeofencingService::validateLocation(
            $validated['latitude'], 
            $validated['longitude'], 
            $user
        );
        
        // Log the validation attempt
        GeofencingService::logValidationAttempt(
            $locationValidation, 
            $user, 
            ['action' => 'mark_attendance', 'date' => $today->toDateString()]
        );
        
        // Check if we should enforce validation
        if (GeofencingService::shouldEnforceValidation($user) && !$locationValidation['valid']) {
            return response()->json([
                'error' => GeofencingService::getValidationMessage($locationValidation),
                'validation_details' => $locationValidation
            ], 422);
        }

        // Handle selfie upload
        $selfiePath = null;
        if ($request->hasFile('selfie')) {
            $selfie = $request->file('selfie');
            $filename = 'attendance_' . $user->id . '_' . $today->format('Y_m_d') . '_' . time() . '.' . $selfie->getClientOriginalExtension();
            
            // Store in main domain directory for direct access
            $publicPath = 'attendance/selfies/' . $filename;
            $fullPath = base_path('../hr_yavis_restaurant/attendance/selfies/' . $filename);
            
            // Ensure directory exists
            $directory = dirname($fullPath);
            if (!file_exists($directory)) {
                mkdir($directory, 0755, true);
            }
            
            // Move uploaded file to main domain directory
            $selfie->move($directory, $filename);
            $selfiePath = $publicPath;
        }

        $attendance = Attendance::create([
            'user_id' => $user->id,
            'date' => $today,
            'status' => $validated['status'],
            'notes' => $validated['notes'] ?? null,
            'check_in' => $validated['check_in'] ?? Carbon::now()->format('H:i'),
            'selfie_path' => $selfiePath,
            'latitude' => $validated['latitude'],
            'longitude' => $validated['longitude'],
            'location_address' => $validated['location_address'],
            'device_info' => $validated['device_info'],
            'marked_at' => Carbon::now(),
            'attendance_type' => 'manual',
        ]);
        
        return response()->json([
            'message' => 'Attendance marked successfully.',
            'attendance' => $attendance
        ], 201);
    }

    /**
     * API: Check-out attendance
     */
    public function apiCheckout(Request $request)
    {
        // DEBUG: Log checkout request
        Log::info('=== CHECKOUT API DEBUG START ===');
        Log::info('Request method: ' . $request->method());
        
        $user = $request->user();
        Log::info('User: ' . ($user ? $user->id . ' - ' . $user->name : 'None'));
        
        $requestData = $request->all();
        if (isset($requestData['selfie'])) {
             $requestData['selfie'] = 'base64_length_' . strlen($requestData['selfie']);
        }
        Log::info('Request Data:', $requestData);

        $today = Carbon::today();

        // Check if attendance exists for today
        $attendance = Attendance::where('user_id', $user->id)
                              ->whereDate('date', $today)
                              ->first();

        if (!$attendance) {
            Log::warning('Checkout failed: No check-in record found for today for user ' . ($user ? $user->id : 'unknown'));
            return response()->json(['error' => 'No check-in record found for today.'], 422);
        }

        if ($attendance->check_out_time) {
            Log::warning('Checkout failed: Already checked out for user ' . $user->id);
            return response()->json(['error' => 'You have already checked out today.'], 422);
        }

        try {
            $validated = $request->validate([
                'selfie' => 'required|string', // Accept base64 string
                'latitude' => 'nullable|numeric|between:-90,90',
                'longitude' => 'nullable|numeric|between:-180,180',
                'location_address' => 'nullable|string|max:255',
            ]);
            Log::info('Checkout validation passed');
        } catch (\Illuminate\Validation\ValidationException $e) {
            Log::error('Checkout validation failed:', $e->errors());
            throw $e;
        }

        // Handle selfie upload (Base64)
        $selfiePath = null;
        if ($request->has('selfie')) {
            try {
                $base64Image = $validated['selfie'];
                if (strpos($base64Image, 'data:image') === 0) {
                    $base64Image = substr($base64Image, strpos($base64Image, ',') + 1);
                }
                $imageData = base64_decode($base64Image);
                
                if ($imageData === false) {
                     Log::error('Checkout failed: Invalid image data');
                     return response()->json(['error' => 'Invalid image data.'], 422);
                }

                $filename = 'checkout_' . $user->id . '_' . $today->format('Y_m_d') . '_' . time() . '.jpg';
                
                // Store in main domain directory for direct access
                $publicPath = 'attendance/selfies/' . $filename;
                $fullPath = base_path('../hr_yavis_restaurant/attendance/selfies/' . $filename);
                
                // Ensure directory exists
                $directory = dirname($fullPath);
                if (!file_exists($directory)) {
                    mkdir($directory, 0755, true);
                }
                
                file_put_contents($fullPath, $imageData);
                $selfiePath = $publicPath;
                Log::info('Checkout selfie saved at: ' . $fullPath);
            } catch (\Exception $e) {
                Log::error('Error saving checkout selfie: ' . $e->getMessage());
            }
        }

        $attendance->update([
            'check_out_time' => Carbon::now(),
            'check_out_selfie_path' => $selfiePath,
            'check_out_latitude' => $validated['latitude'] ?? null,
            'check_out_longitude' => $validated['longitude'] ?? null,
            'check_out_location_address' => $validated['location_address'] ?? null,
        ]);

        Log::info('Checkout successful for user ' . $user->id);
        Log::info('=== CHECKOUT API DEBUG END ===');

        return response()->json([
            'message' => 'Check-out successful.',
            'attendance' => $attendance
        ]);
    }

    /**
     * API: Submit selfie for check-in attendance
     */
    public function apiSubmitSelfie(Request $request)
    {
        // DEBUG: Log all incoming request data
        Log::info('=== SELFIE API DEBUG START ===');
        Log::info('Request method: ' . $request->method());
        Log::info('Request headers: ', $request->headers->all());
        $requestData = $request->all();
        // Don't log full base64 data, just its length
        if (isset($requestData['selfie'])) {
            $requestData['selfie'] = 'base64_data_length_' . strlen($requestData['selfie']);
        }
        Log::info('Request all data: ', $requestData);
        Log::info('Has selfie data: ' . ($request->has('selfie') ? 'YES' : 'NO'));
        
        $user = $request->user();
        Log::info('User found: ' . ($user ? 'YES (ID: ' . $user->id . ')' : 'NO'));
        
        // Validate that user has check-in attendance type
        if ($user && $user->attendance_type !== 'check-in') {
            Log::info('User attendance type mismatch: ' . $user->attendance_type);
            return response()->json([
                'success' => false,
                'message' => 'Selfie submission not required for your attendance type.',
                'debug_info' => [
                    'user_attendance_type' => $user->attendance_type,
                    'required_type' => 'check-in'
                ]
            ], 400);
        }
        
        if (!$user) {
            Log::error('User not authenticated or token invalid');
            return response()->json([
                'success' => false,
                'message' => 'User not authenticated.',
                'debug_info' => [
                    'authentication_status' => 'failed'
                ]
            ], 401);
        }

        try {
            $validated = $request->validate([
                'selfie' => 'required|string', // Accept base64 string
                'timestamp' => 'required|date',
                'latitude' => 'nullable|numeric|between:-90,90',
                'longitude' => 'nullable|numeric|between:-180,180',
                'location_address' => 'nullable|string|max:500',
                'location_timestamp' => 'nullable|date',
            ]);
            Log::info('Validation passed. Validated data: ', array_merge($validated, ['selfie' => 'base64_string_length_' . strlen($validated['selfie'])]));
        } catch (\Illuminate\Validation\ValidationException $e) {
            Log::error('Validation failed: ', $e->errors());
            return response()->json([
                'success' => false,
                'message' => 'Validation failed.',
                'debug_info' => [
                    'validation_errors' => $e->errors(),
                    'received_data' => $request->all()
                ]
            ], 422);
        }

        try {
            // Decode base64 image
            $base64Image = $validated['selfie'];
            
            // Remove data:image/jpeg;base64, prefix if present
            if (strpos($base64Image, 'data:image') === 0) {
                $base64Image = substr($base64Image, strpos($base64Image, ',') + 1);
            }
            
            // Decode base64
            $imageData = base64_decode($base64Image);
            
            if ($imageData === false) {
                throw new \Exception('Invalid base64 image data');
            }
            
            // Generate unique filename
            $filename = 'selfie_' . $user->id . '_' . time() . '.jpg';
            $selfiePath = 'attendance/selfies/' . $filename;
            // Save to main domain folder instead of Laravel app public folder
            $fullImagePath = base_path('../hr_yavis_restaurant/attendance/selfies/' . $filename);
            
            // Ensure directory exists
            $directory = dirname($fullImagePath);
            if (!file_exists($directory)) {
                mkdir($directory, 0755, true);
            }
            
            // Save image file
            file_put_contents($fullImagePath, $imageData);
            
            // Get image metadata
            $imageInfo = getimagesize($fullImagePath);
            $fileSize = strlen($imageData);
            
            // Extract EXIF GPS data as backup location source
            $exifGpsData = ExifService::extractGpsCoordinates($fullImagePath);
            $exifMetadata = ExifService::extractAllMetadata($fullImagePath);
            
            // Determine final location data (prioritize app GPS over EXIF GPS)
            $finalLatitude = $validated['latitude'] ?? ($exifGpsData['latitude'] ?? null);
            $finalLongitude = $validated['longitude'] ?? ($exifGpsData['longitude'] ?? null);
            
            $metadata = [
                'file_path' => $selfiePath,
                'file_size' => $fileSize,
                'dimensions' => $imageInfo ? $imageInfo[0] . 'x' . $imageInfo[1] : null,
                'mime_type' => $imageInfo ? image_type_to_mime_type($imageInfo[2]) : 'image/jpeg',
                'submitted_at' => $validated['timestamp'],
                'user_agent' => $request->header('User-Agent'),
                'ip_address' => $request->ip(),
                'location_data' => [
                    'app_gps' => [
                        'latitude' => $validated['latitude'] ?? null,
                        'longitude' => $validated['longitude'] ?? null,
                        'address' => $validated['location_address'] ?? null,
                        'captured_at' => $validated['location_timestamp'] ?? null,
                    ],
                    'exif_gps' => $exifGpsData,
                    'final_coordinates' => [
                        'latitude' => $finalLatitude,
                        'longitude' => $finalLongitude,
                        'source' => $validated['latitude'] ? 'app' : ($exifGpsData ? 'exif' : 'none')
                    ]
                ],
                'exif_metadata' => $exifMetadata
            ];

            // Validate location if coordinates are available
            $locationValidation = null;
            if ($finalLatitude && $finalLongitude) {
                $locationValidation = GeofencingService::validateLocation(
                    $finalLatitude, 
                    $finalLongitude, 
                    $user
                );
                
                // Log the validation attempt
                $today = now()->format('Y-m-d');
                GeofencingService::logValidationAttempt(
                    $locationValidation, 
                    $user, 
                    ['action' => 'selfie_submission', 'date' => $today]
                );
                
                // Add validation result to metadata
                $metadata['location_validation'] = $locationValidation;
                
                // Check if we should enforce validation
                if (GeofencingService::shouldEnforceValidation($user) && !$locationValidation['valid']) {
                    return response()->json([
                        'success' => false,
                        'message' => GeofencingService::getValidationMessage($locationValidation),
                        'validation_details' => $locationValidation
                    ], 422);
                }
            }

            // Create or update today's attendance record
            $today = Carbon::today();
            $attendance = Attendance::updateOrCreate(
                [
                    'user_id' => $user->id,
                    'date' => $today,
                ],
                [
                    'status' => 'present',
                    'check_in' => Carbon::now()->format('H:i:s'),
                    'attendance_type' => 'check-in',
                    'selfie_path' => $selfiePath,
                    'selfie_metadata' => $metadata,
                    'latitude' => $finalLatitude,
                    'longitude' => $finalLongitude,
                    'location_address' => $validated['location_address'] ?? null,
                    'notes' => 'Selfie submitted for attendance verification',
                ]
            );

            Log::info('Selfie submission successful. Attendance created: ', $attendance->toArray());
            
            return response()->json([
                'success' => true,
                'message' => 'Selfie submitted successfully.',
                'attendance' => $attendance,
                'debug_info' => [
                    'received_fields' => array_keys($request->all()),
                    'base64_processed' => $request->has('selfie'),
                    'file_stored_at' => $selfiePath,
                    'user_id' => $user->id,
                    'final_coordinates' => [
                        'latitude' => $finalLatitude,
                        'longitude' => $finalLongitude
                    ],
                    'metadata' => $metadata
                ]
            ], 201);

        } catch (\Exception $e) {
            Log::error('Selfie submission failed with exception: ', [
                'error_message' => $e->getMessage(),
                'error_trace' => $e->getTraceAsString(),
                'request_data' => array_merge($request->all(), ['selfie' => $request->has('selfie') ? 'base64_data_present' : 'no_selfie_data']),
                'has_selfie_data' => $request->has('selfie')
            ]);
            
            return response()->json([
                'success' => false,
                'message' => 'Failed to submit selfie. Please try again.',
                'debug_info' => [
                    'error_message' => $e->getMessage(),
                    'received_fields' => array_keys($request->all()),
                    'has_selfie_data' => $request->has('selfie')
                ]
            ], 500);
        }
    }

    public function debugSelfieRequest(Request $request)
    {
        Log::info('DEBUG SELFIE REQUEST - Full request dump', [
            'method' => $request->method(),
            'url' => $request->fullUrl(),
            'headers' => $request->headers->all(),
            'all_data' => $request->all(),
            'files' => $request->allFiles(),
            'has_selfie_file' => $request->hasFile('selfie'),
            'content_type' => $request->header('Content-Type'),
            'content_length' => $request->header('Content-Length'),
            'raw_content' => $request->getContent(),
        ]);

        return response()->json([
            'success' => true,
            'message' => 'Debug request received',
            'debug_data' => [
                'method' => $request->method(),
                'url' => $request->fullUrl(),
                'headers' => $request->headers->all(),
                'all_data' => $request->all(),
                'files' => $request->allFiles(),
                'has_selfie_file' => $request->hasFile('selfie'),
                'content_type' => $request->header('Content-Type'),
                'content_length' => $request->header('Content-Length'),
                'file_details' => $request->hasFile('selfie') ? [
                    'original_name' => $request->file('selfie')->getClientOriginalName(),
                    'mime_type' => $request->file('selfie')->getMimeType(),
                    'size' => $request->file('selfie')->getSize(),
                    'extension' => $request->file('selfie')->getClientOriginalExtension(),
                ] : null,
            ]
        ]);
    }

    /**
     * Handle check-in for staff members.
     */
    public function checkin(Request $request)
    {
        $user = Auth::user();
        $today = Carbon::today();
        
        // Check if user already checked in today
        $existingAttendance = Attendance::where('user_id', $user->id)
            ->whereDate('date', $today)
            ->first();
            
        if ($existingAttendance && $existingAttendance->check_in_time) {
            return redirect()->back()->with('error', 'You have already checked in today.');
        }
        
        // Create or update attendance record
        Attendance::updateOrCreate(
            [
                'user_id' => $user->id,
                'date' => $today,
            ],
            [
                'check_in_time' => Carbon::now(),
                'status' => 'present',
            ]
        );
        
        return redirect()->back()->with('success', 'Successfully checked in!');
    }

    /**
     * Handle check-out for staff members.
     */
    public function checkout(Request $request)
    {
        $user = Auth::user();
        $today = Carbon::today();
        
        // Find today's attendance record
        $attendance = Attendance::where('user_id', $user->id)
            ->whereDate('date', $today)
            ->first();
            
        if (!$attendance || !$attendance->check_in_time) {
            return redirect()->back()->with('error', 'You must check in first before checking out.');
        }
        
        if ($attendance->check_out_time) {
            return redirect()->back()->with('error', 'You have already checked out today.');
        }
        
        // Update attendance record with check-out time
        $attendance->update([
            'check_out_time' => Carbon::now(),
        ]);
        
        return redirect()->back()->with('success', 'Successfully checked out!');
    }
}
