<?php
declare(strict_types=1);

namespace App\Modules\Subscriptions\Services;

use App\Core\App;
use App\Core\EventBus;
use App\Core\Logger;

final class OverdueFineApplicator
{
    public static function run(): array
    {
        $db = App::getInstance()->db();

        $currentFY = self::currentFinancialYear();
        $results = ['fines_applied' => 0, 'members_dropped' => 0, 'errors' => []];

        $members = $db->select(
            "SELECT DISTINCT s.member_id
             FROM subscriptions s
             JOIN members m ON m.id = s.member_id AND m.is_archived = 0 AND m.status = 'active'
             WHERE s.status IN ('pending','overdue') AND s.financial_year < ?",
            [$currentFY]
        );

        foreach ($members as $row) {
            $memberId = (int) $row['member_id'];
            try {
                $calc = SubscriptionCalculator::calculateLateFine($memberId, $currentFY);

                // Update fine amounts on individual subscriptions
                foreach ($calc['details'] as $detail) {
                    $db->query(
                        "UPDATE subscriptions SET fine_amount = ?, status = 'overdue', updated_at = NOW()
                         WHERE member_id = ? AND financial_year = ? AND status IN ('pending','overdue')",
                        [$detail['fine_amount'], $memberId, $detail['financial_year']]
                    );
                }

                if (bccomp($calc['total_fine'], '0', 2) > 0) {
                    $results['fines_applied']++;
                }

                // Drop membership if 5+ consecutive years unpaid
                if ($calc['should_drop']) {
                    $db->query(
                        "UPDATE members SET status = 'dropped', updated_at = NOW() WHERE id = ? AND status = 'active'",
                        [$memberId]
                    );
                    $results['members_dropped']++;

                    EventBus::dispatch('member.dropped', [
                        'member_id' => $memberId,
                        'reason'    => 'تأخر عن سداد الاشتراك السنوي 5 سنوات متتالية',
                        'years_unpaid' => $calc['years_unpaid'],
                    ]);

                    Logger::info("Member dropped for non-payment", [
                        'member_id' => $memberId,
                        'years'     => $calc['years_unpaid'],
                    ]);
                }
            } catch (\Throwable $e) {
                $results['errors'][] = "Member #{$memberId}: " . $e->getMessage();
                Logger::error("OverdueFineApplicator error", ['member_id' => $memberId, 'error' => $e->getMessage()]);
            }
        }

        return $results;
    }

    private static function currentFinancialYear(): string
    {
        $month = (int) date('n');
        $year = (int) date('Y');
        return $month >= 7 ? $year . '/' . ($year + 1) : ($year - 1) . '/' . $year;
    }
}
