<?php
declare(strict_types=1);

namespace App\Modules\Procurement\Services;

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

final class ItemPriceTrackingService
{
    public static function registerListeners(): void
    {
        EventBus::listen('procurement.invoice_approved', [self::class, 'onInvoiceApproved'], 60);
    }

    public static function onInvoiceApproved(array $data): void
    {
        $db = App::getInstance()->db();

        $invoiceId = (int) ($data['invoice_id'] ?? 0);
        if ($invoiceId <= 0) return;

        $items = $db->select(
            "SELECT item_id, unit_cost FROM vendor_invoice_items WHERE invoice_id = ? AND item_id IS NOT NULL",
            [$invoiceId]
        );

        $supplierId = (int) ($data['supplier_id'] ?? 0);
        $invoiceDate = date('Y-m-d');

        foreach ($items as $item) {
            $db->insert('item_price_history', [
                'item_id' => (int) $item['item_id'],
                'supplier_id' => $supplierId,
                'price' => (string) $item['unit_cost'],
                'price_date' => $invoiceDate,
                'source' => 'invoice',
                'reference_id' => $invoiceId,
                'created_at' => date('Y-m-d H:i:s'),
            ]);
        }
    }

    public static function getLatestPrice(int $itemId, ?int $supplierId = null): ?array
    {
        $db = App::getInstance()->db();

        $sql = "SELECT * FROM item_price_history WHERE item_id = ?";
        $params = [$itemId];

        if ($supplierId) {
            $sql .= " AND supplier_id = ?";
            $params[] = $supplierId;
        }

        $sql .= " ORDER BY price_date DESC, id DESC LIMIT 1";
        return $db->selectOne($sql, $params);
    }

    public static function getPriceDeviation(int $itemId, string $currentPrice): array
    {
        $db = App::getInstance()->db();

        $avgRow = $db->selectOne(
            "SELECT AVG(price) as avg_price, MIN(price) as min_price, MAX(price) as max_price
             FROM item_price_history WHERE item_id = ? AND price_date >= DATE_SUB(NOW(), INTERVAL 6 MONTH)",
            [$itemId]
        );

        if (!$avgRow || !$avgRow['avg_price']) {
            return ['has_history' => false];
        }

        $avgPrice = (string) $avgRow['avg_price'];
        $deviation = bccomp($avgPrice, '0', 2) > 0
            ? bcmul(bcdiv(bcsub($currentPrice, $avgPrice, 4), $avgPrice, 4), '100', 2)
            : '0.00';

        return [
            'has_history' => true,
            'avg_price' => $avgPrice,
            'min_price' => (string) $avgRow['min_price'],
            'max_price' => (string) $avgRow['max_price'],
            'current_price' => $currentPrice,
            'deviation_pct' => $deviation,
        ];
    }
}
