<?php

namespace App\Console\Commands;

use App\Models\Central\Tenant;
use App\Services\AuditLog;
use App\Services\BatchService;
use App\Services\CurrentContext;
use Illuminate\Console\Command;

class ReconcileBatches extends Command
{
    protected $signature = 'batches:reconcile {--fix : Correct branch_stock from the lot ledger (and open lots for unpriced orphan stock)}';

    protected $description = 'Report (and optionally correct) drift between lot quantities and branch_stock';

    public function handle(BatchService $batches, CurrentContext $context): int
    {
        // Deliberate cross-tenant sweep, per tenant — the same explicit
        // opt-in pattern as FlagExpiredBatches, but tenant-by-tenant so any
        // created rows (fix mode) land in the right tenant.
        $allDrift = [];
        $fixed = 0;

        foreach (Tenant::query()->get() as $tenant) {
            $result = $context->runForTenant($tenant, fn () => $batches->reconcileQuantities((bool) $this->option('fix')));
            $allDrift = array_merge($allDrift, $result['drift']);
            $fixed += $result['fixed'];
        }

        $this->line('');

        foreach ($allDrift as $row) {
            $this->warn(sprintf(
                'Drift — branch #%d, %s: on hand %.4f vs lots %.4f (%.4f)',
                $row['branch_id'], $row['product'], $row['on_hand'], $row['lot_cover'], $row['drift'],
            ));
        }

        AuditLog::record('batches.reconciled', null, [
            'drift_count' => count($allDrift),
            'fixed_count' => $fixed,
            'fix_mode' => (bool) $this->option('fix'),
            'description' => count($allDrift) === 0
                ? 'Lot ledger and branch_stock are in agreement.'
                : ($this->option('fix') ? "Corrected {$fixed} drifted pair(s)." : 'Drift found — run with --fix to correct.'),
        ]);

        if (count($allDrift) === 0) {
            $this->info('Lot ledger and branch_stock are in agreement.');

            return self::SUCCESS;
        }

        if (! $this->option('fix')) {
            $this->error('Drift found — re-run with --fix to correct branch_stock from the lot ledger.');

            return self::FAILURE;
        }

        if ($fixed < count($allDrift)) {
            $this->error("Corrected {$fixed} of ".count($allDrift).' drifted pair(s).');

            return self::FAILURE;
        }

        $this->info("Corrected {$fixed} drifted pair(s).");

        return self::SUCCESS;
    }
}
