<?php

namespace App\Services;

use App\Jobs\SendOrderPlacementNotificationsJob;
use App\Models\Order;
use App\Models\Setting;
use App\Models\SmsTemplate;
use App\Models\User;
use App\Models\WhatsappTemplates;
use App\Utility\SmsUtility;
use App\Utility\WhatsappUtility;
use Illuminate\Support\Facades\Log;
use PDF;

class OrderPlacementNotificationService
{
    public const CHANNEL_POS = 'pos';

    public const CHANNEL_ONLINE = 'online';

    public function __construct(
        protected InvoiceLinkService $invoiceLinkService
    ) {
    }

    public function dispatchAfterPlacement(Order $order, string $channel): void
    {
        if (!in_array($channel, [self::CHANNEL_POS, self::CHANNEL_ONLINE], true)) {
            return;
        }

        SendOrderPlacementNotificationsJob::dispatch(
            $order->id,
            $channel,
            $order->staff_id
        )->afterResponse();
    }

    public function sendPlacementNotifications(int $orderId, string $channel, ?int $staffId = null): void
    {
        $order = Order::with(['user', 'staff', 'items'])->find($orderId);
        if (!$order || !$order->user) {
            return;
        }

        $templateId = $channel === self::CHANNEL_POS ? 'pos_order_placement' : 'order_placement';
        $senderName = $this->resolveSenderName($order, $channel, $staffId);

        try {
            $this->sendWhatsAppInvoicePdf($order, $templateId, $senderName);
        } catch (\Throwable $e) {
            Log::error('WhatsApp PDF sending failed: ' . $e->getMessage(), [
                'order_id' => $orderId,
                'channel' => $channel,
            ]);
        }

        try {
            $invoiceLink = $this->resolveInvoiceShortLink($order, $templateId);
            $this->sendSmsOrderPlacement($order, $templateId, $invoiceLink);
        } catch (\Throwable $e) {
            Log::error('SMS order placement sending failed: ' . $e->getMessage(), [
                'order_id' => $orderId,
                'channel' => $channel,
            ]);
        }
    }

    protected function resolveSenderName(Order $order, string $channel, ?int $staffId): string
    {
        $siteName = ucwords((string) Setting::get('site_name', env('APP_NAME', 'KiyoKart')));

        if ($channel === self::CHANNEL_POS) {
            if ($order->staff?->name) {
                return $order->staff->name;
            }
            if ($staffId) {
                $staff = User::find($staffId);

                return $staff?->name ?: $siteName;
            }

            return $siteName;
        }

        return $order->user?->name ?: 'Website';
    }

    protected function resolveInvoiceShortLink(Order $order, string $templateId): ?string
    {
        $smsActive = SmsTemplate::where('identifier', $templateId)
            ->where('is_active', true)
            ->exists();

        if (!$smsActive) {
            return null;
        }

        return $this->invoiceLinkService->shortUrlForSms($order);
    }

    /**
     * @return string|null Public PDF URL when WhatsApp was sent
     */
    protected function sendWhatsAppInvoicePdf(Order $order, string $templateId, string $senderName): ?string
    {
        $whatsappTemplate = WhatsappTemplates::where('identifier', $templateId)->first();

        if (!$whatsappTemplate || (int) $whatsappTemplate->is_active !== 1) {
            return null;
        }

        $customer = $order->user;
        if (!$customer || $customer->mobile === '9999999999' || empty($customer->mobile)) {
            return null;
        }

        $pdf = PDF::loadView('admin.orders.thermal_invoice', [
            'order' => $order,
        ]);

        $pdfDir = public_path('storage/invoices');
        if (!is_dir($pdfDir)) {
            mkdir($pdfDir, 0755, true);
        }

        $pdfPath = $pdfDir . DIRECTORY_SEPARATOR . 'order-' . $order->id . '.pdf';
        $pdf->save($pdfPath);

        $pdfUrl = asset('storage/invoices/order-' . $order->id . '.pdf');

        if ($templateId === 'pos_order_placement') {
            WhatsappUtility::pos_order_placement($customer, $order, $pdfUrl, null, $senderName);
            $this->sendPosOwnerWhatsAppCopy($customer, $order, $pdfUrl, $senderName);
        } else {
            WhatsappUtility::order_placement($customer, $order, $pdfUrl, $senderName);
        }

        return $pdfUrl;
    }

    protected function sendPosOwnerWhatsAppCopy(User $customer, Order $order, string $pdfUrl, string $senderName): void
    {
        $ownerCopyEnabled = Setting::get('whatsapp_pos_owner_copy_enabled', '0') === '1';
        if (!$ownerCopyEnabled || ($customer->customer_type ?? 'retail') !== 'wholesale') {
            return;
        }

        $ownerMobile = $this->extractPrimaryMobile((string) Setting::get('site_phone', ''));
        if ($ownerMobile === '' || $this->normalizeMobileForCompare($ownerMobile) === $this->normalizeMobileForCompare((string) $customer->mobile)) {
            return;
        }

        WhatsappUtility::pos_order_placement($customer, $order, $pdfUrl, $ownerMobile, $senderName);
    }

    protected function sendSmsOrderPlacement(Order $order, string $templateId, ?string $invoiceLink): void
    {
        if (!$invoiceLink) {
            return;
        }

        $smsTemplate = SmsTemplate::where('identifier', $templateId)
            ->where('is_active', true)
            ->first();

        if (!$smsTemplate) {
            return;
        }

        $customer = $order->user;
        if (!$customer || $customer->mobile === '9999999999' || empty($customer->mobile)) {
            return;
        }

        if ($templateId === 'pos_order_placement') {
            SmsUtility::pos_order_placement($customer, $order, $invoiceLink);
            $this->sendPosOwnerSmsCopy($customer, $order, $invoiceLink);
        } else {
            SmsUtility::order_placement($customer, $order, $invoiceLink);
        }
    }

    protected function sendPosOwnerSmsCopy(User $customer, Order $order, string $invoiceLink): void
    {
        $ownerCopyEnabled = Setting::get('sms_pos_owner_copy_enabled', '0') === '1';
        if (!$ownerCopyEnabled || ($customer->customer_type ?? 'retail') !== 'wholesale') {
            return;
        }

        $ownerMobile = $this->extractPrimaryMobile((string) Setting::get('site_phone', ''));
        if ($ownerMobile === '' || $this->normalizeMobileForCompare($ownerMobile) === $this->normalizeMobileForCompare((string) $customer->mobile)) {
            return;
        }

        SmsUtility::pos_order_placement($customer, $order, $invoiceLink, $ownerMobile);
    }

    protected function extractPrimaryMobile(string $raw): string
    {
        if ($raw === '') {
            return '';
        }

        preg_match_all('/\+?\d{10,15}/', $raw, $matches);
        $numbers = $matches[0] ?? [];
        if (empty($numbers)) {
            return '';
        }

        return trim((string) $numbers[0]);
    }

    protected function normalizeMobileForCompare(string $mobile): string
    {
        $digits = preg_replace('/\D+/', '', $mobile) ?: '';
        if (strlen($digits) > 10) {
            return substr($digits, -10);
        }

        return $digits;
    }
}
