<?php
declare(strict_types=1);

namespace App\Modules\PlayerAffairs\Services;

use App\Core\App;
use App\Modules\PlayerAffairs\Models\Player;
use App\Modules\PlayerAffairs\Models\PlayerDiscipline;
use App\Modules\Members\Models\Member;
use App\Modules\Rules\Services\RuleEngine;

final class PlayerRegistrationService
{
    /**
     * Register a player from an existing club member.
     */
    public static function registerMemberPlayer(int $memberId, array $data): Player
    {
        $member = Member::find($memberId);
        if (!$member) {
            throw new \RuntimeException('العضو غير موجود');
        }

        $serial = self::nextSerial('member');

        $playerData = array_merge($data, [
            'player_type'         => 'member',
            'member_id'           => $memberId,
            'registration_serial' => $serial,
            'full_name_ar'        => $data['full_name_ar'] ?? $member->full_name_ar,
            'full_name_en'        => $data['full_name_en'] ?? $member->full_name_en,
            'national_id'         => $data['national_id'] ?? $member->national_id,
            'date_of_birth'       => $data['date_of_birth'] ?? $member->date_of_birth,
            'gender'              => $data['gender'] ?? $member->gender,
            'phone'               => $data['phone'] ?? $member->phone_mobile,
            'email'               => $data['email'] ?? $member->email,
            'card_status'         => 'inactive',
            'medical_status'      => 'pending',
            'is_archived'         => 0,
        ]);

        return Player::create($playerData);
    }

    /**
     * Register a non-member player from direct input.
     */
    public static function registerNonMemberPlayer(array $data): Player
    {
        $serial = self::nextSerial('non_member');

        $playerData = array_merge($data, [
            'player_type'          => 'non_member',
            'member_id'            => null,
            'registration_serial'  => $serial,
            'access_window_minutes' => $data['access_window_minutes'] ?? 30,
            'card_status'          => 'inactive',
            'medical_status'       => 'pending',
            'is_archived'          => 0,
        ]);

        return Player::create($playerData);
    }

    /**
     * Generate the next registration serial for the given player type.
     */
    public static function nextSerial(string $type): string
    {
        $ruleCode = $type === 'member'
            ? 'SPORTS_REG_SERIAL_START_MEMBER'
            : 'SPORTS_REG_SERIAL_START_NONMEMBER';

        $ruleValue = RuleEngine::getValue($ruleCode, 'value');
        $start = $ruleValue !== null ? (int) $ruleValue : 1;

        $db = App::getInstance()->db();
        $row = $db->selectOne(
            "SELECT MAX(CAST(registration_serial AS UNSIGNED)) as max_serial FROM players WHERE player_type = ?",
            [$type]
        );

        $maxSerial = (int) ($row['max_serial'] ?? 0);

        return (string) max($start, $maxSerial + 1);
    }

    /**
     * Add a discipline to a player.
     */
    public static function addDiscipline(int $playerId, int $disciplineId, ?string $season = null): PlayerDiscipline
    {
        return PlayerDiscipline::create([
            'player_id'     => $playerId,
            'discipline_id' => $disciplineId,
            'season'        => $season,
            'status'        => 'active',
            'registered_at' => date('Y-m-d H:i:s'),
        ]);
    }

    /**
     * Quick search for autocomplete: players matching name/national_id/serial.
     */
    public static function search(string $query): array
    {
        $db = App::getInstance()->db();
        $search = '%' . $query . '%';

        return $db->select(
            "SELECT id, full_name_ar, full_name_en, national_id, registration_serial, player_type
             FROM players
             WHERE is_archived = 0
               AND (full_name_ar LIKE ? OR full_name_en LIKE ? OR national_id LIKE ? OR registration_serial LIKE ?)
             ORDER BY full_name_ar ASC
             LIMIT 10",
            [$search, $search, $search, $search]
        );
    }
}
