<?php
declare(strict_types=1);

namespace App\Modules\Members\Services;

use App\Core\App;

/**
 * Handles automatic freezing of male children who reach age 25,
 * subscription blocking checks, and carnet printing eligibility.
 */
final class AutoFreezeService
{
    /**
     * Process automatic freeze for male children aged 25+.
     * Sets is_frozen = 1 with reason indicating they must convert to independent membership.
     *
     * @return array{frozen_count: int, processed: int}
     */
    public static function processAutoFreeze(): array
    {
        $db = App::getInstance()->db();

        $children = $db->select(
            "SELECT id, date_of_birth FROM children
             WHERE gender = 'male'
               AND is_frozen = 0
               AND is_archived = 0
               AND status = 'active'"
        );

        $processed = count($children);
        $frozenCount = 0;
        $now = date('Y-m-d H:i:s');
        $today = new \DateTimeImmutable('today');

        foreach ($children as $child) {
            $dob = new \DateTimeImmutable($child['date_of_birth']);
            $age = (int) $dob->diff($today)->y;

            if ($age >= 25) {
                $db->update(
                    'children',
                    [
                        'is_frozen'     => 1,
                        'frozen_at'     => $now,
                        'frozen_reason' => 'بلوغ سن 25 عام - يجب التحويل لعضوية مستقلة',
                    ],
                    'id = ?',
                    [$child['id']]
                );
                $frozenCount++;
            }
        }

        return [
            'frozen_count' => $frozenCount,
            'processed'    => $processed,
        ];
    }

    /**
     * Check if a member has unpaid subscriptions for the current financial year.
     * Blocks certain operations if annual subscription is not paid.
     *
     * @return array{blocked: bool, reason?: string, unpaid_amount?: string}
     */
    public static function checkSubscriptionBlock(int $memberId): array
    {
        $db = App::getInstance()->db();

        $financialYear = self::getCurrentFinancialYear();

        $unpaid = $db->select(
            "SELECT total_amount, paid_amount FROM subscriptions
             WHERE member_id = ?
               AND financial_year = ?
               AND status IN ('pending', 'overdue')",
            [$memberId, $financialYear]
        );

        if (!empty($unpaid)) {
            $unpaidAmount = '0.00';
            foreach ($unpaid as $row) {
                $remaining = bcsub($row['total_amount'], $row['paid_amount'], 2);
                $unpaidAmount = bcadd($unpaidAmount, $remaining, 2);
            }

            return [
                'blocked'       => true,
                'reason'        => 'لم يتم سداد الاشتراك السنوي',
                'unpaid_amount' => $unpaidAmount,
            ];
        }

        return ['blocked' => false];
    }

    /**
     * Check if a member is eligible to print their carnet (membership card).
     * Blocked if subscription unpaid, member is suspended, or member is frozen.
     *
     * @return array{allowed: bool, reason?: string}
     */
    public static function canPrintCarnet(int $memberId): array
    {
        $db = App::getInstance()->db();

        // Check member status
        $member = $db->selectOne(
            "SELECT status FROM members WHERE id = ? AND is_archived = 0",
            [$memberId]
        );

        if (!$member) {
            return [
                'allowed' => false,
                'reason'  => 'العضو غير موجود',
            ];
        }

        if ($member['status'] === 'suspended') {
            return [
                'allowed' => false,
                'reason'  => 'العضوية موقوفة',
            ];
        }

        if ($member['status'] === 'frozen') {
            return [
                'allowed' => false,
                'reason'  => 'العضوية مجمدة',
            ];
        }

        // Check subscription block
        $subscriptionCheck = self::checkSubscriptionBlock($memberId);
        if ($subscriptionCheck['blocked']) {
            return [
                'allowed' => false,
                'reason'  => $subscriptionCheck['reason'],
            ];
        }

        return ['allowed' => true];
    }

    /**
     * Get current financial year string.
     * FY runs July to June: if month >= 7, FY is "thisYear/thisYear+1", else "lastYear/thisYear".
     */
    private static function getCurrentFinancialYear(): string
    {
        $month = (int) date('n');
        $year = (int) date('Y');

        if ($month >= 7) {
            return $year . '/' . ($year + 1);
        }

        return ($year - 1) . '/' . $year;
    }
}
