<?php

namespace App\Services;

use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use Illuminate\Support\Facades\Log;

class AutoTraderAdvertisersApi
{
    protected AutoTraderApi $api;

    public function __construct()
    {
        $config = config('auto_trader_stock', []);
        $config['use_live_api'] = !$config['use_sandbox'];

        $this->api = new AutoTraderApi($config);
    }

    /**
     * Get list of all advertisers accessible by the API credentials
     */
    public function getAdvertisers(): array
    {
        try {
            $data = $this->api->get('advertisers?autotraderAdvertAllowances=true');

            return [
                'success' => true,
                'advertisers' => $data['results'] ?? [],
            ];
        } catch (ClientException $exception) {
            Log::error('Autotrader Advertisers API error', [
                'message' => $exception->getMessage(),
                'response' => (string) $exception->getResponse()->getBody(),
            ]);
            return [
                'success' => false,
                'error' => $this->parseErrorResponse($exception),
            ];
        } catch (\Exception $exception) {
            Log::error('Autotrader Advertisers API error', [
                'message' => $exception->getMessage(),
            ]);
            return [
                'success' => false,
                'error' => $exception->getMessage(),
            ];
        }
    }

    /**
     * Get details for a specific advertiser
     */
    public function getAdvertiser(string $advertiserId): array
    {
        try {
            $data = $this->api->get("advertisers?advertiserId={$advertiserId}&autotraderAdvertAllowances=true");

            return [
                'success' => true,
                'advertiser' => $data['results'][0],
            ];
        } catch (ClientException $exception) {
            $statusCode = $exception->getResponse()->getStatusCode();
            if ($statusCode === 403 || $statusCode === 404) {
                return [
                    'success' => false,
                    'error' => "No access to advertiser ID: {$advertiserId}",
                    'accessible' => false,
                ];
            }

            Log::error('Autotrader Advertiser API error', [
                'advertiser_id' => $advertiserId,
                'message' => $exception->getMessage(),
                'response' => (string) $exception->getResponse()->getBody(),
            ]);
            return [
                'success' => false,
                'error' => $this->parseErrorResponse($exception),
            ];
        } catch (\Exception $exception) {
            Log::error('Autotrader Advertiser API error', [
                'advertiser_id' => $advertiserId,
                'message' => $exception->getMessage(),
            ]);
            return [
                'success' => false,
                'error' => $exception->getMessage(),
            ];
        }
    }

    /**
     * Get details for multiple advertisers in a single API call
     *
     * @param  array<string>  $advertiserIds
     */
    public function getAdvertisersByIds(array $advertiserIds): array
    {
        if (empty($advertiserIds)) {
            return [
                'success' => true,
                'advertisers' => [],
            ];
        }

        $query = collect($advertiserIds)
            ->map(fn(string $id) => 'advertiserId=' . urlencode($id))
            ->implode('&');

        try {
            $data = $this->api->get("advertisers?{$query}&autotraderAdvertAllowances=true");

            return [
                'success' => true,
                'advertisers' => $data['results'] ?? [],
            ];
        } catch (ClientException $exception) {
            Log::error('Autotrader Advertisers API error', [
                'advertiser_ids' => $advertiserIds,
                'message' => $exception->getMessage(),
                'response' => (string) $exception->getResponse()->getBody(),
            ]);

            return [
                'success' => false,
                'error' => $this->parseErrorResponse($exception),
            ];
        } catch (\Exception $exception) {
            Log::error('Autotrader Advertisers API error', [
                'advertiser_ids' => $advertiserIds,
                'message' => $exception->getMessage(),
            ]);

            return [
                'success' => false,
                'error' => $exception->getMessage(),
            ];
        }
    }

    /**
     * Check if we have access to a specific advertiser ID
     */
    public function checkAccess(string $advertiserId): array
    {
        $result = $this->getAdvertiser($advertiserId);

        if ($result['success']) {
            return [
                'accessible' => true,
                'advertiser' => $result['advertiser'],
            ];
        }

        return [
            'accessible' => false,
            'error' => $result['error'] ?? 'Unknown error',
        ];
    }

    /**
     * Verify API credentials are valid
     */
    public function verifyCredentials(): array
    {
        try {
            $token = $this->api->accessToken();

            if ($token) {
                return [
                    'valid' => true,
                    'message' => 'API credentials are valid',
                ];
            }

            return [
                'valid' => false,
                'message' => 'Failed to authenticate with API credentials',
            ];
        } catch (\Exception $exception) {
            return [
                'valid' => false,
                'message' => $exception->getMessage(),
            ];
        }
    }

    /**
     * Parse error response from API
     */
    protected function parseErrorResponse(ClientException $exception): string
    {
        try {
            $body = json_decode((string) $exception->getResponse()->getBody(), true);
            return $body['message'] ?? $body['error'] ?? $exception->getMessage();
        } catch (\Exception $e) {
            return $exception->getMessage();
        }
    }
}
