<?php

namespace App\Jobs;

use App\Traits\EnsuresVehicleAttribute;
use App\Facades\Settings;
use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Http;
use Mtc\MercuryDataModels\ApiNotification;
use Mtc\MercuryDataModels\SalesChannelHistory;
use App\Exports\AutowebExport;
use Illuminate\Http\Client\Response;
use Mtc\MercuryDataModels\Vehicle;

class AutowebExportJob implements ShouldQueue
{
    use Dispatchable;
    use InteractsWithQueue;
    use Queueable;
    use SerializesModels;
    use EnsuresVehicleAttribute;

    private string $apiKey;
    private string $sellerId;
    private array $vehicleAttributes;

    public $timeout = 0;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->onQueue('export');
        $this->apiKey = Settings::get('sales-channels-autoweb-api-key', '');
        $this->sellerId = Settings::get('sales-channels-autoweb-seller-id', '');

        $this->vehicleAttributes = [
            'autoweb_id' => $this->getVehicleAttribute('Autoweb ID', 'text')->toArray(),
        ];
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        try {
            $export = new AutowebExport();
            $exported = $export->collection()->filter($this->exportVehicle(...));

            $this->removeOld();

            SalesChannelHistory::store(
                'autoweb',
                true,
                $exported->count() . ' records exported',
                null,
                $exported->map(fn ($row) => [
                    'uuid' => $row['vehicle']['externalVehicleId'],
                    'vrm' => $row['vehicle']['registration'],
                    'price' => $row['vehicle']['price'],
                    'image count' => count($row['media']['images'] ?? [])
                ])->toArray()
            );
        } catch (Exception $exception) {
            SalesChannelHistory::store('autoweb', false, $exception->getMessage());
        }
    }

    private function exportVehicle($vehicle): bool
    {
        $vehicleModel = Vehicle::query()
            ->with('dealership')
            ->where('uuid', $vehicle['vehicle']['externalVehicleId'])
            ->first();

        try {
            $sellerId = $vehicleModel->dealership?->data['autoweb-dealer-id'] ?? $this->sellerId;
            $apiKey = $vehicleModel->dealership?->data['autoweb-api-key'] ?? $this->apiKey;

            if (empty($sellerId)) {
                return false;
            }


            $response = Http::withHeaders($this->getHeaders($apiKey))
                ->post(config('services.autoweb.endpoint') . '/rest/vehicles?sellerId=' . $sellerId, $vehicle)
                ->onError(function (Response $response) use ($vehicleModel) {
                    ApiNotification::query()
                        ->create([
                            'provider' => 'autoweb',
                            'data' => $response->body(),
                            'data_model' => 'vehicle',
                            'reference' => $vehicleModel->id,
                        ]);
                });

            if ($response['success']) {
                $this->syncVehicleAttribute($vehicleModel, 'autoweb_id', $response['vehicleId']);
            } else {
                ApiNotification::query()
                    ->create([
                        'provider' => 'autoweb',
                        'data' => $response['message'],
                        'data_model' => 'vehicle',
                        'reference' => $vehicleModel->id,
                    ]);
            }
            return true;
        } catch (\Exception $exception) {
            ApiNotification::query()
                ->create([
                    'provider' => 'autoweb',
                    'data' => $exception->getMessage(),
                    'data_model' => 'vehicle',
                    'reference' => $vehicleModel->id,
                ]);
            return false;
        }
    }

    private function removeOld()
    {
        $attributeSlug = $this->vehicleAttributes['autoweb_id']['slug'];
        $vehicles = Vehicle::query()
            ->onlyTrashed()
            ->whereHas('attributeValues', function ($query) use ($attributeSlug) {
                $query->where('slug', $attributeSlug);
            })
            ->get();

        $vehicles->each(function ($vehicle) use ($attributeSlug) {
            try {
                $autowebId = $vehicle->getCustom('autoweb_id');
                $deleteUrl = config('services.autoweb.endpoint') . '/rest/vehicles/' . $autowebId;
                $apiKey = $vehicle->dealership?->data['autoweb-api-key'] ?? $this->apiKey;
                $response = Http::withHeaders($this->getHeaders($apiKey))
                    ->delete($deleteUrl);

                if ($response->json('success')) {
                    $vehicle->attributeValues
                        ->where('slug', $attributeSlug)
                        ->first()
                        ->delete();
                }
            } catch (\Exception $exception) {
                ApiNotification::query()
                    ->create([
                        'provider' => 'autoweb',
                        'data' => $exception->getMessage(),
                        'data_model' => 'vehicle',
                        'reference' => $vehicle->id,
                    ]);
            }
        });
    }

    /**
     * Get API request headers
     *
     * @return \string[][]
     */
    protected function getHeaders($apiKey): array
    {
        return [
            'Authorization' => 'Bearer ' . $apiKey
        ];
    }
}
