<?php

namespace App\Services\Carriers;

use App\Models\Order;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\Log;

class IndiaPostCarrier implements CarrierInterface
{
    protected Client $client;
    protected array $config;

    public function __construct(array $config)
    {
        $this->config = $config;
        $this->client = new Client([
            'base_uri' => $config['api_url'] ?? 'https://api.indiapost.gov.in',
            'timeout' => 30,
        ]);
    }

    public function createShipment(Order $order, array $formData = []): array
    {
        try {
            $address = $order->address_snapshot;

            $data = [
                'booking_type' => $formData['booking_type'] ?? 'Parcel',
                'from_pincode' => $this->config['from_pincode'] ?? '',
                'to_pincode' => $address['pin'],
                'from_name' => $this->config['from_name'] ?? '',
                'from_address' => $this->config['from_address'] ?? '',
                'from_city' => $this->config['from_city'] ?? '',
                'from_state' => $this->config['from_state'] ?? '',
                'from_phone' => $this->config['from_phone'] ?? '',
                'to_name' => $address['name'],
                'to_address' => $address['line1'] . ' ' . ($address['line2'] ?? ''),
                'to_city' => $address['city'],
                'to_state' => $address['state'],
                'to_phone' => $address['mobile'],
                'weight' => $formData['weight'] ?? 500,
                'value' => $order->total_payable,
                'payment_mode' => $formData['payment_mode'] ?? 'Prepaid',
                'cod_amount' => $formData['cod_amount'] ?? 0,
                'description' => $this->getProductsDescription($order),
                'order_id' => (string) $order->id,
            ];

            $response = $this->client->post('/api/v1/shipment/create', [
                'headers' => [
                    'Content-Type' => 'application/json',
                    'Authorization' => 'Bearer ' . ($this->config['api_token'] ?? ''),
                ],
                'json' => $data,
            ]);

            $result = json_decode($response->getBody()->getContents(), true);

            if (isset($result['success']) && $result['success'] && isset($result['data']['tracking_number'])) {
                $trackingNumber = $result['data']['tracking_number'];
                $labelUrl = $this->generateLabel($trackingNumber);

                Log::info('IndiaPost shipment created', [
                    'order_id' => $order->id,
                    'tracking_number' => $trackingNumber,
                ]);

                return [
                    'tracking_id' => $trackingNumber,
                    'label_url' => $labelUrl,
                    'raw_response' => $result,
                    'metadata' => $result['data'] ?? [],
                ];
            }

            Log::error('IndiaPost shipment creation failed', [
                'order_id' => $order->id,
                'response' => $result,
            ]);

            throw new \Exception('Failed to create IndiaPost shipment: ' . ($result['message'] ?? 'Unknown error'));
        } catch (\Exception $e) {
            Log::error('IndiaPost shipment creation exception', [
                'order_id' => $order->id,
                'error' => $e->getMessage(),
            ]);

            throw $e;
        }
    }

    public function generateLabel(string $trackingId): ?string
    {
        try {
            $apiUrl = $this->config['api_url'] ?? 'https://api.indiapost.gov.in';
            $labelUrl = $apiUrl . '/api/v1/label/download?tracking_number=' . $trackingId;

            Log::info('IndiaPost label generated', [
                'tracking_number' => $trackingId,
                'url' => $labelUrl,
            ]);

            return $labelUrl;
        } catch (\Exception $e) {
            Log::error('IndiaPost label generation failed', [
                'tracking_number' => $trackingId,
                'error' => $e->getMessage(),
            ]);

            return null;
        }
    }

    public function track(string $trackingId): ?array
    {
        try {
            $response = $this->client->get('/api/v1/track', [
                'headers' => [
                    'Authorization' => 'Bearer ' . ($this->config['api_token'] ?? ''),
                ],
                'query' => [
                    'tracking_number' => $trackingId,
                ],
            ]);

            $result = json_decode($response->getBody()->getContents(), true);

            return $result['data'] ?? null;
        } catch (\Exception $e) {
            Log::error('IndiaPost tracking failed', [
                'tracking_number' => $trackingId,
                'error' => $e->getMessage(),
            ]);

            return null;
        }
    }

    public function validateConfig(array $config): bool
    {
        return !empty($config['api_token']) && !empty($config['from_pincode']);
    }

    /**
     * Check delivery availability for a given pincode
     *
     * @param string $pincode
     * @return array Returns array with 'available' (bool) and 'message' (string)
     */
    public function checkDeliveryAvailability(string $pincode): array
    {
        // IndiaPost availability check not implemented yet
        return [
            'available' => false,
            'message' => 'Delivery availability check not available for IndiaPost',
        ];
    }

    protected function getProductsDescription(Order $order): string
    {
        $items = $order->items->map(function ($item) {
            return $item->name . ' (x' . $item->qty . ')';
        })->take(3)->toArray();

        return implode(', ', $items);
    }
}

