<?php

namespace Modules\Inventory\Services;

use App\Models\ActivityLogModel;
use App\Models\StockAdjustmentModel;
use App\Models\StockBalanceModel;

class StockService
{
    protected StockBalanceModel $balances;
    protected StockAdjustmentModel $adjustments;
    protected ActivityLogModel $activity;

    public function __construct()
    {
        $this->balances    = new StockBalanceModel();
        $this->adjustments = new StockAdjustmentModel();
        $this->activity    = new ActivityLogModel();
    }

    public function adjust(array $input, ?int $actingUserId): array
    {
        $productId   = (int) ($input['product_id'] ?? 0);
        $warehouseId = (int) ($input['warehouse_id'] ?? 0);
        $quantity    = (float) ($input['quantity'] ?? 0);
        $mode        = $input['mode'] ?? 'set';

        if ($productId <= 0 || $warehouseId <= 0) {
            return ['success' => false, 'errors' => ['product_id' => 'Product and warehouse are required.']];
        }

        $existing = $this->balances->findByProductAndWarehouse($productId, $warehouseId);
        $before   = $existing ? (float) $existing['quantity'] : 0.0;

        if ($mode === 'set') {
            $delta = $quantity - $before;
        } else {
            $delta = $quantity;
        }

        if ($delta == 0.0) {
            return ['success' => true];
        }

        $result = $this->balances->adjustQuantity($productId, $warehouseId, $delta, $actingUserId);
        if (! $result['success']) {
            return ['success' => false, 'errors' => ['quantity' => $result['error']]];
        }

        $after = (float) $result['quantity'];

        if (! $this->adjustments->insert([
            'number'          => $this->adjustments->nextNumber(),
            'adjustment_date' => date('Y-m-d'),
            'product_id'      => $productId,
            'warehouse_id'    => $warehouseId,
            'quantity_before' => $before,
            'quantity_after'  => $after,
            'delta'           => $delta,
            'mode'            => $mode,
            'reason'          => trim($input['reason'] ?? '') ?: null,
            'notes'           => trim($input['notes'] ?? '') ?: null,
            'created_by'      => $actingUserId,
        ], true)) {
            return ['success' => false, 'errors' => $this->adjustments->errors()];
        }

        $adjustmentId = $this->adjustments->getInsertID();

        $this->activity->log(
            'stock',
            'adjusted',
            $actingUserId,
            "Adjusted stock product #{$productId} warehouse #{$warehouseId} by {$delta}",
            (string) $result['id']
        );

        return ['success' => true, 'adjustment_id' => $adjustmentId];
    }
}
