<?php
declare(strict_types=1);

namespace App\Modules\SportsActivity\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Core\Pagination;
use App\Modules\SportsActivity\Models\Discipline;

class AttendanceController extends Controller
{
    /**
     * List today's training bookings for attendance recording.
     */
    public function index(Request $request): Response
    {
        $db = App::getInstance()->db();
        $today = date('Y-m-d');

        $disciplineId = trim((string) $request->get('discipline_id', ''));
        $coachId = trim((string) $request->get('coach_id', ''));

        $where = "b.booking_type = 'training' AND b.booking_date = ? AND b.status NOT IN ('cancelled', 'no_show')";
        $params = [$today];

        if ($disciplineId !== '') {
            $where .= " AND pr.discipline_id = ?";
            $params[] = (int) $disciplineId;
        }

        if ($coachId !== '') {
            $where .= " AND b.coach_id = ?";
            $params[] = (int) $coachId;
        }

        $bookings = $db->select(
            "SELECT b.*, fu.name_ar as unit_name, f.name_ar as facility_name,
                    g.name_ar as group_name, c.full_name_ar as coach_name
             FROM sa_bookings b
             JOIN sa_facility_units fu ON fu.id = b.facility_unit_id
             JOIN sa_facilities f ON f.id = fu.facility_id
             LEFT JOIN sa_groups g ON g.id = b.group_id
             LEFT JOIN sa_programs pr ON pr.id = g.program_id
             LEFT JOIN sa_coaches c ON c.id = b.coach_id
             WHERE {$where}
             ORDER BY b.start_time ASC",
            $params
        );

        $disciplines = Discipline::getActive();
        $coaches = $db->select("SELECT id, full_name_ar as name_ar FROM sa_coaches WHERE is_archived = 0 AND is_active = 1 ORDER BY full_name_ar", []);

        return $this->view('SportsActivity.Views.attendance.index', [
            'bookings'     => $bookings,
            'today'        => $today,
            'disciplines'  => $disciplines,
            'coaches'      => $coaches,
            'filters'      => ['discipline_id' => $disciplineId, 'coach_id' => $coachId],
        ]);
    }

    /**
     * Show attendance form for a specific booking.
     */
    public function record(Request $request, string $bookingId): Response
    {
        $db = App::getInstance()->db();

        $booking = $db->selectOne(
            "SELECT b.*, fu.name_ar as unit_name, f.name_ar as facility_name,
                    g.name_ar as group_name, g.id as group_id, c.full_name_ar as coach_name
             FROM sa_bookings b
             JOIN sa_facility_units fu ON fu.id = b.facility_unit_id
             JOIN sa_facilities f ON f.id = fu.facility_id
             LEFT JOIN sa_groups g ON g.id = b.group_id
             LEFT JOIN sa_coaches c ON c.id = b.coach_id
             WHERE b.id = ?",
            [(int) $bookingId]
        );

        if (!$booking) {
            return $this->redirect('/sa/attendance')->withError('الحجز غير موجود');
        }

        $players = [];
        if ($booking['group_id']) {
            $players = $db->select(
                "SELECT gp.player_id, gp.status as enrollment_status,
                        gp.medical_grace_deadline,
                        p.full_name_ar as player_name, p.registration_serial as player_code,
                        p.medical_status, p.medical_expiry_date, p.player_type,
                        (SELECT COUNT(*) FROM sa_subscriptions s
                         WHERE s.player_id = gp.player_id AND s.group_id = gp.group_id
                         AND s.payment_status IN ('unpaid','overdue','partial')) as unpaid_count,
                        (SELECT COUNT(*) FROM sa_player_documents doc
                         WHERE doc.player_id = gp.player_id AND doc.document_type = 'medical_cert'
                         AND doc.approval_status = 'approved') as approved_medical_count
                 FROM sa_group_players gp
                 JOIN sa_players p ON p.id = gp.player_id
                 WHERE gp.group_id = ? AND gp.status IN ('active', 'pending_payment')
                 ORDER BY p.full_name_ar ASC",
                [(int) $booking['group_id']]
            );
        }

        // Get existing attendance records for this booking
        $existingAttendance = $db->select(
            "SELECT * FROM sa_attendance WHERE booking_id = ?",
            [(int) $bookingId]
        );
        $attendanceMap = [];
        foreach ($existingAttendance as $att) {
            $attendanceMap[(int) $att['player_id']] = $att['status'];
        }

        return $this->view('SportsActivity.Views.attendance.record', [
            'booking'       => $booking,
            'players'       => $players,
            'attendanceMap' => $attendanceMap,
        ]);
    }

    /**
     * Store attendance records for a booking.
     */
    public function store(Request $request, string $bookingId): Response
    {
        $db = App::getInstance()->db();

        $booking = $db->selectOne(
            "SELECT * FROM sa_bookings WHERE id = ?",
            [(int) $bookingId]
        );

        if (!$booking) {
            return $this->redirect('/sa/attendance')->withError('الحجز غير موجود');
        }

        $playerIds = $request->post('player_ids', []);
        $statuses = $request->post('statuses', []);

        if (!is_array($playerIds) || !is_array($statuses)) {
            return $this->redirect('/sa/attendance/record/' . $bookingId)->withError('بيانات غير صالحة');
        }

        $session = App::getInstance()->session();
        $employeeId = (int) ($session->get('employee_id') ?? 0);
        $now = date('Y-m-d H:i:s');

        // Delete existing records for this booking then re-insert
        $db->delete('sa_attendance', 'booking_id = ?', [(int) $bookingId]);

        $recorded = 0;
        foreach ($playerIds as $index => $playerId) {
            $status = $statuses[$index] ?? 'absent';
            if (!in_array($status, ['present', 'absent', 'late', 'excused'], true)) {
                $status = 'absent';
            }

            $db->insert('sa_attendance', [
                'booking_id'      => (int) $bookingId,
                'player_id'       => (int) $playerId,
                'attendance_date' => $booking['booking_date'],
                'status'          => $status,
                'recorded_by'     => $employeeId,
                'created_at'      => $now,
                'updated_at'      => $now,
            ]);
            $recorded++;
        }

        return $this->redirect('/sa/attendance')->withSuccess(
            sprintf('تم تسجيل حضور %d لاعب بنجاح', $recorded)
        );
    }

    /**
     * Attendance report with filters.
     */
    public function report(Request $request): Response
    {
        $db = App::getInstance()->db();

        $filters = [
            'group_id'   => trim((string) $request->get('group_id', '')),
            'player_id'  => trim((string) $request->get('player_id', '')),
            'date_from'  => trim((string) $request->get('date_from', '')),
            'date_to'    => trim((string) $request->get('date_to', '')),
        ];

        $where = [];
        $params = [];
        $records = [];
        $summary = null;

        $hasFilter = $filters['group_id'] !== '' || $filters['player_id'] !== ''
            || $filters['date_from'] !== '' || $filters['date_to'] !== '';

        if ($hasFilter) {
            if ($filters['group_id'] !== '') {
                $where[] = "b.group_id = ?";
                $params[] = (int) $filters['group_id'];
            }
            if ($filters['player_id'] !== '') {
                $where[] = "a.player_id = ?";
                $params[] = (int) $filters['player_id'];
            }
            if ($filters['date_from'] !== '') {
                $where[] = "b.booking_date >= ?";
                $params[] = $filters['date_from'];
            }
            if ($filters['date_to'] !== '') {
                $where[] = "b.booking_date <= ?";
                $params[] = $filters['date_to'];
            }

            $whereClause = !empty($where) ? 'WHERE ' . implode(' AND ', $where) : '';

            $records = $db->select(
                "SELECT a.*, p.full_name_ar as player_name, g.name_ar as group_name,
                        b.booking_date, b.start_time, b.end_time
                 FROM sa_attendance a
                 JOIN sa_bookings b ON b.id = a.booking_id
                 JOIN sa_players p ON p.id = a.player_id
                 LEFT JOIN sa_groups g ON g.id = b.group_id
                 {$whereClause}
                 ORDER BY b.booking_date DESC, b.start_time DESC
                 LIMIT 200",
                $params
            );

            // Summary counts
            $summaryRow = $db->selectOne(
                "SELECT
                    COUNT(*) as total,
                    SUM(CASE WHEN a.status = 'present' THEN 1 ELSE 0 END) as present_count,
                    SUM(CASE WHEN a.status = 'absent' THEN 1 ELSE 0 END) as absent_count,
                    SUM(CASE WHEN a.status = 'late' THEN 1 ELSE 0 END) as late_count,
                    SUM(CASE WHEN a.status = 'excused' THEN 1 ELSE 0 END) as excused_count
                 FROM sa_attendance a
                 JOIN sa_bookings b ON b.id = a.booking_id
                 {$whereClause}",
                $params
            );
            $summary = $summaryRow;
        }

        $groups = $db->select(
            "SELECT id, name_ar FROM sa_groups WHERE status = 'active' AND is_archived = 0 ORDER BY name_ar",
            []
        );

        return $this->view('SportsActivity.Views.attendance.report', [
            'records' => $records,
            'summary' => $summary,
            'filters' => $filters,
            'groups'  => $groups,
        ]);
    }
}
