<?php

use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;

/**
 * Get conversations from the /merchants/conversations endpoint
 */
function getApiConversations(array $params = []): array
{
    try {
        $response = getHttpClient(true)->get(config('app.api_url').'/merchants/conversations', $params);

        if (! $response->successful() && $response->status() == 401) {
            Auth::logout();
            session()->invalidate();
            session()->regenerateToken();

            return ['success' => false, 'message' => 'Session expirée', 'status' => 401, 'is_connection_error' => false];
        }

        if ($response->successful()) {
            $responseData = $response->json();

            return [
                'success' => true,
                'data' => $responseData,
                'message' => $responseData['message'] ?? 'Conversations récupérées avec succès',
                'status' => 200,
                'is_connection_error' => false,
            ];
        }

        $errorData = $response->json();
        $errorMessage = $errorData['message'] ?? 'Échec de la récupération des conversations';

        return [
            'success' => false,
            'message' => $errorMessage,
            'status' => $response->status(),
            'is_connection_error' => false,
        ];
    } catch (\Illuminate\Http\Client\ConnectionException $e) {
        Log::error('API conversations connection exception', [
            'params' => $params,
            'error' => $e->getMessage(),
        ]);

        return [
            'success' => false,
            'message' => 'Impossible de se connecter au serveur. Vérifiez votre connexion internet.',
            'status' => 0,
            'is_connection_error' => true,
        ];
    } catch (\Exception $e) {
        Log::error('API conversations fetch exception', [
            'params' => $params,
            'error' => $e->getMessage(),
            'type' => get_class($e),
        ]);

        ['message' => $friendlyMessage, 'status' => $status] = extractApiExceptionMessage($e);

        $isConnectionError = $e instanceof \Illuminate\Http\Client\ConnectionException
            || str_contains($e->getMessage(), 'Connection')
            || str_contains($e->getMessage(), 'timeout')
            || str_contains($e->getMessage(), 'resolve host');

        return [
            'success' => false,
            'message' => $friendlyMessage,
            'status' => $status,
            'is_connection_error' => $isConnectionError,
        ];
    }
}

/**
 * Sync conversations from API to local database
 */
function getAndSyncConversations(array $params = []): array
{
    try {
        $apiResponse = getApiConversations($params);
        if (! $apiResponse['success']) {
            $isConnectionError = $apiResponse['is_connection_error'] ?? false;

            Log::warning('API conversations fetch failed', [
                'error' => $apiResponse['message'],
                'status' => $apiResponse['status'] ?? null,
                'is_connection_error' => $isConnectionError,
                'params' => $params,
            ]);

            return [
                'success' => false,
                'data' => new \Illuminate\Pagination\LengthAwarePaginator([], 0, $params['per_page'] ?? 15, $params['page'] ?? 1, [
                    'path' => request()->url(),
                    'query' => request()->query(),
                ]),
                'offline_mode' => $isConnectionError,
                'message' => $apiResponse['message'] ?? 'Impossible de récupérer les conversations.',
            ];
        }

        $apiData = $apiResponse['data'] ?? [];
        $conversationsList = $apiData['conversations'] ?? $apiData['data'] ?? $apiData;

        if (is_array($conversationsList) && isset($conversationsList['data'])) {
            $conversationsList = $conversationsList['data'];
        }

        if (! is_array($conversationsList)) {
            $conversationsList = [];
        }

        $transformedConversations = [];
        $syncedCount = 0;

        foreach ($conversationsList as $conversation) {
            if (isset($conversation['order'])) {
                $order = $conversation['order'];
                $synced = syncPrescriptionToLocal($order);
                if ($synced) {
                    $syncedCount++;
                }

                $clientName = $order['customer_name']
                    ?? trim(($order['user']['first_name'] ?? '').' '.($order['user']['last_name'] ?? ''))
                    ?: 'Client inconnu';

                $lastMessage = $conversation['last_message'] ?? null;
                if (is_array($lastMessage)) {
                    $lastMessage = $lastMessage['body'] ?? $lastMessage['message'] ?? null;
                }

                $transformedConversations[] = [
                    'reference' => $order['reference'] ?? null,
                    'customer_name' => $clientName,
                    'client_name' => $clientName,
                    'conversation_slug' => $conversation['slug'] ?? $order['user']['conversation_slug'] ?? null,
                    'status' => $order['merchant_status'] ?? $order['status'] ?? null,
                    'created_at' => $order['submitted_at'] ?? $order['created_at'] ?? null,
                    'products_count' => count($order['products'] ?? []),
                    'distance' => $order['distance'] ?? null,
                    'last_message' => $lastMessage,
                    'unread_count' => (int) ($conversation['unread_count'] ?? 0),
                    'is_active' => (bool) ($conversation['is_active'] ?? false),
                ];
            } elseif (isset($conversation['slug'])) {
                $clientName = trim(($conversation['user']['first_name'] ?? '').' '.($conversation['user']['last_name'] ?? ''))
                    ?: ($conversation['customer_name'] ?? 'Client inconnu');

                $lastMessage = $conversation['last_message'] ?? null;
                if (is_array($lastMessage)) {
                    $lastMessage = $lastMessage['body'] ?? $lastMessage['message'] ?? null;
                }

                $transformedConversations[] = [
                    'reference' => $conversation['order_reference'] ?? null,
                    'customer_name' => $clientName,
                    'client_name' => $clientName,
                    'conversation_slug' => $conversation['slug'] ?? null,
                    'status' => $conversation['status'] ?? ($conversation['is_active'] ? 'Active' : 'Inactive'),
                    'created_at' => $conversation['created_at'] ?? $conversation['updated_at'] ?? null,
                    'products_count' => 0,
                    'distance' => null,
                    'last_message' => $lastMessage,
                    'unread_count' => (int) ($conversation['unread_count'] ?? 0),
                    'is_active' => (bool) ($conversation['is_active'] ?? false),
                ];
            }
        }

        Log::info('Conversations synced successfully', [
            'total' => count($conversationsList),
            'synced' => $syncedCount,
            'params' => $params,
        ]);

        $total = isset($apiData['total']) ? (int) $apiData['total'] : count($transformedConversations);
        $perPage = (int) ($apiData['per_page'] ?? ($params['per_page'] ?? 15));
        $currentPage = (int) ($apiData['current_page'] ?? ($params['page'] ?? 1));

        $apiPaginator = new \Illuminate\Pagination\LengthAwarePaginator(
            $transformedConversations,
            $total,
            $perPage,
            $currentPage,
            [
                'path' => request()->url(),
                'query' => request()->query(),
            ]
        );

        return [
            'success' => true,
            'data' => $apiPaginator,
            'synced_count' => $syncedCount,
            'message' => "Conversations synchronisées avec succès ({$syncedCount} éléments)",
        ];
    } catch (\Exception $e) {
        Log::error('Conversation sync exception', [
            'error' => $e->getMessage(),
            'params' => $params,
        ]);

        return [
            'success' => false,
            'data' => new \Illuminate\Pagination\LengthAwarePaginator([], 0, $params['per_page'] ?? 15, $params['page'] ?? 1, [
                'path' => request()->url(),
                'query' => request()->query(),
            ]),
            'offline_mode' => true,
            'message' => 'Erreur de synchronisation. Vérifiez votre connexion internet.',
        ];
    }
}

/**
 * Get conversations from local database
 */
function getLocalConversations(array $params = [])
{
    $query = \App\Models\Prescription::query()
        ->whereNotNull('conversation_slug');

    if (! empty($params['search'])) {
        $query->where(function ($q) use ($params) {
            $q->where('customer_name', 'like', '%'.$params['search'].'%')
                ->orWhere('reference', 'like', '%'.$params['search'].'%')
                ->orWhere('conversation_slug', 'like', '%'.$params['search'].'%');
        });
    }

    if (! empty($params['status'])) {
        $query->where('status', $params['status']);
    }

    if (! empty($params['date_from'])) {
        $query->where('created_at', '>=', $params['date_from']);
    }

    if (! empty($params['date_to'])) {
        $query->where('created_at', '<=', $params['date_to']);
    }

    $perPage = $params['per_page'] ?? 15;

    return $query->orderBy('created_at', 'desc')->paginate($perPage);
}

/**
 * Sync conversation from API to local database
 */
function syncConversationToLocal(array $conversationData): bool
{
    try {
        $conversation = \App\Models\Conversation::updateOrCreate(
            ['slug' => $conversationData['conversation']['slug']],
            [
                'client_slug' => $conversationData['client']['slug'] ?? null,
                'client_first_name' => $conversationData['client']['first_name'] ?? null,
                'client_last_name' => $conversationData['client']['last_name'] ?? null,
                'is_active' => $conversationData['conversation']['is_active'] ?? true,
                'deleted_by_user' => $conversationData['conversation']['deleted_by_user'] ?? false,
                'deleted_by_merchant' => $conversationData['conversation']['deleted_by_merchant'] ?? false,
                'api_created_at' => isset($conversationData['conversation']['created_at'])
                    ? \Carbon\Carbon::parse($conversationData['conversation']['created_at'])
                    : null,
                'api_updated_at' => isset($conversationData['conversation']['updated_at'])
                    ? \Carbon\Carbon::parse($conversationData['conversation']['updated_at'])
                    : null,
            ]
        );

        if (isset($conversationData['messages']) && is_array($conversationData['messages'])) {
            foreach ($conversationData['messages'] as $messageData) {
                \App\Models\ConversationMessage::updateOrCreate(
                    [
                        'conversation_id' => $conversation->id,
                        'api_message_id' => $messageData['id'] ?? null,
                    ],
                    [
                        'sender_type' => $messageData['sender_type'] ?? 'user',
                        'user_id' => $messageData['user_id'] ?? null,
                        'merchant_id' => $messageData['merchant_id'] ?? null,
                        'body' => $messageData['body'] ?? '',
                        'api_created_at' => isset($messageData['created_at'])
                            ? \Carbon\Carbon::parse($messageData['created_at'])
                            : null,
                    ]
                );
            }
        }

        return true;
    } catch (\Exception $e) {
        Log::error('Error syncing conversation to local', [
            'conversation_data' => $conversationData,
            'error' => $e->getMessage(),
        ]);

        return false;
    }
}

/**
 * Get conversation from local database
 */
function getLocalConversation(string $conversationSlug): ?\App\Models\Conversation
{
    return \App\Models\Conversation::where('slug', $conversationSlug)
        ->with(['messages' => function ($query) {
            $query->orderBy('api_created_at', 'asc');
        }])
        ->first();
}

/**
 * Get single conversation from API
 */
function getApiSingleConversation(string $conversationSlug): array
{
    try {
        $apiResponse = getHttpClient(true)->get(config('app.api_url').'/merchants/conversations/'.$conversationSlug);

        if ($apiResponse->successful()) {
            $conversationData = $apiResponse->json();

            return [
                'success' => true,
                'data' => $conversationData,
                'from_api' => true,
                'offline_mode' => false,
            ];
        }

        $errorData = $apiResponse->json();
        $errorMessage = $errorData['message'] ?? 'Conversation introuvable sur le serveur';

        Log::warning('API conversation fetch failed', [
            'slug' => $conversationSlug,
            'status' => $apiResponse->status(),
            'error' => $errorMessage,
        ]);

        return [
            'success' => false,
            'data' => null,
            'offline_mode' => false,
            'message' => $errorMessage,
            'status' => $apiResponse->status(),
        ];
    } catch (\Illuminate\Http\Client\ConnectionException $e) {
        Log::error('API conversation connection exception', [
            'slug' => $conversationSlug,
            'error' => $e->getMessage(),
        ]);

        return [
            'success' => false,
            'data' => null,
            'offline_mode' => true,
            'message' => 'Impossible de se connecter au serveur. Vérifiez votre connexion internet.',
            'status' => 0,
        ];
    } catch (\Exception $e) {
        Log::error('API conversation fetch exception', [
            'slug' => $conversationSlug,
            'error' => $e->getMessage(),
            'type' => get_class($e),
        ]);

        ['message' => $friendlyMessage, 'status' => $status] = extractApiExceptionMessage($e);

        $isConnectionError = str_contains($e->getMessage(), 'Connection')
            || str_contains($e->getMessage(), 'timeout')
            || str_contains($e->getMessage(), 'resolve host');

        return [
            'success' => false,
            'data' => null,
            'offline_mode' => $isConnectionError,
            'message' => $friendlyMessage,
            'status' => $status,
        ];
    }
}

/**
 * Get and sync conversation from API (backward compatibility)
 */
function getAndSyncConversation(string $conversationSlug): array
{
    return getApiSingleConversation($conversationSlug);
}

/**
 * Send a new message in a conversation
 */
function sendConversationMessage(string $conversationSlug, string $body): array
{
    try {
        $response = getHttpClient(true)->post(
            config('app.api_url').'/merchants/conversations/'.urlencode($conversationSlug).'/messages',
            ['body' => $body, 'sender_type' => 'merchant']
        );

        if ($response->successful()) {
            $payload = $response->json();

            return [
                'success' => true,
                'data' => $payload['message'] ?? $payload['data'] ?? null,
                'message' => $payload['message_text'] ?? $payload['message'] ?? 'Message envoyé.',
                'status' => $response->status(),
            ];
        }

        if ($response->status() === 401) {
            Auth::logout();
            session()->invalidate();
            session()->regenerateToken();

            return [
                'success' => false,
                'message' => 'Session expirée',
                'status' => 401,
            ];
        }

        $errorData = $response->json();
        $errorMessage = $errorData['message'] ?? 'Échec de l\'envoi du message';

        return [
            'success' => false,
            'message' => $errorMessage,
            'status' => $response->status(),
        ];
    } catch (\Exception $e) {
        Log::error('Conversation send message exception', [
            'conversation_slug' => $conversationSlug,
            'error' => $e->getMessage(),
        ]);

        ['message' => $friendlyMessage, 'status' => $status] = extractApiExceptionMessage($e);

        return [
            'success' => false,
            'message' => $friendlyMessage,
            'status' => $status,
        ];
    }
}
