<?php

namespace App\Core\Services;

use App\Models\WhatsAppConfiguration;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;

/**
 * WhatsApp Service
 * Handles WhatsApp message sending through different providers
 */
class WhatsAppService
{
    protected $config;

    public function __construct()
    {
        $this->config = WhatsAppConfiguration::getActive();
    }

    /**
     * Send WhatsApp message
     */
    public function send(string $to, string $message, ?string $mediaUrl = null, ?string $mediaType = null): array
    {
        if (! $this->config) {
            return [
                'success' => false,
                'message' => 'WhatsApp configuration not found. Please configure WhatsApp settings first.',
            ];
        }

        $provider = $this->config->provider;

        try {
            return match ($provider) {
                'twilio' => $this->sendViaTwilio($to, $message, $mediaUrl, $mediaType),
                'whatsapp_business' => $this->sendViaWhatsAppBusiness($to, $message, $mediaUrl, $mediaType),
                '360dialog' => $this->sendVia360Dialog($to, $message, $mediaUrl, $mediaType),
                'custom' => $this->sendViaCustom($to, $message, $mediaUrl, $mediaType),
                default => [
                    'success' => false,
                    'message' => "Unsupported WhatsApp provider: {$provider}",
                ],
            };
        } catch (\Exception $e) {
            Log::error('WhatsApp sending failed: '.$e->getMessage());

            return [
                'success' => false,
                'message' => 'Failed to send WhatsApp message: '.$e->getMessage(),
            ];
        }
    }

    /**
     * Send WhatsApp message via Twilio
     */
    protected function sendViaTwilio(string $to, string $message, ?string $mediaUrl = null, ?string $mediaType = null): array
    {
        $accountSid = env('TWILIO_ACCOUNT_SID', $this->config->api_key);
        $authToken = env('TWILIO_AUTH_TOKEN', $this->config->api_secret);
        $from = env('TWILIO_WHATSAPP_FROM', $this->config->phone_number_id ?? 'whatsapp:+14155238886');

        if (! $accountSid || ! $authToken || ! $from) {
            return [
                'success' => false,
                'message' => 'Twilio WhatsApp credentials are not configured.',
            ];
        }

        // Ensure 'whatsapp:' prefix
        if (! str_starts_with($from, 'whatsapp:')) {
            $from = 'whatsapp:'.$from;
        }
        if (! str_starts_with($to, 'whatsapp:')) {
            $to = 'whatsapp:'.$to;
        }

        try {
            $payload = [
                'From' => $from,
                'To' => $to,
                'Body' => $message,
            ];

            if ($mediaUrl) {
                $payload['MediaUrl'] = [$mediaUrl];
            }

            $response = Http::withBasicAuth($accountSid, $authToken)
                ->asForm()
                ->post("https://api.twilio.com/2010-04-01/Accounts/{$accountSid}/Messages.json", $payload);

            if ($response->successful()) {
                return [
                    'success' => true,
                    'message' => 'WhatsApp message sent successfully',
                    'sid' => $response->json('sid'),
                ];
            }

            return [
                'success' => false,
                'message' => $response->json('message', 'Failed to send WhatsApp message'),
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => 'Twilio error: '.$e->getMessage(),
            ];
        }
    }

    /**
     * Send WhatsApp message via WhatsApp Business API
     */
    protected function sendViaWhatsAppBusiness(string $to, string $message, ?string $mediaUrl = null, ?string $mediaType = null): array
    {
        $phoneNumberId = env('WHATSAPP_PHONE_NUMBER_ID', $this->config->phone_number_id);
        $accessToken = env('WHATSAPP_ACCESS_TOKEN', $this->config->api_secret);
        $businessAccountId = env('WHATSAPP_BUSINESS_ACCOUNT_ID', $this->config->business_account_id);

        if (! $phoneNumberId || ! $accessToken) {
            return [
                'success' => false,
                'message' => 'WhatsApp Business API credentials are not configured.',
            ];
        }

        try {
            // Format phone number (remove + and spaces)
            $to = preg_replace('/[^0-9]/', '', $to);

            $payload = [
                'messaging_product' => 'whatsapp',
                'to' => $to,
                'type' => 'text',
                'text' => [
                    'body' => $message,
                ],
            ];

            // Add media if provided
            if ($mediaUrl) {
                $mediaType = $mediaType ?? 'document';
                $payload['type'] = $mediaType;

                if ($mediaType === 'document') {
                    $payload['document'] = [
                        'link' => $mediaUrl,
                        'caption' => $message,
                    ];
                    unset($payload['text']);
                } elseif ($mediaType === 'image') {
                    $payload['image'] = [
                        'link' => $mediaUrl,
                        'caption' => $message,
                    ];
                    unset($payload['text']);
                } else {
                    $payload[$mediaType] = [
                        'link' => $mediaUrl,
                    ];
                }
            }

            $response = Http::withToken($accessToken)
                ->post("https://graph.facebook.com/v18.0/{$phoneNumberId}/messages", $payload);

            if ($response->successful()) {
                return [
                    'success' => true,
                    'message' => 'WhatsApp message sent successfully',
                    'message_id' => $response->json('messages.0.id'),
                ];
            }

            $error = $response->json('error');
            $raw = $error['message'] ?? 'Failed to send WhatsApp message';

            if (is_string($raw) && (
                str_contains($raw, 'Session has expired')
                || str_contains($raw, 'Error validating access token')
                || str_contains($raw, 'OAuthException')
            )) {
                $raw .= ' Regenerate your Meta access token (Meta for Developers → your app → WhatsApp → API Setup, or Business Settings → System users) and save it again under Settings → WhatsApp / WHATSAPP_ACCESS_TOKEN.';
            }

            return [
                'success' => false,
                'message' => $raw,
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => 'WhatsApp Business API error: '.$e->getMessage(),
            ];
        }
    }

    /**
     * Send WhatsApp message via 360dialog
     */
    protected function sendVia360Dialog(string $to, string $message, ?string $mediaUrl = null, ?string $mediaType = null): array
    {
        $apiKey = env('360DIALOG_API_KEY', $this->config->api_key);
        $instanceId = env('360DIALOG_INSTANCE_ID', $this->config->phone_number_id);

        if (! $apiKey || ! $instanceId) {
            return [
                'success' => false,
                'message' => '360dialog credentials are not configured.',
            ];
        }

        try {
            // Format phone number
            $to = preg_replace('/[^0-9]/', '', $to);

            $payload = [
                'to' => $to,
                'text' => $message,
            ];

            if ($mediaUrl) {
                $payload['media'] = [
                    'url' => $mediaUrl,
                    'type' => $mediaType ?? 'document',
                ];
            }

            $response = Http::withHeaders([
                'D360-API-KEY' => $apiKey,
            ])->post('https://waba.360dialog.io/v1/messages', $payload);

            if ($response->successful()) {
                return [
                    'success' => true,
                    'message' => 'WhatsApp message sent successfully',
                    'message_id' => $response->json('messages.0.id'),
                ];
            }

            return [
                'success' => false,
                'message' => $response->json('error.message', 'Failed to send WhatsApp message'),
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => '360dialog error: '.$e->getMessage(),
            ];
        }
    }

    /**
     * Send WhatsApp message via Custom provider
     */
    protected function sendViaCustom(string $to, string $message, ?string $mediaUrl = null, ?string $mediaType = null): array
    {
        $config = $this->config->config ?? [];
        $apiUrl = $config['api_url'] ?? env('CUSTOM_WHATSAPP_API_URL');
        $apiKey = env('CUSTOM_WHATSAPP_API_KEY', $this->config->api_key);
        $apiSecret = env('CUSTOM_WHATSAPP_API_SECRET', $this->config->api_secret);

        if (! $apiUrl) {
            return [
                'success' => false,
                'message' => 'Custom WhatsApp API URL is not configured.',
            ];
        }

        try {
            $headers = [];
            if ($apiKey) {
                $headers['Authorization'] = "Bearer {$apiKey}";
            }

            $payload = array_merge([
                'to' => $to,
                'message' => $message,
            ], $config['payload'] ?? []);

            if ($mediaUrl) {
                $payload['media_url'] = $mediaUrl;
                $payload['media_type'] = $mediaType ?? 'document';
            }

            $response = Http::withHeaders($headers)->post($apiUrl, $payload);

            if ($response->successful()) {
                return [
                    'success' => true,
                    'message' => 'WhatsApp message sent successfully',
                ];
            }

            return [
                'success' => false,
                'message' => 'Failed to send WhatsApp message: '.$response->body(),
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => 'Custom WhatsApp error: '.$e->getMessage(),
            ];
        }
    }

    /**
     * Send document (PDF) via WhatsApp
     */
    public function sendDocument(string $to, string $documentPath, string $caption = ''): array
    {
        // Get full URL for the document
        if (filter_var($documentPath, FILTER_VALIDATE_URL)) {
            // Already a full URL
            $documentUrl = $documentPath;
        } else {
            // Get storage URL
            $documentUrl = Storage::disk('public')->url($documentPath);

            // If storage URL is relative, make it absolute
            if (! filter_var($documentUrl, FILTER_VALIDATE_URL)) {
                $documentUrl = url($documentUrl);
            }
        }

        return $this->send($to, $caption, $documentUrl, 'document');
    }
}
