<?php

namespace App\Services\Graph;

use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

class GraphLogger
{
    public function logRequest(string $action, array $context = []): void
    {
        $payload = [
            'action' => $action,
            'method' => $context['method'] ?? null,
            'endpoint' => $context['endpoint'] ?? null,
            'full_path' => $context['full_path'] ?? null,
            'query' => $context['query'] ?? null,
            'tenant' => $context['tenant'] ?? null,
            'client_request_id' => $context['client_request_id'] ?? null,
        ];

        Log::info('graph.request', $this->filter($payload));
    }

    public function logResponse(string $action, GraphResponse $response, array $context = []): void
    {
        $payload = [
            'action' => $action,
            'status' => $response->status,
            'success' => $response->success,
            'warnings' => $response->warnings,
            'method' => $context['method'] ?? $response->meta['method'] ?? null,
            'endpoint' => $context['endpoint'] ?? $response->meta['path'] ?? null,
            'full_path' => $context['full_path'] ?? $response->meta['full_path'] ?? null,
            'tenant' => $context['tenant'] ?? $response->meta['tenant'] ?? null,
            'request_id' => $response->meta['request_id'] ?? null,
            'client_request_id' => $response->meta['client_request_id'] ?? null,
        ];

        if ($response->failed()) {
            $payload['error_code'] = $response->meta['error_code'] ?? $this->firstErrorField($response->errors, 'code');
            $payload['error_message'] = $response->meta['error_message'] ?? $this->firstErrorMessage($response->errors, $response->data);
            $payload['response_excerpt'] = $response->meta['body_excerpt'] ?? null;
        }

        Log::info('graph.response', $this->filter($payload));
    }

    private function firstErrorField(array $errors, string $key): ?string
    {
        foreach ($errors as $error) {
            if (is_array($error) && is_string($error[$key] ?? null)) {
                return $error[$key];
            }
        }

        return null;
    }

    private function firstErrorMessage(array $errors, array $data): ?string
    {
        $message = $data['error']['message'] ?? null;

        if (is_string($message) && $message !== '') {
            return $message;
        }

        foreach ($errors as $error) {
            if (is_array($error) && is_string($error['message'] ?? null)) {
                return $error['message'];
            }

            if (is_array($error) && is_string($error['error']['message'] ?? null)) {
                return $error['error']['message'];
            }

            if (is_string($error) && $error !== '') {
                return Str::limit($error, 500);
            }
        }

        return null;
    }

    private function filter(array $payload): array
    {
        return array_filter($payload, static fn ($value) => $value !== null && $value !== []);
    }
}
