<?php

namespace App\Http\Controllers\Training;

use App\Http\Controllers\Controller;
use App\Models\TrainingSession;
use App\Models\TrainingAttendance;
use App\Models\TrainingRegistration;
use Illuminate\Http\Request;
use Illuminate\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\JsonResponse;

/**
 * AttendanceController
 *
 * Handles training session attendance management.
 *
 * @package App\Http\Controllers\Training
 */
class AttendanceController extends Controller
{
    /**
     * Display attendance for a session.
     *
     * @param \App\Models\TrainingSession $session
     * @return \Illuminate\View\View
     */
    public function index(TrainingSession $session): View
    {
        abort_unless(auth()->user()->can('view training attendance'), 403);

        $session->load(['trainingPackage']);

        // Get registered participants
        $participants = TrainingRegistration::with(['user'])
            ->where('training_package_id', $session->training_package_id)
            ->whereIn('status', ['approved', 'completed'])
            ->get();

        // Get attendance records
        $attendance = TrainingAttendance::where('training_session_id', $session->id)
            ->get()
            ->keyBy('user_id');

        // Merge attendance status with participants
        $participants->each(function ($participant) use ($attendance) {
            $record = $attendance->get($participant->user_id);
            $participant->attendance = $record;
        });

        $statistics = $this->getSessionStatistics($session, $participants);

        return view('training.attendance.index', compact('session', 'participants', 'attendance', 'statistics'));
    }

    /**
     * Store attendance records.
     *
     * @param \Illuminate\Http\Request $request
     * @param \App\Models\TrainingSession $session
     * @return \Illuminate\Http\RedirectResponse
     */
    public function store(Request $request, TrainingSession $session): RedirectResponse
    {
        abort_unless(auth()->user()->can('manage training attendance'), 403);

        $validated = $request->validate([
            'attendance' => 'required|array',
            'attendance.*.user_id' => 'required|exists:users,id',
            'attendance.*.status' => 'required|in:present,absent,late',
            'attendance.*.notes' => 'nullable|string|max:500',
        ]);

        try {
            foreach ($validated['attendance'] as $record) {
                TrainingAttendance::updateOrCreate(
                    [
                        'training_session_id' => $session->id,
                        'user_id' => $record['user_id'],
                    ],
                    [
                        'attendance_status' => $record['status'],
                        'notes' => $record['notes'] ?? null,
                        'check_in_time' => $record['status'] !== 'absent' ? now() : null,
                        'checked_in_by' => auth()->id(),
                    ]
                );
            }

            return back()->with('success', 'Attendance recorded successfully!');

        } catch (\Exception $e) {
            return back()->with('error', 'Failed to record attendance: ' . $e->getMessage());
        }
    }

    /**
     * Bulk store attendance records.
     *
     * @param \Illuminate\Http\Request $request
     * @param \App\Models\TrainingSession $session
     * @return \Illuminate\Http\RedirectResponse
     */
    public function bulkStore(Request $request, TrainingSession $session): RedirectResponse
    {
        abort_unless(auth()->user()->can('manage training attendance'), 403);

        $validated = $request->validate([
            'status' => 'required|in:present,absent,late',
            'user_ids' => 'required|array',
            'user_ids.*' => 'exists:users,id',
        ]);

        try {
            foreach ($validated['user_ids'] as $userId) {
                TrainingAttendance::updateOrCreate(
                    [
                        'training_session_id' => $session->id,
                        'user_id' => $userId,
                    ],
                    [
                        'attendance_status' => $validated['status'],
                        'checked_in_by' => auth()->id(),
                    ]
                );
            }

            return back()->with('success', 'Bulk attendance recorded successfully!');

        } catch (\Exception $e) {
            return back()->with('error', 'Failed to record attendance: ' . $e->getMessage());
        }
    }

    /**
     * Check in a participant (AJAX).
     *
     * @param \App\Models\TrainingAttendance $attendance
     * @return \Illuminate\Http\JsonResponse
     */
    public function apiCheckIn(TrainingAttendance $attendance): JsonResponse
    {
        abort_unless(auth()->user()->can('manage training attendance'), 403);

        try {
            $attendance->update([
                'attendance_status' => 'present',
                'check_in_time' => now(),
                'recorded_by' => auth()->id(),
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Check-in recorded successfully.',
                'check_in_time' => $attendance->check_in_time->format('H:i:s'),
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to check in: ' . $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Check out a participant (AJAX).
     *
     * @param \App\Models\TrainingAttendance $attendance
     * @return \Illuminate\Http\JsonResponse
     */
    public function apiCheckOut(TrainingAttendance $attendance): JsonResponse
    {
        abort_unless(auth()->user()->can('manage training attendance'), 403);

        try {
            $attendance->update([
                'check_out_time' => now(),
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Check-out recorded successfully.',
                'check_out_time' => $attendance->check_out_time->format('H:i:s'),
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to check out: ' . $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Export attendance records.
     *
     * @param \App\Models\TrainingSession $session
     * @return \Symfony\Component\HttpFoundation\BinaryFileResponse
     */
    public function export(TrainingSession $session)
    {
        abort_unless(auth()->user()->can('export training attendance'), 403);

        $attendance = TrainingAttendance::with(['user'])
            ->where('training_session_id', $session->id)
            ->get();

        // Generate CSV export
        $filename = 'attendance_' . $session->id . '_' . now()->format('Y-m-d') . '.csv';

        $headers = [
            'Content-Type' => 'text/csv',
            'Content-Disposition' => 'attachment; filename="' . $filename . '"',
        ];

        $callback = function () use ($attendance, $session) {
            $file = fopen('php://output', 'w');

            // Header row
            fputcsv($file, [
                'Session',
                'Date',
                'Participant Name',
                'Email',
                'Status',
                'Check In Time',
                'Check Out Time',
                'Notes',
            ]);

            foreach ($attendance as $record) {
                fputcsv($file, [
                    $session->session_name,
                    $session->session_date->format('Y-m-d'),
                    $record->user->name,
                    $record->user->email,
                    ucfirst($record->attendance_status),
                    $record->check_in_time?->format('H:i:s'),
                    $record->check_out_time?->format('H:i:s'),
                    $record->notes,
                ]);
            }

            fclose($file);
        };

        return response()->stream($callback, 200, $headers);
    }

    /**
     * Get session attendance statistics.
     *
     * @param \App\Models\TrainingSession $session
     * @param \Illuminate\Support\Collection $participants
     * @return array
     */
    protected function getSessionStatistics(TrainingSession $session, $participants): array
    {
        $attendance = TrainingAttendance::where('training_session_id', $session->id)->get();

        return [
            'total_participants' => $participants->count(),
            'present' => $attendance->where('attendance_status', 'present')->count(),
            'absent' => $attendance->where('attendance_status', 'absent')->count(),
            'late' => $attendance->where('attendance_status', 'late')->count(),
            'not_recorded' => $participants->count() - $attendance->count(),
            'attendance_rate' => $participants->count() > 0
                ? round(($attendance->whereIn('attendance_status', ['present', 'late'])->count() / $participants->count()) * 100, 1)
                : 0,
        ];
    }
}
