<?php

/*
 * CarController — CRUD-контроллер для управления автомобилями в административной панели.
 *
 * Создан: 2026-05-06
 * Маршруты: resource /admin/cars (index, create, store, edit, update, destroy)
 * Защита: middleware 'admin' → EnsureUserIsAdmin — только авторизованные администраторы
 * Зависимости: модель Car (app/Models/Car.php), DictSection (справочники для форм)
 */

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Car;
use App\Models\DictSection;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Storage;

class CarController extends Controller
{
    // Список с фильтрацией: текст (марка/модель/VIN/заголовок) + поля (статус, марка и др.)
    // paginate(20)->withQueryString() — сохраняет фильтры в ссылках страниц
    // Вьюха: resources/views/admin/cars/index.blade.php
    public function index(Request $request)
    {
        $query = Car::query()->orderByDesc('id');

        if ($request->filled('q')) {
            $q = '%'.$request->q.'%';
            $query->where(function ($qb) use ($q) {
                $qb->where('make', 'like', $q)
                    ->orWhere('model', 'like', $q)
                    ->orWhere('title', 'like', $q)
                    ->orWhere('vin', 'like', $q);
            });
        }

        foreach (['status', 'condition', 'make', 'engine_type', 'transmission', 'drive', 'platform'] as $field) {
            if ($request->filled($field)) {
                $query->where($field, $request->input($field));
            }
        }

        $cars = $query->paginate(20)->withQueryString();

        $makes = Car::select('make')->distinct()->orderBy('make')->pluck('make');

        // Площадки строго из справочника — чтобы отображались все, даже без привязанных авто
        $platformSection = DictSection::where('code', 'platforms')->with('values')->first();
        $platforms = $platformSection ? $platformSection->values->pluck('value') : collect();

        return view('admin.cars.index', compact('cars', 'makes', 'platforms'));
    }

    // Форма создания нового автомобиля
    // keyBy('code') — индексирует коллекцию по полю code для удобного доступа в шаблоне: $dictSections->get('makes')
    // Вьюха: resources/views/admin/cars/form.blade.php (общая для create и edit)
    public function create()
    {
        $dictSections = DictSection::with('values')->orderBy('sort_order')->get()->keyBy('code');

        return view('admin.cars.form', compact('dictSections'));
    }

    // Сохранение нового автомобиля: validated() → Car::create() → handlePhotos() → редирект
    public function store(Request $request)
    {
        $data = $this->validated($request);
        $car = Car::create($data);

        $this->handlePhotos($request, $car);
        Cache::flush(); // каталог с фильтрами — сбрасываем весь кеш при изменении авто

        return redirect()->route('admin.cars.index')->with('success', 'Автомобиль добавлен.');
    }

    // Форма редактирования: $car передаётся через route model binding по {car} в URL
    // Та же вьюха form.blade.php — внутри проверяется isset($car)
    public function edit(Car $car)
    {
        $dictSections = DictSection::with('values')->orderBy('sort_order')->get()->keyBy('code');

        return view('admin.cars.form', compact('car', 'dictSections'));
    }

    // Обновление данных автомобиля: логика аналогична store()
    public function update(Request $request, Car $car)
    {
        $data = $this->validated($request);
        $car->update($data);

        $this->handlePhotos($request, $car);
        Cache::flush(); // каталог с фильтрами — сбрасываем весь кеш при изменении авто

        return redirect()->route('admin.cars.index')->with('success', 'Автомобиль обновлён.');
    }

    // Удаление: сначала удаляет файлы с диска, затем запись из БД
    // photo_main и photos_gallery (JSON-массив) удаляются из Storage::disk('public')
    public function destroy(Car $car)
    {
        if ($car->photo_main) {
            Storage::disk('public')->delete($car->photo_main);
        }
        if ($car->photos_gallery) {
            foreach ($car->photos_gallery as $path) {
                Storage::disk('public')->delete($path);
            }
        }

        $car->delete();
        Cache::flush();

        return redirect()->route('admin.cars.index')->with('success', 'Автомобиль удалён.');
    }

    // Правила валидации для формы автомобиля — вынесены в приватный метод
    // чтобы не дублировать между store() и update(); фото-поля здесь не включены
    private function validated(Request $request): array
    {
        return $request->validate([
            'status' => 'required|in:active,sold,draft',
            'condition' => 'required|in:new,used',
            'make' => 'required|string|max:64',
            'model' => 'required|string|max:64',
            'generation' => 'nullable|string|max:64',
            'year' => 'required|integer|min:1900|max:2100',
            'vin' => 'nullable|string|max:17',
            'plate' => 'nullable|string|max:20',
            'body_type' => 'nullable|string|max:32',
            'doors' => 'nullable|integer|min:1|max:10',
            'color_exterior' => 'nullable|string|max:32',
            'color_interior' => 'nullable|string|max:32',
            'engine_type' => 'nullable|in:petrol,diesel,hybrid,electric,gas,other',
            'engine_volume' => 'nullable|numeric|min:0|max:99',
            'engine_power_hp' => 'nullable|integer|min:0|max:5000',
            'transmission' => 'nullable|in:manual,automatic,robot,variator,electric',
            'drive' => 'nullable|in:FWD,RWD,AWD,4WD',
            'mileage_km' => 'nullable|integer|min:0',
            'steering' => 'required|in:left,right',
            'owners_count' => 'nullable|integer|min:0',
            'customs_cleared' => 'nullable|boolean',
            'pts' => 'nullable|in:original,duplicate,electronic',
            'accident_free' => 'nullable|boolean',
            'price_usd' => 'nullable|integer|min:0',
            'price_rub' => 'nullable|integer|min:0',
            'price_vladivostok' => 'nullable|integer|min:0',
            'price_moscow' => 'nullable|integer|min:0',
            'price_negotiable' => 'nullable|boolean',
            'country_origin' => 'nullable|string|max:64',
            'city' => 'nullable|string|max:64',
            'platform' => 'required|string|max:64',
            'options' => 'nullable|array',
            'title' => 'nullable|string|max:128',
            'description' => 'nullable|string',
        ]);
    }

    // Загрузка и обновление фото: вызывается из store() и update() после сохранения записи
    // 1. photo_main — старый файл удаляется, новый → storage/app/public/cars/{id}/main/
    // 2. photos_gallery — новые фото добавляются к JSON-массиву → cars/{id}/gallery/
    // 3. delete_gallery — пути из формы → удаление файла + фильтрация массива + array_values()
    // Доступ через web: /storage/cars/... (требует: php artisan storage:link)
    private function handlePhotos(Request $request, Car $car): void
    {
        if ($request->hasFile('photo_main') && $request->file('photo_main')->isValid()) {
            if ($car->photo_main) {
                Storage::disk('public')->delete($car->photo_main);
            }
            $path = $request->file('photo_main')->store("cars/{$car->id}/main", 'public');
            $car->update(['photo_main' => $path]);
        }

        if ($request->hasFile('photos_gallery')) {
            $gallery = $car->photos_gallery ?? [];
            foreach ($request->file('photos_gallery') as $file) {
                if ($file->isValid()) {
                    $gallery[] = $file->store("cars/{$car->id}/gallery", 'public');
                }
            }
            $car->update(['photos_gallery' => $gallery]);
        }

        if ($request->filled('delete_gallery')) {
            $toDelete = (array) $request->input('delete_gallery');
            $gallery = $car->photos_gallery ?? [];
            foreach ($toDelete as $path) {
                Storage::disk('public')->delete($path);
                $gallery = array_filter($gallery, fn ($p) => $p !== $path);
            }
            $car->update(['photos_gallery' => array_values($gallery)]);
        }
    }
}
