<?php

declare(strict_types=1);
final class InventoryController
{
    private static function admin(): void
    {
        if (!Auth::is('admin')) {
            http_response_code(403);
            echo h(t('settings.admin_only'));
            exit();
        }
    }
    public static function index(): void
    {
        self::admin();
        $db = DB::pdo();
        render('settings_inventory.php', [
            'title' => t('inventory.title'),
            'products' => InventoryService::products(),
            'batches' => InventoryService::batches(),
            'movements' => InventoryService::movements(),
            'alerts' => InventoryService::alerts(),
            'references' => [
                'medication' => $db
                    ->query('SELECT id,name FROM ref_medications ORDER BY name COLLATE NOCASE')
                    ->fetchAll(),
                'dewormer' => $db->query('SELECT id,name FROM ref_dewormers ORDER BY name COLLATE NOCASE')->fetchAll(),
                'vaccine' => $db->query('SELECT id,name FROM ref_vaccines ORDER BY name COLLATE NOCASE')->fetchAll(),
            ],
            'suppliers' => $db
                ->query(
                    "SELECT DISTINCT dc.id,dc.name FROM directory_contacts dc JOIN directory_contact_roles r ON r.contact_id=dc.id WHERE dc.deleted_at IS NULL AND dc.kind='organization' AND r.role IN ('cabinet','fourriere') ORDER BY dc.name COLLATE NOCASE",
                )
                ->fetchAll(),
            'animals' => $db
                ->query(
                    'SELECT id,name FROM animals WHERE deleted_at IS NULL AND archived_at IS NULL ORDER BY name COLLATE NOCASE',
                )
                ->fetchAll(),
            'status' => (string) ($_GET['status'] ?? ''),
            'error' => (string) ($_GET['error'] ?? ''),
        ]);
    }
    public static function product(): void
    {
        self::admin();
        self::run(fn() => InventoryService::saveProduct($_POST), 'product');
    }
    public static function receive(): void
    {
        self::admin();
        self::run(fn() => InventoryService::receive($_POST), 'received');
    }
    public static function move(): void
    {
        self::admin();
        self::run(fn() => InventoryService::move($_POST), 'moved');
    }
    private static function run(callable $fn, string $status): void
    {
        try {
            $fn();
            header('Location: /settings/inventory?status=' . $status);
        } catch (RuntimeException $e) {
            header('Location: /settings/inventory?error=' . rawurlencode($e->getMessage()));
        } catch (Throwable $e) {
            header('Location: /settings/inventory?error=' . rawurlencode(SecurityService::publicError($e)));
        }
        exit();
    }
}
