<?php

namespace App\Services;

use App\Models\Car;
use Illuminate\Support\Facades\Storage;

class CarService
{
    public function getAllCars($filters = [])
    {
        $query = Car::query()->with(['mainImage', 'brand', 'carModel', 'currentInsurance', 'rentals' => function($q) {
            $q->where('status', 'open');
        }]);

        if (! empty($filters['search'])) {
            $searchTerm = $filters['search'];
            $keywords = array_filter(explode(' ', $searchTerm));
            
            $query->where(function ($q) use ($keywords) {
                foreach ($keywords as $word) {
                    $q->where(function ($sq) use ($word) {
                        $sq->where('title', 'like', "%{$word}%")
                            ->orWhere('description', 'like', "%{$word}%")
                            ->orWhere('vin', 'like', "%{$word}%")
                            ->orWhere('plate_number', 'like', "%{$word}%")
                            ->orWhere('year', 'like', "%{$word}%")
                            ->orWhereHas('brand', function ($ssq) use ($word) {
                                $ssq->where('name', 'like', "%{$word}%");
                            })
                            ->orWhereHas('carModel', function ($ssq) use ($word) {
                                $ssq->where('name', 'like', "%{$word}%");
                            });
                    });
                }
            });
        }

        if (isset($filters['brand_id']) && $filters['brand_id'] !== '') {
            $query->where('brand_id', $filters['brand_id']);
        }

        if (isset($filters['car_model_id']) && $filters['car_model_id'] !== '') {
            $query->where('car_model_id', $filters['car_model_id']);
        }

        if (isset($filters['branch_id']) && $filters['branch_id'] !== '') {
            $query->where('branch_id', $filters['branch_id']);
        }

        if (isset($filters['status']) && $filters['status'] !== 'all') {
            $query->where('status', $filters['status']);
        }


        if (isset($filters['condition']) && $filters['condition'] !== 'all') {
            $query->where('condition', $filters['condition']);
        }

        if (isset($filters['type']) && $filters['type'] !== 'all') {
            $query->where(function($q) use ($filters) {
                $q->where('type', $filters['type'])
                  ->orWhere('type', 'both');
            });
        }

        if (! empty($filters['min_price'])) {
            $query->where(function($q) use ($filters) {
                if (isset($filters['type']) && $filters['type'] == 'sale') {
                    $q->where('price', '>=', $filters['min_price']);
                } elseif (isset($filters['type']) && $filters['type'] == 'rent') {
                    $q->where('daily_price', '>=', $filters['min_price']);
                } else {
                    $q->where(function($sub) use ($filters) {
                        $sub->whereIn('type', ['sale', 'both'])
                            ->where('price', '>=', $filters['min_price']);
                    })->orWhere(function($sub) use ($filters) {
                        $sub->whereIn('type', ['rent', 'both'])
                            ->where('daily_price', '>=', $filters['min_price']);
                    });
                }
            });
        }

        if (! empty($filters['max_price'])) {
            $query->where(function($q) use ($filters) {
                if (isset($filters['type']) && $filters['type'] == 'sale') {
                    $q->where('price', '<=', $filters['max_price']);
                } elseif (isset($filters['type']) && $filters['type'] == 'rent') {
                    $q->where('daily_price', '<=', $filters['max_price']);
                } else {
                    $q->where(function($sub) use ($filters) {
                        $sub->whereIn('type', ['sale', 'both'])
                            ->where('price', '<=', $filters['max_price']);
                    })->orWhere(function($sub) use ($filters) {
                        $sub->whereIn('type', ['rent', 'both'])
                            ->where('daily_price', '<=', $filters['max_price']);
                    });
                }
            });
        }

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

        if (! empty($filters['body_type']) && $filters['body_type'] !== 'all') {
            $query->where('body_type', $filters['body_type']);
        }

        if (! empty($filters['transmission']) && $filters['transmission'] !== 'all') {
            $query->where('transmission', $filters['transmission']);
        }

        if (! empty($filters['fuel_type']) && $filters['fuel_type'] !== 'all') {
            $query->where('fuel_type', $filters['fuel_type']);
        }

        return $query->latest()->paginate(20)->withQueryString();
    }

    public function getLatestCars($limit = 6)
    {
        return Car::with('mainImage')->latest()->take($limit)->get();
    }

    public function getCarDetails($id)
    {
        return Car::with(['images', 'inquiries.customer', 'document', 'branch'])->findOrFail($id);
    }

    public function storeCar(array $data, $mainImage = null, array $additionalImages = [])
    {
        if (isset($data['features']) && is_string($data['features'])) {
            $data['features'] = array_map('trim', explode(',', $data['features']));
        }

        $car = Car::create($data);

        if ($mainImage) {
            $path = $mainImage->store('cars', 'public');
            $car->images()->create([
                'path' => $path,
                'is_main' => true,
            ]);
        }

        foreach ($additionalImages as $image) {
            if ($image) {
                $path = $image->store('cars', 'public');
                $car->images()->create([
                    'path' => $path,
                    'is_main' => false,
                ]);
            }
        }
        
        $this->syncAddOns($car, $data);

        return $car;
    }

    public function updateCar($id, array $data, $mainImage = null, array $additionalImages = [])
    {
        $car = Car::findOrFail($id);

        if (isset($data['features']) && is_string($data['features'])) {
            $data['features'] = array_map('trim', explode(',', $data['features']));
        }

        // Handle image deletion
        if (isset($data['delete_images']) && is_array($data['delete_images'])) {
            foreach ($data['delete_images'] as $imageId) {
                $image = $car->images()->find($imageId);
                if ($image) {
                    Storage::disk('public')->delete($image->path);
                    $image->delete();
                }
            }
        }

        $car->update($data);
        
        $this->syncAddOns($car, $data);

        if ($mainImage) {
            $car->images()->where('is_main', true)->each(function ($image) {
                Storage::disk('public')->delete($image->path);
                $image->delete();
            });
            
            $path = $mainImage->store('cars', 'public');
            $car->images()->create([
                'path' => $path,
                'is_main' => true,
            ]);
        }

        if (! empty($additionalImages)) {
            foreach ($additionalImages as $image) {
                if ($image) {
                    $path = $image->store('cars', 'public');
                    $car->images()->create([
                        'path' => $path,
                        'is_main' => false,
                    ]);
                }
            }
        }

        // Ensure there is always one main image
        if ($car->images()->count() > 0 && ! $car->images()->where('is_main', true)->exists()) {
            $car->images()->first()->update(['is_main' => true]);
        }

        return $car;
    }

    public function deleteCar($id)
    {
        $car = Car::findOrFail($id);
        foreach ($car->images as $image) {
            Storage::disk('public')->delete($image->path);
        }

        return $car->delete();
    }

    private function syncAddOns(Car $car, array $data)
    {
        if (isset($data['add_ons'])) {
            $syncData = [];
            foreach ($data['add_ons'] as $addOnId) {
                $syncData[$addOnId] = [
                    'custom_price' => $data['add_on_custom_prices'][$addOnId] ?? null,
                    'is_suggested_bundle' => (isset($data['suggested_bundle_id']) && $data['suggested_bundle_id'] == $addOnId),
                ];
            }
            $car->addOns()->sync($syncData);
        } else {
            $car->addOns()->detach();
        }
    }
}
