<?php

namespace App\Services;

use App\Models\Order;
use App\Models\CourierBooking;
use App\Models\OrderHistory;
use App\Models\Setting;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use App\Services\NotificationDispatcher;
use Exception;

class CourierService
{
    /**
     * Book a consignment for an order using the default courier configured in settings.
     */
    public static function bookConsignment(Order $order, ?string $courier = null): array
    {
        // 1. Get courier to use (fallback to default)
        $courier = $courier ?: Setting::getValue('default_courier', 'steadfast');
        
        if ($order->courierBooking()->exists()) {
            return [
                'success' => false,
                'message' => 'Courier consignment is already booked for this order. Tracking Code: ' . $order->courierBooking->tracking_code
            ];
        }

        // Calculate COD (Cash On Delivery) amount. If payment status is paid, COD is 0.
        $codAmount = strtolower($order->payment_status) === 'paid' ? 0.00 : $order->grand_total;

        try {
            if ($courier === 'steadfast') {
                $enabled = Setting::getValue('steadfast_enabled');
                if ($enabled !== 'on' && $enabled !== true && $enabled !== '1' && $enabled !== 1) {
                    return [
                        'success' => false,
                        'message' => 'Steadfast Courier is not enabled in settings.'
                    ];
                }
                return self::bookSteadfast($order, $codAmount);
            } elseif ($courier === 'pathao') {
                $enabled = Setting::getValue('pathao_enabled');
                if ($enabled !== 'on' && $enabled !== true && $enabled !== '1' && $enabled !== 1) {
                    return [
                        'success' => false,
                        'message' => 'Pathao Courier is not enabled in settings.'
                    ];
                }
                return self::bookPathao($order, $codAmount);
            } else {
                return [
                    'success' => false,
                    'message' => 'Invalid courier configured: ' . $courier
                ];
            }
        } catch (Exception $e) {
            Log::error('Courier Booking Exception for Order #' . $order->order_number . ': ' . $e->getMessage());
            return [
                'success' => false,
                'message' => self::formatCourierError($e)
            ];
        }
    }

    /**
     * Book consignment via Steadfast Courier API.
     */
    private static function bookSteadfast(Order $order, float $codAmount): array
    {
        $apiKey = Setting::getValue('steadfast_api_key');
        $secretKey = Setting::getValue('steadfast_secret_key');

        if (!$apiKey || !$secretKey) {
            return [
                'success' => false,
                'message' => 'Steadfast API credentials are not configured in settings.'
            ];
        }

        $url = 'https://portal.steadfast.com.bd/api/v1/create_order';

        $note = $order->notes ?? 'E-commerce delivery';
        if ($order->is_exchange) {
            $note = '*** EXCHANGE ORDER: Deliver new items and COLLECT return items! *** ' . $note;
        }

        $payload = [
            'invoice' => $order->order_number,
            'recipient_name' => $order->customer_name,
            'recipient_phone' => $order->customer_phone,
            'recipient_address' => $order->shipping_address,
            'cod_amount' => $codAmount,
            'note' => $note,
            'is_exchange' => $order->is_exchange ? 1 : 0,
        ];

        // Hit the API
        $response = Http::withHeaders([
            'Api-Key' => $apiKey,
            'Secret-Key' => $secretKey,
            'Content-Type' => 'application/json',
        ])->post($url, $payload);

        if ($response->failed()) {
            throw new Exception('Steadfast server responded with status: ' . $response->status());
        }

        $result = $response->json();

        // Steadfast returns status 200 on success
        if (isset($result['status']) && $result['status'] == 200 && isset($result['consignment'])) {
            $consignment = $result['consignment'];
            
            // Record booking
            CourierBooking::create([
                'order_id' => $order->id,
                'courier_name' => 'steadfast',
                'consignment_id' => $consignment['consignment_id'] ?? null,
                'tracking_code' => $consignment['tracking_code'] ?? null,
                'cod_amount' => $codAmount,
                'delivery_status' => 'pending',
                'raw_response' => $result,
            ]);

            // Update order status
            $oldStatus = $order->status;
            $order->update(['status' => 'shipped']);

            // Record history
            OrderHistory::create([
                'order_id' => $order->id,
                'user_id' => auth()->id(),
                'action' => 'status_changed',
                'from_status' => $oldStatus,
                'to_status' => 'shipped',
                'notes' => 'Successfully booked with Steadfast. Tracking: ' . ($consignment['tracking_code'] ?? 'N/A'),
            ]);

            // Dispatch SMS & Email notifications
            NotificationDispatcher::dispatchOrderShipped($order);

            return [
                'success' => true,
                'message' => 'Consignment successfully booked with Steadfast! Tracking Code: ' . ($consignment['tracking_code'] ?? 'N/A')
            ];
        }

        $errorMsg = $result['errors'] ?? ($result['message'] ?? 'Unknown error response');
        if (is_array($errorMsg)) {
            $errorMsg = json_encode($errorMsg);
        }

        return [
            'success' => false,
            'message' => 'Steadfast API Error: ' . $errorMsg
        ];
    }

    /**
     * Book consignment via Pathao Courier API.
     */
    private static function bookPathao(Order $order, float $codAmount): array
    {
        // Simple Pathao mock/integration structure for the plan setup
        $clientId = Setting::getValue('pathao_client_id');
        $clientSecret = Setting::getValue('pathao_client_secret');
        $username = Setting::getValue('pathao_username');
        $password = Setting::getValue('pathao_password');
        $storeId = Setting::getValue('pathao_store_id');

        if (!$clientId || !$clientSecret || !$username || !$password || !$storeId) {
            return [
                'success' => false,
                'message' => 'Pathao API credentials or Store ID are not configured in settings.'
            ];
        }

        // 1. Get Access Token
        $tokenUrl = 'https://api.pathao.com/aladdin/api/v1/issue-token';
        $tokenResponse = Http::post($tokenUrl, [
            'client_id' => $clientId,
            'client_secret' => $clientSecret,
            'username' => $username,
            'password' => $password,
            'grant_type' => 'password',
        ]);

        if ($tokenResponse->failed()) {
            return [
                'success' => false,
                'message' => 'Pathao Token authentication failed: ' . ($tokenResponse->json('message') ?? 'Connection error')
            ];
        }

        $accessToken = $tokenResponse->json('access_token');

        // Pathao requires precise city, zone, area matching. 
        // For simplicity, we fallback to default zone/area parsing or let the admin define them.
        // In full execution, we'd pull from dynamic locations mapping.
        // For this single-click action, we send the request with default parameters.
        $createUrl = 'https://api.pathao.com/aladdin/api/v1/orders';

        // Example mock fallback locations or parsing
        $description = 'E-commerce order #' . $order->order_number;
        if ($order->is_exchange) {
            $description = '*** EXCHANGE ORDER: Deliver new items and COLLECT return items! *** ' . $description;
        }

        $payload = [
            'store_id' => (int)$storeId,
            'merchant_order_id' => $order->order_number,
            'recipient_name' => $order->customer_name,
            'recipient_phone' => $order->customer_phone,
            'recipient_address' => $order->shipping_address,
            'recipient_city' => 1, // Default Dhaka
            'recipient_zone' => 1, // Default Zone
            'recipient_area' => 1, // Default Area
            'delivery_type' => 48, // Standard 48 Hours
            'item_type' => 2, // Parcel
            'item_quantity' => 1,
            'amount_to_collect' => $codAmount,
            'item_weight' => 0.5,
            'description' => $description,
        ];

        $response = Http::withToken($accessToken)
            ->withHeaders(['Content-Type' => 'application/json', 'Accept' => 'application/json'])
            ->post($createUrl, $payload);

        if ($response->failed()) {
            $errorMsg = $response->json('message') ?? 'API request failed';
            if ($response->json('errors')) {
                $errorMsg .= ': ' . json_encode($response->json('errors'));
            }
            return [
                'success' => false,
                'message' => 'Pathao API Error: ' . $errorMsg
            ];
        }

        $result = $response->json();
        
        if (isset($result['type']) && $result['type'] === 'success' && isset($result['data'])) {
            $consignment = $result['data'];

            CourierBooking::create([
                'order_id' => $order->id,
                'courier_name' => 'pathao',
                'consignment_id' => $consignment['consignment_id'] ?? null,
                'tracking_code' => $consignment['consignment_id'] ?? null, // Pathao uses consignment_id as tracking code
                'cod_amount' => $codAmount,
                'delivery_status' => 'pending',
                'raw_response' => $result,
            ]);

            // Update order status
            $oldStatus = $order->status;
            $order->update(['status' => 'shipped']);

            // Record history
            OrderHistory::create([
                'order_id' => $order->id,
                'user_id' => auth()->id(),
                'action' => 'status_changed',
                'from_status' => $oldStatus,
                'to_status' => 'shipped',
                'notes' => 'Successfully booked with Pathao. Consignment ID: ' . ($consignment['consignment_id'] ?? 'N/A'),
            ]);

            // Dispatch SMS & Email notifications
            NotificationDispatcher::dispatchOrderShipped($order);

            return [
                'success' => true,
                'message' => 'Consignment successfully booked with Pathao! Consignment ID: ' . ($consignment['consignment_id'] ?? 'N/A')
            ];
        }

        return [
            'success' => false,
            'message' => 'Pathao Response failure: ' . ($result['message'] ?? 'Unknown Error')
        ];
    }

    private static function formatCourierError(Exception $e): string
    {
        $msg = $e->getMessage();

        if (str_contains($msg, 'Could not resolve host') || str_contains($msg, 'cURL error 6')) {
            return 'Connection Error: Could not reach the courier server. Please verify your internet connection or API credentials.';
        }

        if (str_contains($msg, 'Connection timed out') || str_contains($msg, 'cURL error 28') || str_contains($msg, 'timed out')) {
            return 'Connection Error: Request timed out. The courier server took too long to respond.';
        }

        if (preg_match('/cURL error \d+:/i', $msg)) {
            if (preg_match('/cURL error \d+: ([^(]+)/i', $msg, $match)) {
                return 'Connection Error: ' . trim($match[1]);
            }
        }

        return strlen($msg) > 120 ? substr($msg, 0, 120) . '...' : $msg;
    }
}
