<?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\GateAccessService;

class GateController extends Controller
{
    public function index(Request $request): Response
    {
        $db = App::getInstance()->db();

        $todayStats = $db->selectOne(
            "SELECT
                COUNT(*) as total_scans,
                SUM(CASE WHEN granted = 1 AND access_type = 'entry' THEN 1 ELSE 0 END) as entries,
                SUM(CASE WHEN granted = 0 THEN 1 ELSE 0 END) as denied,
                COUNT(DISTINCT player_id) as unique_players
             FROM sa_gate_access_log
             WHERE DATE(recorded_at) = CURDATE()"
        );

        $recentEntries = $db->select(
            "SELECT g.*, p.full_name_ar, p.photo_path, c.card_number
             FROM sa_gate_access_log g
             INNER JOIN sa_players p ON p.id = g.player_id
             LEFT JOIN sa_player_cards c ON c.id = g.card_id
             WHERE DATE(g.recorded_at) = CURDATE()
             ORDER BY g.recorded_at DESC
             LIMIT 20"
        );

        return $this->view('SportsActivity.Views.gate.index', [
            'todayStats'    => $todayStats,
            'recentEntries' => $recentEntries,
        ]);
    }

    public function scan(Request $request): Response
    {
        $scannedData = trim((string) $request->post('scanned_data', ''));
        $accessPoint = trim((string) $request->post('access_point', ''));

        if ($scannedData === '') {
            return $this->json(['success' => false, 'error' => 'لا توجد بيانات مسح']);
        }

        $result = GateAccessService::checkAccess($scannedData);

        if ($result['granted']) {
            $card = $result['card'];
            GateAccessService::recordEntry(
                (int) $card['player_id'],
                (int) $card['id'],
                $accessPoint
            );

            $sessionInfo = GateAccessService::getPlayerSessionToday((int) $card['player_id']);

            return $this->json([
                'success'     => true,
                'granted'     => true,
                'player_name' => $result['player_name'],
                'player_type' => $result['player_type'],
                'card_number' => $card['card_number'],
                'card_type'   => $result['card_type'],
                'valid_until' => $result['valid_until'],
                'photo_path'  => $card['photo_path'] ?? null,
                'has_session_today' => $sessionInfo['has_session_today'],
                'session_info'      => $sessionInfo['session_info'],
            ]);
        }

        $card = $result['card'] ?? null;
        if ($card) {
            GateAccessService::recordDenial(
                (int) $card['player_id'],
                (int) $card['id'],
                $result['reason'],
                $scannedData
            );
        }

        return $this->json([
            'success'     => true,
            'granted'     => false,
            'reason'      => $result['reason'],
            'player_name' => $card['full_name_ar'] ?? null,
            'card_number' => $card['card_number'] ?? null,
        ]);
    }

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

        $date = trim((string) $request->get('date', date('Y-m-d')));
        $grantedFilter = trim((string) $request->get('granted', ''));
        $search = trim((string) $request->get('q', ''));
        $page = max(1, (int) $request->get('page', 1));
        $perPage = 50;

        $where = 'DATE(g.recorded_at) = ?';
        $params = [$date];

        if ($grantedFilter !== '') {
            $where .= ' AND g.granted = ?';
            $params[] = (int) $grantedFilter;
        }

        if ($search !== '') {
            $where .= ' AND (p.full_name_ar LIKE ? OR c.card_number LIKE ?)';
            $params[] = '%' . $search . '%';
            $params[] = '%' . $search . '%';
        }

        $total = (int) $db->selectOne(
            "SELECT COUNT(*) as cnt FROM sa_gate_access_log g
             INNER JOIN sa_players p ON p.id = g.player_id
             LEFT JOIN sa_player_cards c ON c.id = g.card_id
             WHERE {$where}",
            $params
        )['cnt'];

        $pagination = \App\Core\Pagination::paginate($total, $perPage, $page);
        $offset = ($pagination['current_page'] - 1) * $perPage;

        $entries = $db->select(
            "SELECT g.*, p.full_name_ar, p.player_type, p.photo_path, c.card_number, c.card_type,
                    e.full_name_ar as recorded_by_name
             FROM sa_gate_access_log g
             INNER JOIN sa_players p ON p.id = g.player_id
             LEFT JOIN sa_player_cards c ON c.id = g.card_id
             LEFT JOIN employees e ON e.id = g.recorded_by
             WHERE {$where}
             ORDER BY g.recorded_at DESC
             LIMIT {$perPage} OFFSET {$offset}",
            $params
        );

        return $this->view('SportsActivity.Views.gate.log', [
            'entries'    => $entries,
            'pagination' => $pagination,
            'filters'    => ['date' => $date, 'granted' => $grantedFilter, 'q' => $search],
        ]);
    }

    public function report(Request $request): Response
    {
        $date = trim((string) $request->get('date', date('Y-m-d')));
        $report = GateAccessService::getDailyAccessReport($date);

        return $this->view('SportsActivity.Views.gate.log', [
            'entries'    => $report['entries'],
            'pagination' => null,
            'filters'    => ['date' => $date, 'granted' => '', 'q' => ''],
            'summary'    => $report['summary'],
            'isReport'   => true,
        ]);
    }
}
