<?php

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

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

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

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

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

            return [
                'success' => true,
                'data' => $responseData,
                'message' => $responseData['message'] ?? 'Prescriptions récupérées avec succès',
                'status' => 200,
                'meta' => $responseData['orders'] ?? null,
            ];
        }

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

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

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

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

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

/**
 * Get a single prescription by reference
 */
function getApiSinglePrescription(string $reference): array
{
    try {
        $response = getHttpClient(true)->get(config('app.api_url').'/merchants/orders/'.urlencode($reference));

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

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

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

            return [
                'success' => (bool) ($responseData['success'] ?? true),
                'data' => $responseData['order'] ?? null,
                'message' => $responseData['message'] ?? 'Prescription récupérée avec succès',
                'status' => 200,
            ];
        }

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

        return ['success' => false, 'message' => $errorMessage, 'status' => $response->status()];
    } catch (\Exception $e) {
        Log::error('API single prescription fetch exception', [
            'reference' => $reference,
            'error' => $e->getMessage(),
        ]);

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

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

/**
 * Get latest prescriptions
 */
function getApiLatestPrescriptions(int $limit = 5): array
{
    try {
        $response = getHttpClient(true)->get(config('app.api_url').'/merchants/orders/latest', [
            'limit' => $limit,
        ]);

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

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

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

            return [
                'success' => true,
                'data' => $responseData['orders'] ?? $responseData['data'] ?? [],
                'message' => $responseData['message'] ?? 'Dernières prescriptions récupérées avec succès',
                'status' => 200,
            ];
        }

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

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

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

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

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

/**
 * Sync prescriptions from API to local database
 */
function getAndSyncPrescriptions(array $params = []): array
{
    try {
        $apiResponse = getApiPrescriptions($params);

        if (! $apiResponse['success']) {
            Log::warning('API prescriptions fetch failed, using local data', [
                'error' => $apiResponse['message'],
                'params' => $params,
            ]);

            return [
                'success' => true,
                'data' => getLocalPrescriptions($params),
                'offline_mode' => true,
                'message' => 'Mode hors ligne - Données locales affichées',
            ];
        }

        $apiData = $apiResponse['data'] ?? [];
        $ordersList = $apiData['orders'] ?? $apiData['data'] ?? $apiData;

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

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

        $syncedCount = 0;
        foreach ($ordersList as $order) {
            $synced = syncPrescriptionToLocal($order);
            if ($synced) {
                $syncedCount++;
            }
        }

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

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

        return [
            'success' => true,
            'data' => getLocalPrescriptions($params),
            'offline_mode' => true,
            'message' => 'Erreur de synchronisation - Données locales affichées',
        ];
    }
}

/**
 * Get prescriptions from local database
 */
function getLocalPrescriptions(array $params = [])
{
    $query = \App\Models\Prescription::query();

    if (! empty($params['search'])) {
        $query->where('customer_name', 'like', '%'.$params['search'].'%')
            ->orWhere('reference', '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 a single prescription from API to local database
 */
function syncPrescriptionToLocal(array $order): bool
{
    try {
        $customerName = $order['customer_name'] ?? null;
        $user = $order['user'] ?? [];
        $firstName = $user['first_name'] ?? '';
        $lastName = $user['last_name'] ?? '';

        if (! $customerName && ($firstName || $lastName)) {
            $customerName = trim($firstName.' '.$lastName);
        }

        if (! $customerName) {
            $customerName = 'Client Inconnu';
        }

        $customer = null;
        if ($customerName) {
            $customer = \App\Models\Customer::where('name', 'like', '%'.$customerName.'%')->first();

            if (! $customer) {
                $contact = \App\Models\Contact::create([
                    'phone' => $user['phone'] ?? null,
                    'email' => $user['email'] ?? null,
                ]);

                $customer = \App\Models\Customer::create([
                    'name' => $customerName,
                    'slug' => Str::slug($customerName.'-'.uniqid()),
                    'contact_id' => $contact->id,
                    'status' => true,
                ]);
            }
        }

        $apiStatus = $order['status_name'] ?? $order['status'] ?? 'En attente';
        $localStatus = $apiStatus;

        $prescriptionData = [
            'reference' => $order['reference'] ?? null,
            'customer_name' => $order['customer_name'] ?? null,
            'products_count' => $order['products_count'] ?? 0,
            'status' => $localStatus,
            'created_at' => $order['created_at'] ? \Carbon\Carbon::parse($order['created_at']) : null,
            'distance' => $order['distance'] ?? null,
            'conversation_slug' => $order['user']['conversation_slug'] ?? null,
        ];

        \App\Models\Prescription::updateOrCreate(
            ['reference' => $order['reference']],
            $prescriptionData
        );

        return true;
    } catch (\Exception $e) {
        Log::error('Failed to sync prescription', [
            'order' => $order,
            'error' => $e->getMessage(),
        ]);

        return false;
    }
}

/**
 * Approve prescription
 */
function approvePrescription(string $reference): array
{
    try {
        $response = getHttpClient(true)->post(
            config('app.api_url').'/merchants/orders/'.urlencode($reference).'/approve'
        );

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

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

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

            return [
                'success' => true,
                'message' => $responseData['message'] ?? 'Prescription approuvée avec succès',
                'data' => [
                    'order' => $responseData['order'] ?? null,
                ],
                'status' => 200,
            ];
        }

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

        return [
            'success' => false,
            'message' => $errorMessage,
            'status' => $response->status(),
        ];
    } catch (\Exception $e) {
        Log::error('API prescription approval exception', [
            'reference' => $reference,
            'error' => $e->getMessage(),
        ]);

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

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

/**
 * Cancel prescription
 */
function cancelPrescription(string $reference): array
{
    try {
        $response = getHttpClient(true)->post(
            config('app.api_url').'/merchants/orders/'.urlencode($reference).'/cancel'
        );

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

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

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

            return [
                'success' => true,
                'message' => $responseData['message'] ?? 'Prescription annulée avec succès',
                'data' => [
                    'order' => $responseData['order'] ?? null,
                ],
                'status' => 200,
            ];
        }

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

        return [
            'success' => false,
            'message' => $errorMessage,
            'status' => $response->status(),
        ];
    } catch (\Exception $e) {
        Log::error('API prescription cancellation exception', [
            'reference' => $reference,
            'error' => $e->getMessage(),
        ]);

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

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

/**
 * Finish prescription
 */
function finishPrescription(string $reference): array
{
    try {
        $response = getHttpClient(true)->post(
            config('app.api_url').'/merchants/orders/'.urlencode($reference).'/finish'
        );

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

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

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

            return [
                'success' => true,
                'message' => $responseData['message'] ?? 'Prescription marquée comme terminée',
                'data' => [
                    'order' => $responseData['order'] ?? null,
                ],
                'status' => 200,
            ];
        }

        $errorData = $response->json();
        $errorMessage = $errorData['message'] ?? 'Échec du marquage de la prescription';

        return [
            'success' => false,
            'message' => $errorMessage,
            'status' => $response->status(),
        ];
    } catch (\Exception $e) {
        Log::error('API prescription finish exception', [
            'reference' => $reference,
            'error' => $e->getMessage(),
        ]);

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

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

/**
 * Update prescription conversation slug in local database
 */
function updatePrescriptionConversationSlug($reference, $conversationSlug): array
{
    try {
        $prescription = \App\Models\Prescription::where('reference', $reference)->first();

        if ($prescription) {
            $prescription->update(['conversation_slug' => $conversationSlug]);

            return [
                'success' => true,
                'message' => 'Conversation slug mis à jour avec succès',
            ];
        } else {
            return [
                'success' => false,
                'message' => 'Prescription non trouvée',
            ];
        }
    } catch (\Exception $e) {
        Log::error('Failed to update conversation slug', [
            'reference' => $reference,
            'conversation_slug' => $conversationSlug,
            'error' => $e->getMessage(),
        ]);

        return [
            'success' => false,
            'message' => 'Erreur lors de la mise à jour: '.$e->getMessage(),
        ];
    }
}
