<?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\Carnets\Services\QRCodeGenerator;
use App\Modules\SportsActivity\Services\CardRenewalService;

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

        $search = trim((string) $request->get('q', ''));
        $statusFilter = trim((string) $request->get('status', ''));
        $typeFilter = trim((string) $request->get('card_type', ''));
        $page = max(1, (int) $request->get('page', 1));
        $perPage = 25;

        $where = 'c.is_archived = 0';
        $params = [];

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

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

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

        $cards = $db->select(
            "SELECT c.*, p.full_name_ar, p.player_type, p.photo_path as player_photo
             FROM sa_player_cards c
             INNER JOIN sa_players p ON p.id = c.player_id
             WHERE {$where}
             ORDER BY c.created_at DESC
             LIMIT {$perPage} OFFSET {$offset}",
            $params
        );

        return $this->view('SportsActivity.Views.cards.index', [
            'cards'      => $cards,
            'pagination' => $pagination,
            'filters'    => ['q' => $search, 'status' => $statusFilter, 'card_type' => $typeFilter],
        ]);
    }

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

        $card = $db->selectOne(
            "SELECT c.*, p.full_name_ar, p.full_name_en, p.national_id, p.player_type,
                    p.date_of_birth, p.phone, p.photo_path as player_photo,
                    r.registration_number, r.group_id,
                    g.name_ar as group_name, d.name_ar as discipline_name
             FROM sa_player_cards c
             INNER JOIN sa_players p ON p.id = c.player_id
             LEFT JOIN sa_registrations r ON r.id = c.registration_id
             LEFT JOIN sa_groups g ON g.id = r.group_id
             LEFT JOIN sa_programs pr ON pr.id = g.program_id
             LEFT JOIN sa_disciplines d ON d.id = pr.discipline_id
             WHERE c.id = ? AND c.is_archived = 0",
            [(int) $id]
        );

        if (!$card) {
            return $this->redirect('/sa/cards')->withError('الكارت غير موجود');
        }

        $accessHistory = $db->select(
            "SELECT * FROM sa_gate_access_log WHERE card_id = ? ORDER BY recorded_at DESC LIMIT 20",
            [(int) $id]
        );

        return $this->view('SportsActivity.Views.cards.index', [
            'card'          => $card,
            'accessHistory' => $accessHistory,
            'showDetail'    => true,
        ]);
    }

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

        $card = $db->selectOne(
            "SELECT * FROM sa_player_cards WHERE id = ? AND status = 'active' AND is_archived = 0",
            [(int) $id]
        );
        if (!$card) {
            return $this->redirect('/sa/cards')->withError('الكارت غير موجود أو لا يمكن إيقافه');
        }

        $reason = trim((string) $request->post('reason', ''));

        $db->update('sa_player_cards', [
            'status'         => 'suspended',
            'suspended_at'   => date('Y-m-d H:i:s'),
            'suspended_by'   => $employee ? (int) $employee->id : null,
            'suspend_reason' => $reason ?: null,
            'updated_at'     => date('Y-m-d H:i:s'),
        ], 'id = ?', [(int) $id]);

        $db->update('sa_players', [
            'card_status' => 'suspended',
            'updated_at'  => date('Y-m-d H:i:s'),
        ], 'id = ?', [(int) $card['player_id']]);

        return $this->redirect('/sa/cards/' . $id)->withSuccess('تم إيقاف الكارت');
    }

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

        $card = $db->selectOne(
            "SELECT * FROM sa_player_cards WHERE id = ? AND status IN ('active','suspended','temporary') AND is_archived = 0",
            [(int) $id]
        );
        if (!$card) {
            return $this->redirect('/sa/cards')->withError('الكارت غير موجود أو لا يمكن إلغاؤه');
        }

        $reason = trim((string) $request->post('reason', ''));

        $db->update('sa_player_cards', [
            'status'        => 'revoked',
            'revoked_at'    => date('Y-m-d H:i:s'),
            'revoked_by'    => $employee ? (int) $employee->id : null,
            'revoke_reason' => $reason ?: null,
            'updated_at'    => date('Y-m-d H:i:s'),
        ], 'id = ?', [(int) $id]);

        $db->update('sa_players', [
            'card_status' => 'revoked',
            'updated_at'  => date('Y-m-d H:i:s'),
        ], 'id = ?', [(int) $card['player_id']]);

        return $this->redirect('/sa/cards/' . $id)->withSuccess('تم إلغاء الكارت');
    }

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

        $card = $db->selectOne(
            "SELECT * FROM sa_player_cards WHERE id = ? AND status = 'suspended' AND is_archived = 0",
            [(int) $id]
        );
        if (!$card) {
            return $this->redirect('/sa/cards')->withError('الكارت غير موجود أو لا يمكن تفعيله');
        }

        $db->update('sa_player_cards', [
            'status'         => 'active',
            'suspended_at'   => null,
            'suspended_by'   => null,
            'suspend_reason' => null,
            'updated_at'     => date('Y-m-d H:i:s'),
        ], 'id = ?', [(int) $id]);

        $db->update('sa_players', [
            'card_status' => 'active',
            'updated_at'  => date('Y-m-d H:i:s'),
        ], 'id = ?', [(int) $card['player_id']]);

        return $this->redirect('/sa/cards/' . $id)->withSuccess('تم إعادة تفعيل الكارت');
    }

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

        $card = $db->selectOne(
            "SELECT c.*, p.full_name_ar, p.full_name_en, p.national_id,
                    p.date_of_birth, p.player_type, p.phone, p.photo_path as player_photo
             FROM sa_player_cards c
             INNER JOIN sa_players p ON p.id = c.player_id
             WHERE c.id = ? AND c.is_archived = 0",
            [(int) $id]
        );

        if (!$card) {
            return $this->redirect('/sa/cards')->withError('الكارت غير موجود');
        }

        $group = null;
        if ($card['registration_id']) {
            $reg = $db->selectOne("SELECT group_id FROM sa_registrations WHERE id = ?", [(int) $card['registration_id']]);
            if ($reg && $reg['group_id']) {
                $group = $db->selectOne(
                    "SELECT g.name_ar, d.name_ar as discipline_name
                     FROM sa_groups g
                     LEFT JOIN sa_programs p ON p.id = g.program_id
                     LEFT JOIN sa_disciplines d ON d.id = p.discipline_id
                     WHERE g.id = ?",
                    [(int) $reg['group_id']]
                );
            }
        }

        $qrSvg = QRCodeGenerator::renderSvg($card['qr_code_data'] ?? '', 150);

        $db->update('sa_player_cards', [
            'print_count'    => (int) $card['print_count'] + 1,
            'last_printed_at' => date('Y-m-d H:i:s'),
            'updated_at'     => date('Y-m-d H:i:s'),
        ], 'id = ?', [(int) $id]);

        return $this->view('SportsActivity.Views.cards.print', [
            'card'  => $card,
            'group' => $group,
            'qrSvg' => $qrSvg,
        ]);
    }

    public function renew(Request $request, string $id): Response
    {
        $months = (int) $request->post('months', 0);
        if ($months < 1 || $months > 24) {
            return $this->redirect('/sa/cards/' . $id)->withError('يرجى تحديد مدة تجديد صالحة (1-24 شهر)');
        }

        $result = CardRenewalService::renewCard((int) $id, $months);

        if ($result['success']) {
            $msg = 'تم إنشاء طلب تجديد الكارت';
            if (!empty($result['request_number'])) {
                $msg .= ' (طلب دفع: ' . $result['request_number'] . ')';
            }
            return $this->redirect('/sa/cards/' . $id)->withSuccess($msg);
        }

        return $this->redirect('/sa/cards/' . $id)->withError($result['error']);
    }

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

        $summary = $db->selectOne(
            "SELECT
                COUNT(*) as total_cards,
                SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active_cards,
                SUM(CASE WHEN status = 'temporary' THEN 1 ELSE 0 END) as temp_cards,
                SUM(CASE WHEN status = 'expired' THEN 1 ELSE 0 END) as expired_cards,
                SUM(CASE WHEN status = 'suspended' THEN 1 ELSE 0 END) as suspended_cards,
                SUM(CASE WHEN status = 'revoked' THEN 1 ELSE 0 END) as revoked_cards
             FROM sa_player_cards WHERE is_archived = 0"
        );

        $recentCards = $db->select(
            "SELECT c.*, p.full_name_ar, p.player_type
             FROM sa_player_cards c
             INNER JOIN sa_players p ON p.id = c.player_id
             WHERE c.is_archived = 0
             ORDER BY c.created_at DESC
             LIMIT 50"
        );

        return $this->view('SportsActivity.Views.cards.index', [
            'cards'      => $recentCards,
            'pagination' => null,
            'filters'    => ['q' => '', 'status' => '', 'card_type' => ''],
            'summary'    => $summary,
            'isReport'   => true,
        ]);
    }
}
