<?php

namespace App\Console\Commands;

use App\Services\Graph\GraphClientInterface;
use App\Services\Graph\GraphContractRegistry;
use Illuminate\Console\Command;

class GraphContractCheck extends Command
{
    protected $signature = 'graph:contract:check {--tenant=}';

    protected $description = 'Validate Graph contract registry against live endpoints (lightweight probes)';

    public function handle(GraphClientInterface $graph, GraphContractRegistry $registry): int
    {
        $contracts = config('graph_contracts.types', []);

        if (empty($contracts)) {
            $this->warn('No graph contracts configured.');

            return self::SUCCESS;
        }

        $tenant = $this->option('tenant');
        $failures = 0;

        foreach ($contracts as $type => $contract) {
            $resource = $contract['resource'] ?? null;
            $select = $contract['allowed_select'] ?? [];
            $expand = $contract['allowed_expand'] ?? [];

            if (! $resource) {
                $this->error("[$type] missing resource path");
                $failures++;

                continue;
            }

            $queryInput = array_filter([
                '$top' => 1,
                '$select' => $select,
                '$expand' => $expand,
            ], static fn ($value): bool => $value !== null && $value !== '' && $value !== []);

            $query = $registry->sanitizeQuery($type, $queryInput)['query'];

            $response = $graph->request('GET', $resource, [
                'query' => $query,
                'tenant' => $tenant,
            ]);

            if ($response->failed()) {
                $code = $response->meta['error_code'] ?? $response->status;
                $message = $response->meta['error_message'] ?? ($response->errors[0]['message'] ?? $response->errors[0] ?? 'unknown');
                $this->error("[$type] drift or capability issue ({$code}): {$message}");
                $failures++;

                continue;
            }

            if (! empty($response->warnings)) {
                $this->warn("[$type] completed with warnings: ".implode('; ', $response->warnings));
            } else {
                $this->info("[$type] OK");
            }
        }

        return $failures > 0 ? self::FAILURE : self::SUCCESS;
    }
}
