<?php
declare(strict_types=1);

namespace App\Modules\Waiver\Services;

use App\Core\App;
use App\Core\EventBus;
use App\Core\Logger;
use App\Modules\Archive\Services\ArchiveService;

final class WaiverProcessor
{
    public static function execute(int $waiverId): array
    {
        $db = App::getInstance()->db();
        $employee = App::getInstance()->currentEmployee();

        $waiver = $db->selectOne("SELECT * FROM waiver_requests WHERE id = ?", [$waiverId]);
        if (!$waiver || !in_array($waiver['status'], ['approved', 'fee_paid'])) {
            return ['success' => false, 'error' => 'طلب التنازل غير صالح أو غير مُعتمد'];
        }

        if (!$waiver['target_member_id']) {
            return ['success' => false, 'error' => 'لم يتم تحديد العضو المستفيد'];
        }

        $sourceMember = $db->selectOne("SELECT * FROM members WHERE id = ?", [(int) $waiver['source_member_id']]);
        if (!$sourceMember) return ['success' => false, 'error' => 'العضو المصدر غير موجود'];

        $db->beginTransaction();
        try {
            // Archive snapshot
            $snapshotId = ArchiveService::takeSnapshot('members', (int) $sourceMember['id'], 'waiver', 'تنازل — طلب #' . $waiverId);

            // Transfer membership number to target member
            $db->update('members', [
                'membership_number' => $waiver['membership_number'],
                'status'            => 'active',
                'updated_at'        => date('Y-m-d H:i:s'),
            ], '`id` = ?', [(int) $waiver['target_member_id']]);

            // Archive source member (remove number, set archived)
            $db->update('members', [
                'membership_number' => null,
                'status'            => 'waived',
                'is_archived'       => 1,
                'archived_at'       => date('Y-m-d H:i:s'),
                'archived_by'       => $employee ? (int) $employee->id : null,
                'updated_at'        => date('Y-m-d H:i:s'),
            ], '`id` = ?', [(int) $waiver['source_member_id']]);

            // Record number chain
            ArchiveService::recordNumberTransfer($waiver['membership_number'], 'waiver', 'members', (int) $waiver['target_member_id']);

            // Complete waiver
            $db->update('waiver_requests', [
                'archive_snapshot_id' => $snapshotId,
                'status'              => 'completed',
                'updated_at'          => date('Y-m-d H:i:s'),
            ], '`id` = ?', [$waiverId]);

            $db->commit();

            EventBus::dispatch('waiver.completed', [
                'waiver_id'        => $waiverId,
                'source_member_id' => (int) $waiver['source_member_id'],
                'target_member_id' => (int) $waiver['target_member_id'],
                'membership_number'=> $waiver['membership_number'],
                'fee_amount'       => $waiver['waiver_fee_amount'] ?? '0.00',
                'fee_percentage'   => $waiver['waiver_fee_percentage'] ?? '30',
            ]);

            return ['success' => true, 'snapshot_id' => $snapshotId];
        } catch (\Throwable $e) {
            $db->rollBack();
            Logger::error("Waiver failed: " . $e->getMessage());
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }
}