<?php
declare(strict_types=1);

namespace CronJobs;

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

class InstallmentDefaultJob
{
    private const OVERDUE_THRESHOLD_DAYS = 90;
    private const MIN_OVERDUE_ITEMS = 3;

    private Database $db;
    public function __construct(Database $db) { $this->db = $db; }

    public function shouldRun(): bool
    {
        return true;
    }

    public function run(): array
    {
        $processed = 0;

        $defaulted = $this->db->select(
            "SELECT p.id as plan_id, p.member_id, COUNT(s.id) as overdue_count
             FROM installment_plans p
             JOIN installment_schedule s ON s.installment_plan_id = p.id
             WHERE p.status = 'active'
               AND s.status = 'pending'
               AND s.due_date < DATE_SUB(CURDATE(), INTERVAL ? DAY)
             GROUP BY p.id, p.member_id
             HAVING overdue_count >= ?",
            [self::OVERDUE_THRESHOLD_DAYS, self::MIN_OVERDUE_ITEMS]
        );

        foreach ($defaulted as $plan) {
            $planId = (int) $plan['plan_id'];
            $memberId = (int) $plan['member_id'];

            $this->db->update('installment_plans', [
                'status'     => 'defaulted',
                'updated_at' => date('Y-m-d H:i:s'),
            ], '`id` = ?', [$planId]);

            $this->db->query(
                "UPDATE installment_schedule SET status = 'overdue', updated_at = NOW()
                 WHERE installment_plan_id = ? AND status = 'pending'",
                [$planId]
            );

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

            if ($member && $member['status'] === 'active') {
                $this->db->update('members', [
                    'status'     => 'dropped',
                    'updated_at' => date('Y-m-d H:i:s'),
                ], '`id` = ?', [$memberId]);

                EventBus::dispatch('member.dropped', [
                    'member_id'          => $memberId,
                    'reason'             => 'عدم الالتزام بسداد الأقساط المستحقة',
                    'installment_plan_id' => $planId,
                ]);

                Logger::warning("Member #{$memberId} dropped: installment default (plan #{$planId})");
            }

            $processed++;
        }

        return ['processed' => $processed];
    }
}
