<?php

namespace Modules\ClinicCore\Services;

use App\Contact;
use Illuminate\Support\Facades\Mail;

/**
 * Item #3 — Send Message (WA / SMS / Email) feature for pet owners.
 *
 * Returns which channels are actually usable for a given contact, then
 * dispatches the message through the best available transport:
 *
 *   - WA  : Modules\WhatsApp\Entities\Services\WaSender if installed,
 *           else wa.me URI fallback so the user opens their own client.
 *   - SMS : Essentials notification util if it exposes sendSms(),
 *           else sms: URI fallback (works on mobile devices).
 *   - Email: Laravel Mail with a tiny inline template, always works
 *           when the contact has an email column.
 *
 * Channel buttons in the modal are hidden when their channel returns
 * false from availableChannels(), so a clinic without WhatsApp module
 * installed simply doesn't see the WA option.
 */
class OwnerMessagingService
{
    /** Detects what's installed in this app — cached per request. */
    private static $whatsappModulePresent;
    private static $smsTransportPresent;

    /**
     * Returns ['wa' => bool, 'sms' => bool, 'email' => bool] for a contact.
     */
    public function availableChannels(?Contact $contact): array
    {
        if (!$contact) return ['wa' => false, 'sms' => false, 'email' => false];

        $waInstalled  = $this->isWhatsappModulePresent();
        $smsInstalled = $this->isSmsTransportPresent();

        // WA: needs mobile + module installed + not explicitly marked no-WA.
        // clc_has_whatsapp NULL = unknown = still try; 1 = yes; 0 = no.
        $waOk = $waInstalled
             && !empty($contact->mobile)
             && ($contact->clc_has_whatsapp ?? null) !== 0;

        // SMS: mobile present + a transport available. We don't gate on
        // clc_has_whatsapp here - SMS works regardless.
        $smsOk = !empty($contact->mobile) && $smsInstalled;

        // Email: just needs an email address.
        $emailOk = !empty($contact->email);

        return ['wa' => $waOk, 'sms' => $smsOk, 'email' => $emailOk];
    }

    /** Send via WhatsApp module. Returns ['success' => bool, 'msg' => string]. */
    public function sendWhatsapp(Contact $contact, int $businessId, string $body, ?int $userId): array
    {
        if (!$this->isWhatsappModulePresent()) {
            return ['success' => false, 'msg' => 'WhatsApp module is not installed.'];
        }
        if (empty($contact->mobile)) {
            return ['success' => false, 'msg' => 'Owner has no mobile number on file.'];
        }
        try {
            $sender = app(\Modules\WhatsApp\Entities\Services\WaSender::class);
            $msg = $sender->send([
                'business_id' => $businessId,
                'to'          => $contact->mobile,
                'body'        => $body,
                'source'      => 'clc_owner_message',
                'created_by'  => $userId,
            ]);
            if ($msg === null) {
                return ['success' => false, 'msg' => 'WhatsApp is disabled or this number opted out.'];
            }
            return ['success' => true, 'msg' => 'WhatsApp message queued.'];
        } catch (\Throwable $e) {
            \Log::warning('ClinicCore WA send failed: ' . $e->getMessage());
            return ['success' => false, 'msg' => 'WhatsApp send failed: ' . $e->getMessage()];
        }
    }

    /** Send via SMS transport. */
    public function sendSms(Contact $contact, int $businessId, string $body): array
    {
        if (empty($contact->mobile)) {
            return ['success' => false, 'msg' => 'Owner has no mobile number on file.'];
        }
        if (!$this->isSmsTransportPresent()) {
            // Return the sms: URI so the frontend opens the user's SMS app.
            return [
                'success' => true,
                'msg'     => 'Opening SMS app',
                'open_uri'=> 'sms:' . $contact->mobile . '?body=' . rawurlencode($body),
            ];
        }
        try {
            // The UltimatePOS NotificationUtil exposes a generic sendSms()
            // that picks up the clinic's configured SMS gateway settings.
            $util = app(\App\Utils\NotificationUtil::class);
            if (method_exists($util, 'sendSms')) {
                $util->sendSms([
                    'sms_body' => $body,
                    'mobile_number' => $contact->mobile,
                    'business_id'   => $businessId,
                ]);
                return ['success' => true, 'msg' => 'SMS dispatched.'];
            }
            return [
                'success' => true,
                'msg'     => 'Opening SMS app',
                'open_uri'=> 'sms:' . $contact->mobile . '?body=' . rawurlencode($body),
            ];
        } catch (\Throwable $e) {
            \Log::warning('ClinicCore SMS send failed: ' . $e->getMessage());
            return ['success' => false, 'msg' => 'SMS send failed: ' . $e->getMessage()];
        }
    }

    /** Send via email (always available when address present). */
    public function sendEmail(Contact $contact, int $businessId, string $body, ?string $subject = null): array
    {
        if (empty($contact->email)) {
            return ['success' => false, 'msg' => 'Owner has no email address on file.'];
        }
        try {
            $clinicName = session('business.name', config('app.name', 'Clinic'));
            $subject    = $subject ?: ('Message from ' . $clinicName);
            Mail::raw($body, function ($m) use ($contact, $subject) {
                $m->to($contact->email)->subject($subject);
            });
            return ['success' => true, 'msg' => 'Email sent.'];
        } catch (\Throwable $e) {
            \Log::warning('ClinicCore email send failed: ' . $e->getMessage());
            return ['success' => false, 'msg' => 'Email send failed: ' . $e->getMessage()];
        }
    }

    private function isWhatsappModulePresent(): bool
    {
        if (self::$whatsappModulePresent !== null) return self::$whatsappModulePresent;
        return self::$whatsappModulePresent = class_exists(\Modules\WhatsApp\Entities\Services\WaSender::class);
    }

    private function isSmsTransportPresent(): bool
    {
        if (self::$smsTransportPresent !== null) return self::$smsTransportPresent;
        // Best-effort detection: UltimatePOS NotificationUtil ships with
        // sendSms(); presence of the method is the gate.
        try {
            $util = app(\App\Utils\NotificationUtil::class);
            return self::$smsTransportPresent = method_exists($util, 'sendSms');
        } catch (\Throwable $e) {
            return self::$smsTransportPresent = false;
        }
    }
}
