<?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\Modules\SportsActivity\Services\MakeupSessionService;

class MakeupSessionController extends Controller
{
    public function index(Request $request): Response
    {
        $db = App::getInstance()->db();
        $status = trim((string) $request->get('status', ''));
        $groupId = trim((string) $request->get('group_id', ''));

        $where = "1=1";
        $params = [];

        if ($status !== '') {
            $where .= " AND ms.status = ?";
            $params[] = $status;
        }
        if ($groupId !== '') {
            $where .= " AND ms.original_group_id = ?";
            $params[] = (int) $groupId;
        }

        $makeups = $db->select(
            "SELECT ms.*, sp.full_name_ar as player_name,
                    g1.name_ar as original_group_name, g2.name_ar as makeup_group_name
             FROM sa_makeup_sessions ms
             JOIN sa_players sp ON sp.id = ms.player_id
             JOIN sa_groups g1 ON g1.id = ms.original_group_id
             LEFT JOIN sa_groups g2 ON g2.id = ms.makeup_group_id
             WHERE {$where}
             ORDER BY ms.created_at DESC
             LIMIT 200",
            $params
        );

        $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.makeup-sessions.index', [
            'makeups' => $makeups,
            'groups'  => $groups,
            'filters' => ['status' => $status, 'group_id' => $groupId],
        ]);
    }

    public function create(Request $request): Response
    {
        $db = App::getInstance()->db();

        $playerId = trim((string) $request->get('player_id', ''));
        $groupId = trim((string) $request->get('group_id', ''));

        $player = null;
        $absences = [];

        if ($playerId !== '' && $groupId !== '') {
            $player = $db->selectOne("SELECT * FROM sa_players WHERE id = ?", [(int) $playerId]);

            $absences = $db->select(
                "SELECT ta.session_date, ta.status
                 FROM sa_training_attendance ta
                 WHERE ta.player_id = ? AND ta.group_id = ? AND ta.status IN ('absent','excused')
                   AND NOT EXISTS (
                       SELECT 1 FROM sa_makeup_sessions ms
                       WHERE ms.player_id = ta.player_id AND ms.original_group_id = ta.group_id
                         AND ms.missed_session_date = ta.session_date AND ms.status NOT IN ('cancelled','expired')
                   )
                 ORDER BY ta.session_date DESC
                 LIMIT 30",
                [(int) $playerId, (int) $groupId]
            );
        }

        $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.makeup-sessions.create', [
            'player'   => $player,
            'absences' => $absences,
            'groups'   => $groups,
            'filters'  => ['player_id' => $playerId, 'group_id' => $groupId],
        ]);
    }

    public function store(Request $request): Response
    {
        $playerId = (int) $request->post('player_id', 0);
        $groupId = (int) $request->post('group_id', 0);
        $missedDate = trim((string) $request->post('missed_session_date', ''));
        $reason = trim((string) $request->post('reason', ''));

        if (!$playerId || !$groupId || !$missedDate) {
            return $this->redirect('/sa/makeup-sessions/create')->withError('جميع الحقول مطلوبة');
        }

        $result = MakeupSessionService::createFromAbsence($playerId, $groupId, $missedDate, $reason);

        if (!$result['success']) {
            return $this->redirect("/sa/makeup-sessions/create?player_id={$playerId}&group_id={$groupId}")
                ->withError($result['error']);
        }

        return $this->redirect('/sa/makeup-sessions')
            ->withSuccess("تم إنشاء حصة تعويضية — تنتهي في {$result['expires_at']}");
    }

    public function schedule(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();

        $makeup = $db->selectOne(
            "SELECT ms.*, sp.full_name_ar as player_name, g.name_ar as group_name,
                    p.discipline_id
             FROM sa_makeup_sessions ms
             JOIN sa_players sp ON sp.id = ms.player_id
             JOIN sa_groups g ON g.id = ms.original_group_id
             JOIN sa_programs p ON p.id = g.program_id
             WHERE ms.id = ? AND ms.status = 'eligible'",
            [(int) $id]
        );
        if (!$makeup) {
            return $this->redirect('/sa/makeup-sessions')->withError('الحصة التعويضية غير متاحة');
        }

        $availableGroups = $db->select(
            "SELECT g.id, g.name_ar, g.code, c.full_name_ar as coach_name
             FROM sa_groups g
             JOIN sa_programs p ON p.id = g.program_id
             LEFT JOIN sa_coaches c ON c.id = g.coach_id
             WHERE g.status = 'active' AND g.is_archived = 0
               AND p.discipline_id = ?
             ORDER BY g.name_ar",
            [(int) $makeup['discipline_id']]
        );

        return $this->view('SportsActivity.Views.makeup-sessions.schedule', [
            'makeup'          => $makeup,
            'availableGroups' => $availableGroups,
        ]);
    }

    public function confirmSchedule(Request $request, string $id): Response
    {
        $makeupGroupId = (int) $request->post('makeup_group_id', 0);
        $makeupDate = trim((string) $request->post('makeup_date', ''));

        if (!$makeupGroupId || !$makeupDate) {
            return $this->redirect("/sa/makeup-sessions/{$id}/schedule")
                ->withError('يجب اختيار المجموعة والتاريخ');
        }

        $result = MakeupSessionService::schedule((int) $id, $makeupGroupId, $makeupDate);

        if (!$result['success']) {
            return $this->redirect("/sa/makeup-sessions/{$id}/schedule")
                ->withError($result['error']);
        }

        return $this->redirect('/sa/makeup-sessions')
            ->withSuccess('تم جدولة الحصة التعويضية بنجاح');
    }

    public function complete(Request $request, string $id): Response
    {
        $result = MakeupSessionService::complete((int) $id);

        if (!$result['success']) {
            return $this->redirect('/sa/makeup-sessions')->withError($result['error']);
        }

        return $this->redirect('/sa/makeup-sessions')->withSuccess('تم تأكيد حضور الحصة التعويضية');
    }

    public function cancel(Request $request, string $id): Response
    {
        $result = MakeupSessionService::cancel((int) $id);

        if (!$result['success']) {
            return $this->redirect('/sa/makeup-sessions')->withError($result['error']);
        }

        return $this->redirect('/sa/makeup-sessions')->withSuccess('تم إلغاء الحصة التعويضية');
    }
}
