<?php

namespace App\Services;

use App\Models\Product;
use App\Models\ServiceProvider;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;

class ProductService
{
    public function getPackages(array $filters = []): Collection
    {
        $packages = Product::where('type', 'package')->available();
        if (isset($filters['city_id'])) {
            $packages->whereHas('cities', function ($query) use ($filters) {
                $query->where('city_id', $filters['city_id']);
            });
        }
        return $packages->get();
    }

    public function getServices(array $filters): Collection
    {
        $services = Product::where('type', 'service')->available();

        if (isset($filters['category_id'])) {
            $services->where('category_id', $filters['category_id']);
        }

        if (isset($filters['city_id'])) {
            $services->whereHas('cities', function ($query) use ($filters) {
                $query->where('city_id', $filters['city_id']);
            });
        }

        return $services->get();
    }

    public function getService(int $id): Product
    {
        return Product::where('type', 'service')->available()->findOrFail($id);
    }

    public function createProduct(array $data, ServiceProvider $provider): Product
    {
        DB::beginTransaction();
        try {
            $product = $provider->products()->create($data);

            $this->syncRelations($product, $data);
            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            throw $e;
        }
        return $product->refresh()->load(['media', 'cities', 'availabilities']);
    }

    public function updateProduct(array $data, Product $product): Product
    {
        DB::beginTransaction();
        try {
            $product->update($data);
            if (!isset($data['images'])) {
                $data['images'] = [];
            }
            if (!isset($data['videos'])) {
                $data['videos'] = [];
            }

            $this->syncRelations($product, $data, true);
            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            throw $e;
        }
        return $product->refresh()->load(['media', 'cities', 'availabilities']);
    }

    protected function syncRelations(Product $product, array $data, bool $is_update = false): void
    {
        if (isset($data['cities'])) {
            $product->cities()->sync($data['cities']);
        }

        if (isset($data['availabilities'])) {
            // $existingAvailabilities = $product->availabilities()->pluck('date')->toArray();
            // $newAvailabilities = $data['availabilities'];

            // $removedAvailabilities = array_diff($existingAvailabilities, $newAvailabilities);
            $conflictingBookings = $product->bookingItems()
                ->whereIn('service_date', $data['availabilities'])

                ->whereDate('service_date', '>=', now())
                ->pluck('service_date')
                ->toArray();
            if (!empty($conflictingBookings)) {
                $conflictingDates = implode(', ', $conflictingBookings);
                throw new \Exception(__('messages.conflicting_bookings_on_dates', ['dates' => $conflictingDates]));
            }

            $product->availabilities()->delete();
            $availabilities = [];
            foreach ($data['availabilities'] as $date) {
                $availabilities[] = ['date' => $date];
            }
            $product->availabilities()->createMany($availabilities);
        }

        if (isset($data['images'])) {
            // Handle image uploads and media creation
            if ($is_update) {
                $images_ids = array_map(fn($id) => (int)$id, $data['images']);
                $product->media()->where('collection_name', 'images')->whereNotIn('id', $images_ids)->delete();
            }
            foreach ($data['images'] as $image) {
                if ($image instanceof UploadedFile) {
                    $product->addMedia($image)->toMediaCollection('images');
                }
            }
        }
        if (isset($data['new_images'])) {
            foreach ($data['new_images'] as $image) {
                if ($image instanceof UploadedFile) {
                    $product->addMedia($image)->toMediaCollection('images');
                }
            }
        }

        if (isset($data['videos'])) {
            // Handle video uploads and media creation
            if ($is_update) {
                $images_ids = array_map(fn($id) => (int)$id, $data['videos']);
                $product->media()->where('collection_name', 'videos')->whereNotIn('id', $images_ids)->delete();
            }
            foreach ($data['videos'] as $video) {
                if ($video instanceof UploadedFile) {
                    $product->addMedia($video)->toMediaCollection('videos');
                }
            }
        }
        if (isset($data['new_videos'])) {
            foreach ($data['new_videos'] as $video) {
                if ($video instanceof UploadedFile) {

                    $product->addMedia($video)->toMediaCollection('videos');
                }
            }
        }
    }
}
