<?php

namespace App\Jobs;

use App\Events\ServiceBookingConfirmedEvent;
use App\Facades\Settings;
use Carbon\Carbon;
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\Log;
use Illuminate\Support\Facades\Mail;
use Mtc\Crm\Traits\RetrievesCustomerId;
use Mtc\MercuryDataModels\Booking;
use Mtc\MercuryDataModels\BookingAvailability;

class ProcessIncomingBookingJob implements ShouldQueue
{
    use Dispatchable;
    use InteractsWithQueue;
    use Queueable;
    use SerializesModels;
    use RetrievesCustomerId;

    /**
     * Create a new job instance.
     */
    public function __construct(protected Booking $booking)
    {
        $this->onQueue('sync');
    }

    /**
     * Execute the job.
     */
    public function handle(): void
    {
        $this->booking->refresh();
        if (empty($this->booking->ingested_at) && $this->process()) {
            $this->booking->update([
                'ingested_at' => Carbon::now(),
                'customer_id' => $this->getCustomerId($this->booking->email, $this->getDetails()),
            ]);
        }
    }

    private function process(): bool
    {
        try {
            $confirmation_class = config('crm.new_booking_confirmation_email');
            if (!empty($this->booking->email) && filter_var($this->booking->email, FILTER_VALIDATE_EMAIL)) {
                Mail::to($this->booking->email)->send(new $confirmation_class($this->booking));
            }

            $class = config('crm.new_booking_email');

            collect($this->getRecipients())
                ->each(fn($recipient) => Mail::to($recipient)->send(new $class($this->booking)));

            ServiceBookingConfirmedEvent::dispatch($this->booking);
            return true;
        } catch (\Exception $exception) {
            Log::warning($exception->getMessage());
        }

        return false;
    }

    private function getDetails(): array
    {
        return [
            'phone_number' => $this->booking->phone_number,
            'first_name' => $this->booking->first_name,
            'last_name' => $this->booking->last_name,
        ];
    }

    private function getRecipients(): array
    {
        $recipients = [];

        $location = BookingAvailability::query()->where('dealership_id', $this->booking->location_id)->first();
        if ($location && $location->email) {
            $recipients = explode(',', (string) $location->email);
        }

        if (empty($recipients)) {
            $recipients[] = Settings::get('app-contact-contact_email');
        }
        return array_filter($recipients, fn($email) => $email && filter_var($email, FILTER_VALIDATE_EMAIL));
    }
}
