<?php
declare(strict_types=1);

namespace App\Modules\Carnets\Services;

use App\Core\App;
use App\Core\EventBus;
use App\Modules\Carnets\Models\Carnet;
use App\Modules\Carnets\Models\CarnetGuestEntry;

class GuestEntryService
{
    public static function checkEligibility(int $carnetId): array
    {
        $db = App::getInstance()->db();
        $carnet = $db->selectOne("SELECT * FROM carnets WHERE id = ? AND is_active = 1", [$carnetId]);

        if (!$carnet) {
            return ['الكارنيه غير موجود أو غير نشط'];
        }

        $errors = [];

        $member = $db->selectOne("SELECT * FROM members WHERE id = ? AND is_archived = 0", [(int) $carnet['member_id']]);
        if (!$member) {
            $errors[] = 'العضو صاحب الكارنيه غير موجود';
            return $errors;
        }

        if (($member['membership_status'] ?? '') !== 'active') {
            $errors[] = 'عضوية صاحب الكارنيه غير نشطة';
        }

        $used = (int) ($carnet['used_invitations'] ?? 0);
        $total = (int) ($carnet['total_invitations'] ?? 10);
        if ($used >= $total) {
            $errors[] = "تم استنفاذ جميع الدعوات ({$total}/{$total})";
        }

        return $errors;
    }

    public static function getRemainingInvitations(int $carnetId): int
    {
        $db = App::getInstance()->db();
        $carnet = $db->selectOne("SELECT total_invitations, used_invitations FROM carnets WHERE id = ?", [$carnetId]);
        if (!$carnet) return 0;
        return max(0, (int) $carnet['total_invitations'] - (int) $carnet['used_invitations']);
    }

    public static function recordEntry(array $data): CarnetGuestEntry
    {
        $db = App::getInstance()->db();
        $carnetId = (int) $data['carnet_id'];

        $entry = CarnetGuestEntry::create($data);

        $guestCount = (int) ($data['guest_count'] ?? 1);
        $db->query(
            "UPDATE carnets SET used_invitations = used_invitations + ? WHERE id = ?",
            [$guestCount, $carnetId]
        );

        EventBus::dispatch('carnet_guest.entry_recorded', [
            'entry_id'   => (int) $entry->id,
            'carnet_id'  => $carnetId,
            'member_id'  => (int) $data['member_id'],
            'guest_name' => $data['guest_name'],
            'facility_id'=> $data['facility_id'] ?? null,
            'activity'   => $data['activity_type'],
            'amount'     => (float) ($data['amount_paid'] ?? 0),
        ]);

        $remaining = self::getRemainingInvitations($carnetId);
        if ($remaining <= 2 && $remaining > 0) {
            EventBus::dispatch('carnet.low_balance', [
                'carnet_id' => $carnetId,
                'member_id' => (int) $data['member_id'],
                'remaining' => $remaining,
            ]);
        }

        return $entry;
    }

    public static function checkOut(int $entryId): bool
    {
        $db = App::getInstance()->db();
        $entry = $db->selectOne("SELECT * FROM carnet_guest_entries WHERE id = ? AND status = 'active'", [$entryId]);
        if (!$entry) return false;

        $db->update('carnet_guest_entries', [
            'exit_time' => date('H:i:s'),
            'status'    => 'checked_out',
            'updated_at'=> date('Y-m-d H:i:s'),
        ], '`id` = ?', [$entryId]);

        return true;
    }

    public static function cancelEntry(int $entryId, string $reason = ''): bool
    {
        $db = App::getInstance()->db();
        $entry = $db->selectOne("SELECT * FROM carnet_guest_entries WHERE id = ? AND status = 'active'", [$entryId]);
        if (!$entry) return false;

        $db->update('carnet_guest_entries', [
            'status'     => 'cancelled',
            'notes'      => $reason,
            'updated_at' => date('Y-m-d H:i:s'),
        ], '`id` = ?', [$entryId]);

        $guestCount = (int) ($entry['guest_count'] ?? 1);
        $db->query(
            "UPDATE carnets SET used_invitations = GREATEST(0, used_invitations - ?) WHERE id = ?",
            [$guestCount, (int) $entry['carnet_id']]
        );

        return true;
    }

    public static function getSummaryForMember(int $memberId): array
    {
        $db = App::getInstance()->db();

        $carnet = $db->selectOne(
            "SELECT * FROM carnets WHERE member_id = ? AND is_active = 1 ORDER BY id DESC LIMIT 1",
            [$memberId]
        );

        if (!$carnet) {
            return ['carnet' => null, 'remaining' => 0, 'total_used' => 0, 'entries' => []];
        }

        $entries = CarnetGuestEntry::getForCarnet((int) $carnet['id']);

        return [
            'carnet'     => $carnet,
            'remaining'  => max(0, (int) $carnet['total_invitations'] - (int) $carnet['used_invitations']),
            'total_used' => (int) $carnet['used_invitations'],
            'entries'    => $entries,
        ];
    }
}
