<?php

namespace App\Modules\VehiclesInVideo\Services;

use App\Mail\VehiclesInVideoVideoNotFoundMail;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Mtc\Crm\Contracts\EnquiryModel;
use Mtc\MercuryDataModels\ApiNotification;
use Mtc\MercuryDataModels\Customer;
use Mtc\MercuryDataModels\Vehicle;

class VehiclesInVideoService
{
    public const STATUS_SENT = 'sent';
    public const STATUS_FAILED = 'failed';
    public const STATUS_NOT_FOUND = 'not_found';

    private const PROVIDER = 'vehicles-in-video';

    public function __construct(
        private readonly VehiclesInVideoApiService $api,
        private readonly TokenService $tokenService,
    ) {
    }

    public function sendFromEnquiry(EnquiryModel $enquiry): ?string
    {
        $vehicle = $enquiry->reason;

        if (!$vehicle instanceof Vehicle) {
            Log::error('VehiclesInVideo: Enquiry is not linked to a vehicle', [
                'enquiry_id' => $enquiry->id,
                'reason_type' => $enquiry->reason_type,
            ]);
            return null;
        }

        [$customerName, $customerPhone] = $this->extractCustomerDetails($enquiry);

        return $this->send(
            $vehicle,
            $customerName,
            $enquiry->email,
            $customerPhone,
            $enquiry->id,
        );
    }

    private function send(
        Vehicle $vehicle,
        string $customerName,
        ?string $customerEmail,
        ?string $customerPhone,
        ?int $enquiryId = null
    ): ?string {
        if (empty($customerEmail)) {
            Log::error('VehiclesInVideo: No customer email available', [
                'enquiry_id' => $enquiryId,
                'vehicle_id' => $vehicle->id,
            ]);
            return null;
        }

        $authToken = $this->tokenService->getValidAuthToken();

        if (!$authToken) {
            Log::error('VehiclesInVideo: No valid auth token available');
            return null;
        }

        $payload = [
            'customer_name' => $customerName,
            'customer_email' => $customerEmail,
            'instant_send' => true,
            'reference' => $vehicle->registration_number,
        ];

        if ($customerPhone) {
            $payload['customer_phone'] = $this->formatPhoneNumber($customerPhone);
        }

        if ($enquiryId) {
            $payload['meta'] = ['leadId' => (string) $enquiryId];
        }

        $apiResult = $this->api->sendVideo($authToken, $payload);
        $statusCode = $apiResult['status_code'] ?? 0;

        $status = match (true) {
            $statusCode === 200 => self::STATUS_SENT,
            $statusCode === 404 => self::STATUS_NOT_FOUND,
            default => self::STATUS_FAILED,
        };

        ApiNotification::create([
            'provider' => self::PROVIDER,
            'data_model' => 'vehicle',
            'reference' => $vehicle->registration_number,
            'processed' => true,
            'data' => [
                'status' => $status,
                'enquiry_id' => $enquiryId,
                'customer' => [
                    'name' => $customerName,
                    'email' => $customerEmail,
                    'phone' => $customerPhone,
                ],
                'request' => $payload,
                'response' => $apiResult,
            ],
        ]);

        if ($status === self::STATUS_NOT_FOUND) {
            $this->notifyVideoNotFound(
                $vehicle,
                $customerName,
                $customerEmail,
                $customerPhone,
                now(),
            );
        } elseif ($status === self::STATUS_FAILED) {
            Log::error('VehiclesInVideo: Failed to send video', [
                'status_code' => $statusCode,
                'response' => $apiResult,
            ]);
        }

        return $status;
    }

    private function extractCustomerDetails(EnquiryModel $enquiry): array
    {
        $name = '';
        $phone = null;

        if ($enquiry->customer_id) {
            $customer = Customer::find($enquiry->customer_id);
            if ($customer) {
                $name = trim(($customer->first_name ?? '') . ' ' . ($customer->last_name ?? ''));
                $phone = $customer->phone_number;
            }
        }

        if ($name === '') {
            $name = 'Customer';
        }

        return [$name, $phone];
    }

    private function formatPhoneNumber(string $phone): string
    {
        $phone = preg_replace('/[^0-9+]/', '', $phone);

        if (str_starts_with($phone, '0')) {
            return '+44' . substr($phone, 1);
        }

        if (!str_starts_with($phone, '+')) {
            return '+44' . $phone;
        }

        return $phone;
    }

    private function notifyVideoNotFound(
        Vehicle $vehicle,
        string $customerName,
        ?string $customerEmail,
        ?string $customerPhone,
        Carbon $createdAt
    ): void {
        $recipients = $this->notificationRecipients();

        if (empty($recipients)) {
            Log::warning('VehiclesInVideo: No notification recipients configured for video-not-found alert');
            return;
        }

        try {
            Mail::to($recipients)->send(new VehiclesInVideoVideoNotFoundMail(
                $vehicle,
                $customerName,
                $customerEmail,
                $customerPhone,
                $createdAt,
            ));
        } catch (\Throwable $e) {
            Log::error('VehiclesInVideo: Failed to send notification email', [
                'exception' => $e->getMessage(),
            ]);
        }
    }

    private function notificationRecipients(): array
    {
        $value = \App\Facades\Settings::get('vehicles-in-video-notification-recipients');
        if (empty($value)) {
            return [];
        }

        return array_values(array_filter(array_map('trim', explode(',', $value))));
    }
}
