<?php

namespace App\Services;

use App\Crm\Config\WebLeadsConfig;
use App\Crm\EnquiryDataToProviderData;
use Carbon\Carbon;
use Illuminate\Http\Client\Response;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
use Mtc\Crm\Contracts\EnquiryActionModel;
use Mtc\Crm\Contracts\EnquiryModel;
use Mtc\MercuryDataModels\ApiNotification;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\VehicleValuation\Models\VehicleValuation;

class WebLeadsApi
{
    use EnquiryDataToProviderData;

    private Response $response;

    public function __construct(protected readonly WebLeadsConfig $config)
    {
        //
    }

    public function getResponseAttribute(string $attribute): mixed
    {
        return $this->response->json($attribute);
    }

    public function getResponseMessage(): string
    {
        return $this->response->json('message') ?? '';
    }

    public function sendLead(EnquiryModel $enquiry, EnquiryActionModel $action): bool
    {
        return $this->submitLead($this->mapEnquiry($enquiry));
    }

    protected function mapEnquiry(EnquiryModel $enquiry): array
    {
        $params = $this->convertEnquiryToParams($enquiry, 'webleads-field');

        $dynamicSource = $params['source'] ?? null;
        unset($params['source']);

        foreach ($enquiry->objects as $object) {
            if ($object->object_type === 'vehicle' && $object->object) {
                $params['vehicle'] = $this->mapVehicle($object->object);
            }

            if ($object->object_type === 'valuation' && $object->object) {
                $params['valuation'] = $this->mapValuation($object->object);
            }
        }

        if (empty($params['preferredContactMethods'])) {
            $methods = [];
        } elseif (is_string($params['preferredContactMethods'])) {
            $methods = array_fill_keys(explode(',', strtolower($params['preferredContactMethods'])), true);
        } elseif (is_array($params['preferredContactMethods'])) {
            $methods = array_fill_keys(array_map(strtolower(...), $params['preferredContactMethods']), true);
        }

        $notes = $this->mapNotes($params);

        $data = [
            'enquiry' => [
                'apikey' => $this->config->apiKey(),
                'lead' => [
                    'origin' => $enquiry->form?->name ?? '',
                    'source' => $this->getEnquirySource($enquiry, $dynamicSource),
                    'branch' => $params['vehicle']['branch_id'] ?? $this->config->fallbackDealerId(),
                    'idnumber' => $enquiry->id,
                ],
                'contact' => [
                    'firstname' => $params['firstname'] ?? '',
                    'surname' => $params['surname'] ?? '',
                    'email' => $params['email'] ?? '',
                    'phone' => $params['phone'] ?? '',
                    'mobile' => $params['mobile'] ?? '',
                    'source' => 'WEB',
                ],
                'seeks' => [
                    'newused' => $params['vehicle']['new_used'] ?? '',
                    'make' => $params['vehicle']['make'] ?? '',
                    'model' => $params['vehicle']['model'] ?? '',
                    'stocknumber' => $params['vehicle']['uuid'] ?? '',
                    'regnumber' => $params['vehicle']['vrm'] ?? '',
                    'notes' => $notes ?? '',
                ],
                'tradein' => [
                    'registration' => $params['valuation']['registration'] ?? '',
                    'make' => $params['valuation']['make'] ?? '',
                    'model' => $params['valuation']['model'] ?? '',
                    'mileage' => $params['valuation']['mileage'] ?? '',
                    'year' => $params['valuation']['year'] ?? '',
                    'notes' => $notes ?? '',
                ],
            ],
            'mkagree' => [
                'updatemkagree' => 'agree-to-marketing',

                'dealersms' => $methods['sms'] ?? null,
                'dealeremail' => $methods['email'] ?? null,
                'dealerletter' => $methods['post'] ?? null,
                'dealerphone' => $methods['phone'] ?? null,

                'partssms' => $methods['sms'] ?? null,
                'partsemail' => $methods['email'] ?? null,
                'partsletter' => $methods['post'] ?? null,
                'partsphone' => $methods['phone'] ?? null,

                'salessms' => $methods['sms'] ?? null,
                'salesemail' => $methods['email'] ?? null,
                'salesletter' => $methods['post'] ?? null,
                'salesphone' => $methods['phone'] ?? null,

                'servicesms' => $methods['sms'] ?? null,
                'serviceemail' => $methods['email'] ?? null,
                'serviceletter' => $methods['post'] ?? null,
                'servicephone' => $methods['phone'] ?? null,
            ],
        ];

        return $data;
    }

    protected function mapVehicle(Vehicle $vehicle): array
    {
        return [
            'make' => $vehicle->make?->name,
            'model' => $vehicle->model?->name,
            'vrm' => $vehicle->vrm_condensed,
            'uuid' => $vehicle->uuid,
            'new_used' => $vehicle->is_new ? 'New' : 'Used',
            'branch_id' => $vehicle->dealership?->data['webleads-dealer-id'] ?? null,
        ];
    }

    protected function mapValuation(VehicleValuation $valuation): array
    {
        return [
            'registration' => $valuation->registration ?? '',
            'make' => $valuation->make ?? '',
            'model' => $valuation->model ?? '',
            'mileage' => $valuation->mileage ?? '',
            'year' => $valuation->date_of_registration
                ? Carbon::parse($valuation->date_of_registration)->format('Y')
                : '',
        ];
    }

    protected function submitLead(array $leadData): bool
    {
        $endpoint = $this->endpoint();
        $this->response = Http::withOptions(['verify' => false])->post($endpoint, $leadData);

        ApiNotification::query()->create([
            'provider' => 'webleads',
            'processed' => $this->response->successful(),
            'headers' => null,
            'data' => [
                'request' => $leadData,
                'result' => $this->response->body(),
                'endpoint' => $endpoint,
            ],
            'data_model' => WebLeadsApi::class,
        ]);

        return $this->response->successful();
    }

    private function endpoint(): string
    {
        return rtrim($this->config->apiDomain(), '/')
            . '/tramo/leads-v1/generic.json?SoapAction=InboundEnquiry&ContentType=application/json';
    }

    private function getEnquirySource(EnquiryModel $enquiry, ?string $dynamicSource = null): string
    {
        if (!empty($dynamicSource)) {
            return strtoupper($dynamicSource);
        }

        if (empty($enquiry->type?->data['webleads_form_type'])) {
            return 'GEN';
        }

        return strtoupper($enquiry->type?->data['webleads_form_type']);
    }

    private function mapNotes(array $params = []): string
    {
        $notes = '';

        collect($params)
            ->filter(fn ($value, $key) => Str::startsWith($key, ['address.', 'vehicle.', 'description']))
            ->each(function ($value, $key) use (&$notes) {
                $key_to_use = Str::replace(['address.', 'vehicle.'], '', $key);
                $notes .= $key_to_use . ': ' . $value . '. ';
            });

        return trim($notes);
    }
}
