<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Http\Traits\CrulRequest;

class ServiceReservationController extends Controller
{
    use CrulRequest;

    // Base path appended to TURBOLY_URL by CrulRequest
    protected $url = '';

    /**
     * Create service reservation in Turboly
     * 
     * @api POST /turboly/service-reservation/create
     * 
     * @param Integer cart_service_id
     * @param Integer customer_id (local)
     * @param Integer pet_id (vehicle)
     * @param String plan_service_date (Y-m-d format)
     * @param String plan_service_time (H:i format)
     * @param Array service_items (array of service descriptions)
     * @param Integer odometer (optional)
     * @param String notes (optional)
     */
    public function create(Request $request)
    {
        try {
            // Validate required fields
            $validator = \Validator::make($request->all(), [
                'cart_service_id' => 'required|integer',
                'site_id' => 'required|integer',
                'customer_id' => 'required|integer',
                'pet_id' => 'required|integer',
                'plan_service_date' => 'required|date',
                'plan_service_time' => 'required',
                'service_items' => 'array',
            ]);
            $SITE_ID = $request->site_id;
            if ($validator->fails()) {
                return response()->json([
                    'STATUS_CODE' => '400',
                    'MESSAGE' => 'Validation failed',
                    'ERROR' => $validator->errors(),
                ], 400);
            }

            // Get customer with turboly_customer_id
            $customer = DB::connection('mysql3')
                ->table('customers')
                ->where('customer_id', $request->customer_id)
                ->first();

            // Auto-sync customer to Turboly if not yet synced
            if (!$customer || empty($customer->turboly_customer_id)) {
                Log::info('Customer not synced with Turboly, attempting auto-sync', [
                    'customer_id' => $request->customer_id,
                ]);

                if ($customer) {
                    try {
                        // Run customers:save command with the customer's email
                        $email = $customer->customer_email ?? null;
                        if (!empty($email)) {
                            \Illuminate\Support\Facades\Artisan::call('customers:save', ['email' => $email]);
                            Log::info('Auto-sync customer completed', ['email' => $email]);

                            // Re-fetch customer after sync
                            $customer = DB::connection('mysql3')
                                ->table('customers')
                                ->where('customer_id', $request->customer_id)
                                ->first();
                        }
                    } catch (\Throwable $e) {
                        Log::error('Auto-sync customer failed', ['error' => $e->getMessage()]);
                    }
                }

                // If still not synced after auto-attempt, return error
                if (!$customer || empty($customer->turboly_customer_id)) {
                    return response()->json([
                        'STATUS_CODE' => '400',
                        'MESSAGE' => 'Customer not synced with Turboly (auto-sync failed)',
                    ], 400);
                }
            }

            // Get vehicle with turboly_vehicle_id
            $vehicle = DB::connection('mysql3')
                ->table('customer_pet')
                ->where('pet_id', $request->pet_id)
                ->first();

            // Auto-sync vehicle to Turboly if not yet synced
            if (!$vehicle || empty($vehicle->turboly_vehicle_id)) {
                Log::info('Vehicle not synced with Turboly, attempting auto-sync', [
                    'pet_id' => $request->pet_id,
                ]);

                if ($vehicle && !empty($customer->turboly_customer_id)) {
                    try {
                        $synced = $this->autoSyncVehicleToTurboly($vehicle, $customer);
                        if ($synced) {
                            // Re-fetch vehicle after sync
                            $vehicle = DB::connection('mysql3')
                                ->table('customer_pet')
                                ->where('pet_id', $request->pet_id)
                                ->first();
                        }
                    } catch (\Throwable $e) {
                        Log::error('Auto-sync vehicle failed', ['error' => $e->getMessage()]);
                    }
                }

                // If still not synced after auto-attempt, return error
                if (!$vehicle || empty($vehicle->turboly_vehicle_id)) {
                    return response()->json([
                        'STATUS_CODE' => '400',
                        'MESSAGE' => 'Vehicle not synced with Turboly (auto-sync failed)',
                    ], 400);
                }
            }

            // Build service reservation lines
            $serviceLines = [];
            if (!empty($request->service_items) && is_array($request->service_items)) {
                foreach ($request->service_items as $item) {
                    $description = $item['description'] ?? $item;

                    // Check if this item is a package
                    try {
                        $package = DB::connection('mysql2')->table('medicals')
                            ->where('medical_name', $description)
                            ->where('is_package', 1)
                            ->select('package_services_json')
                            ->first();
                        
                        // Fallback: Try LIKE search if exact match fails
                        if (!$package) {
                             $package = DB::connection('mysql2')->table('medicals')
                                ->where('medical_name', 'LIKE', '%' . $description . '%')
                                ->where('is_package', 1)
                                ->select('package_services_json')
                                ->first();
                        }

                        if ($package && !empty($package->package_services_json)) {
                            $services = json_decode($package->package_services_json, true);
                            if (json_last_error() === JSON_ERROR_NONE && is_array($services)) {
                                foreach ($services as $svc) {
                                    $serviceLines[] = [
                                        'description' => $svc['service_description'] ?? $svc['description'] ?? 'Service',
                                    ];
                                }
                                continue;
                            }
                        }
                    } catch (\Throwable $e) {
                        Log::warning('Error searching package service', ['item' => $description, 'error' => $e->getMessage()]);
                    }

                    $serviceLines[] = [
                        'description' => $description,
                    ];
                }
            }

            // If no service items provided, add a default one
            if (empty($serviceLines)) {
                $serviceLines[] = [
                    'description' => 'Service',
                ];
            }
            Log::info('Creating Turboly service reservation', [
                'cart_service_id' => $request->cart_service_id,
                'request' => $request->all()
            ]);
            $storeId = DB::connection('mysqlUser')
                ->table('user_site')
                ->where('user_id', $SITE_ID)
                ->first();
            // Build payload
            $payload = [
                'service_reservation' => [
                    'store_id' => $storeId ? (int)$storeId->store_id : 7630,
                    'customer_id' => (int)$customer->turboly_customer_id,
                    'vehicle_id' => (int)$vehicle->turboly_vehicle_id,
                    'plan_service_date' => $request->plan_service_date,
                    'plan_service_time' => $request->plan_service_time,
                    'service_advisor_id' => 15648,
                    'salesperson_id' => 15656,
                    'serviced_item_type' => '',
                    'serviced_item_name' => '',
                    'serviced_item_serial' => '',
                    'booking_source_id' => 127, // Default booking source
                    'odometer' => (int)($request->odometer),
                    'notes' => $request->notes ?? '',
                    'service_reservation_lines' => $serviceLines,
                ],
            ];

            Log::info('Creating Turboly service reservation', [
                'cart_service_id' => $request->cart_service_id,
                'payload' => $payload,
                'request' => $request->all()
            ]);

            // Send request to Turboly (use CrulRequest base URL handling)
            $this->url = '/api/v1/service_reservations';
            $response = $this->sendRequest('', [], $payload, 'POST');

            $status = $response['status'] ?? null;
            $responseData = $response['response'] ?? [];

            if ($status == 200 || $status == 201) {
                $reservation = $responseData['service_reservation'] ?? null;
                $reservationId = $reservation['id'] ?? null;

                if ($reservationId) {
                    // Update cart_services with turboly_service_reservation_id
                    DB::connection('mysqlCart')
                        ->table('cart_services')
                        ->where('cart_service_id', $request->cart_service_id)
                        ->update([
                            'turboly_service_reservation_id' => (int)$reservationId,
                            'updated_at' => date('Y-m-d H:i:s'),
                        ]);

                    Log::info('Turboly service reservation created', [
                        'cart_service_id' => $request->cart_service_id,
                        'turboly_service_reservation_id' => $reservationId,
                    ]);

                    return response()->json([
                        'STATUS_CODE' => '200',
                        'MESSAGE' => 'Service reservation created successfully',
                        'DATA' => [
                            'turboly_service_reservation_id' => $reservationId,
                            'response' => $responseData,
                        ],
                    ], 200);
                }
            }

            Log::error('Failed to create Turboly service reservation', [
                'cart_service_id' => $request->cart_service_id,
                'status' => $status,
                'responseData' => $responseData,
                'response' => $response,
                'url' => $this->url,
            ]);

            return response()->json([
                'STATUS_CODE' => '400',
                'MESSAGE' => 'Failed to create service reservation',
                'ERROR' => $responseData,
            ], 400);
        } catch (\Exception $e) {
            Log::error('Exception creating Turboly service reservation', [
                'cart_service_id' => $request->cart_service_id ?? null,
                'error' => $e->getMessage(),
            ]);

            return response()->json([
                'STATUS_CODE' => '500',
                'MESSAGE' => 'Internal Server Error',
                'ERROR' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Auto-sync a vehicle to Turboly when turboly_vehicle_id is missing.
     * Mirrors logic from CustomerCarController::pushVehicleToTurboly.
     */
    private function autoSyncVehicleToTurboly($vehicle, $customer): bool
    {
        try {
            // Resolve brand and type Turboly IDs
            $makeId = null;
            $modelId = null;

            if (!empty($vehicle->car_brand_id)) {
                $brand = DB::connection('mysql3')->table('car_brands')
                    ->where('brand_id', $vehicle->car_brand_id)->first();
                $makeId = $brand->turboly_vehicle_make_id ?? null;
            }

            if (!empty($vehicle->car_brand_type_id)) {
                $type = DB::connection('mysql3')->table('car_brand_types')
                    ->where('type_id', $vehicle->car_brand_type_id)->first();
                $modelId = $type->turboly_vehicle_model_id ?? null;
            }

            if (empty($makeId) || empty($modelId)) {
                Log::warning('Auto-sync vehicle: missing brand/type Turboly mapping', [
                    'pet_id' => $vehicle->pet_id,
                    'car_brand_id' => $vehicle->car_brand_id ?? null,
                    'car_brand_type_id' => $vehicle->car_brand_type_id ?? null,
                ]);
                return false;
            }

            // Parse year from pet_microchip or pet_birthday
            $year = 2000;
            if (!empty($vehicle->pet_microchip) && is_numeric($vehicle->pet_microchip)) {
                $year = (int)$vehicle->pet_microchip;
            } elseif (!empty($vehicle->pet_birthday)) {
                $year = (int)date('Y', strtotime($vehicle->pet_birthday));
            }
            if ($year < 1900) $year = 2000;

            $registration = !empty($vehicle->pet_name) ? $vehicle->pet_name : 'REG-' . $vehicle->pet_id;
            $color = !empty($vehicle->pet_color) ? $vehicle->pet_color : 'N/A';

            $payload = [
                'vehicle' => [
                    'registration' => $registration,
                    'vehicle_make_id' => (int)$makeId,
                    'vehicle_model_id' => (int)$modelId,
                    'vehicle_type' => 'car',
                    'year' => $year,
                    'vin' => 'VIN-' . $vehicle->pet_id . '-' . time(),
                    'engine_number' => 'ENG-' . $vehicle->pet_id . '-' . time(),
                    'color' => $color,
                    'odometer' => 0,
                    'notes' => $vehicle->pet_special_notes ?? '',
                    'last_service' => date('Y-m-d'),
                    'next_service' => date('Y-m-d', strtotime('+6 months')),
                    'customer_id' => (int)$customer->turboly_customer_id,
                    'store_id' => (int)env('TURBOLY_STORE_ID', 7626),
                ],
            ];

            $url = env('TURBOLY_URL') . '/api/v1/vehicles';
            $client = new \GuzzleHttp\Client(['timeout' => 10, 'http_errors' => false]);
            $response = $client->post($url, [
                'headers' => [
                    'X-AUTH-EMAIL' => env('AUTH_EMAIL'),
                    'X-AUTH-TOKEN' => env('AUTH_TOKEN'),
                ],
                'json' => $payload,
            ]);

            $statusCode = $response->getStatusCode();
            $responseData = json_decode((string)$response->getBody(), true);

            Log::info('Auto-sync vehicle to Turboly response', [
                'pet_id' => $vehicle->pet_id,
                'status' => $statusCode,
                'response' => $responseData,
            ]);

            $vehicleId = null;

            if ($statusCode == 200 || $statusCode == 201) {
                $vehicleId = $responseData['vehicle']['id'] ?? null;
            } elseif ($statusCode == 422) {
                // Might already exist - try to fetch by registration
                try {
                    $getUrl = env('TURBOLY_URL') . '/api/v1/vehicles?registration=' . urlencode($registration);
                    $getResp = $client->get($getUrl, [
                        'headers' => [
                            'X-AUTH-EMAIL' => env('AUTH_EMAIL'),
                            'X-AUTH-TOKEN' => env('AUTH_TOKEN'),
                        ],
                    ]);
                    $getData = json_decode((string)$getResp->getBody(), true);
                    $vehicles = $getData['vehicles'] ?? [];
                    if (!empty($vehicles[0]['id'])) {
                        $vehicleId = $vehicles[0]['id'];
                    }
                } catch (\Throwable $e) {
                    Log::warning('Auto-sync vehicle lookup failed', ['error' => $e->getMessage()]);
                }
            }

            if ($vehicleId) {
                DB::connection('mysql3')->table('customer_pet')
                    ->where('pet_id', $vehicle->pet_id)
                    ->update([
                        'turboly_vehicle_id' => (int)$vehicleId,
                        'updated_at' => date('Y-m-d H:i:s'),
                    ]);
                Log::info('Auto-sync vehicle: turboly_vehicle_id saved', [
                    'pet_id' => $vehicle->pet_id,
                    'turboly_vehicle_id' => $vehicleId,
                ]);
                return true;
            }

            return false;
        } catch (\Throwable $e) {
            Log::error('Auto-sync vehicle exception', [
                'pet_id' => $vehicle->pet_id ?? null,
                'error' => $e->getMessage(),
            ]);
            return false;
        }
    }
}
