<?php
declare(strict_types=1);

namespace CronJobs;

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

/**
 * Daily: scans items below reorder point and dispatches alerts.
 * Complements LowStockAlertJob with procurement-specific actions.
 */
class ReorderPointAlertJob
{
    private Database $db;
    public function __construct(Database $db) { $this->db = $db; }

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

    public function run(): array
    {
        // Find items where current stock is at or below reorder point
        // and there is no open PO or PR already covering them
        $items = $this->db->select(
            "SELECT iws.`item_id`, iws.`warehouse_id`, iws.`quantity`, iws.`min_level`,
                    i.`name_ar`, i.`sku`, w.`name_ar` as warehouse_name
             FROM `item_warehouse_stock` iws
             JOIN `inventory_items` i ON i.`id` = iws.`item_id` AND i.`is_archived` = 0
             JOIN `warehouses` w ON w.`id` = iws.`warehouse_id` AND w.`is_archived` = 0
             WHERE iws.`quantity` <= iws.`min_level`
               AND iws.`min_level` IS NOT NULL
               AND iws.`min_level` > 0
               AND NOT EXISTS (
                   SELECT 1 FROM `purchase_order_items` poi
                   JOIN `purchase_orders` po ON po.`id` = poi.`purchase_order_id`
                   WHERE poi.`item_id` = iws.`item_id`
                     AND po.`status` IN ('draft', 'submitted', 'approved')
               )
             ORDER BY (iws.`quantity` - iws.`min_level`) ASC"
        );

        $count = count($items);

        foreach ($items as $item) {
            EventBus::dispatch('procurement.reorder_point_alert', [
                'item_id'        => (int) $item['item_id'],
                'warehouse_id'   => (int) $item['warehouse_id'],
                'item_name'      => $item['name_ar'] ?? '',
                'sku'            => $item['sku'] ?? '',
                'warehouse_name' => $item['warehouse_name'] ?? '',
                'current_qty'    => (string) $item['quantity'],
                'min_level'      => (string) $item['min_level'],
                'deficit'        => bcsub((string) $item['min_level'], (string) $item['quantity'], 3),
            ]);
        }

        if ($count > 0) {
            Logger::info("Reorder point alert: {$count} item(s) need replenishment (no open PO)");
        }

        return ['items_below_reorder' => $count];
    }
}
