<?php

namespace App\Http\Controllers\Api\Admin;

use App\Http\Controllers\Controller;
use App\Models\CategoryFeature;
use App\Models\ListingCategory;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;

class CategoryController extends Controller
{
    public function index()
    {
        $categories = ListingCategory::query()
            ->withCount(['listings', 'categoryFeatures'])
            ->orderBy('sort_order')
            ->get()
            ->map(fn ($c) => $this->toArray($c));

        return response()->json(['data' => $categories]);
    }

    public function store(Request $request)
    {
        $data = $this->validateData($request);

        $category = ListingCategory::create([
            'name' => $data['name'],
            'slug' => $data['slug'] ?? $this->uniqueSlug($data['name']),
            'description' => $data['description'] ?? null,
            'image' => $data['image'] ?? null,
            'image_alt' => $data['image_alt'] ?? null,
            'sort_order' => $data['sort_order'] ?? 0,
            'is_active' => $data['is_active'] ?? true,
            'is_featured' => $data['is_featured'] ?? false,
        ]);

        return response()->json(['data' => $this->toArray($category)], 201);
    }

    public function show(ListingCategory $category)
    {
        $category->load(['features']);

        return response()->json([
            'data' => array_merge($this->toArray($category), [
                'features' => $category->features->map(fn ($f) => [
                    'id' => $f->id,
                    'name' => $f->name,
                    'key' => $f->key,
                    'input_type' => $f->input_type,
                    'is_required' => (bool) $f->pivot->is_required,
                    'sort_order' => (int) $f->pivot->sort_order,
                ])->values(),
            ]),
        ]);
    }

    public function update(Request $request, ListingCategory $category)
    {
        $data = $this->validateData($request, $category->id);

        $category->update(array_filter([
            'name' => $data['name'] ?? $category->name,
            'slug' => $data['slug'] ?? $category->slug,
            'description' => $data['description'] ?? $category->description,
            'image' => $data['image'] ?? $category->image,
            'image_alt' => $data['image_alt'] ?? $category->image_alt,
            'sort_order' => $data['sort_order'] ?? $category->sort_order,
        ], fn ($v) => $v !== null) + [
            'is_active' => $data['is_active'] ?? $category->is_active,
            'is_featured' => $data['is_featured'] ?? $category->is_featured,
        ]);

        return response()->json(['data' => $this->toArray($category->fresh())]);
    }

    public function destroy(ListingCategory $category)
    {
        if ($category->listings()->exists()) {
            return response()->json([
                'message' => 'Bu kategoriye ait ilanlar var, silinemez.',
            ], 422);
        }

        $category->delete();

        return response()->json(['message' => 'Kategori silindi.']);
    }

    /**
     * Kategoriye atanmış feature'ları toptan günceller.
     * Body: { features: [{ feature_id, is_required, sort_order }] }
     */
    public function syncFeatures(Request $request, ListingCategory $category)
    {
        $data = $request->validate([
            'features' => ['present', 'array'],
            'features.*.feature_id' => ['required', 'integer', 'exists:listing_features,id'],
            'features.*.is_required' => ['boolean'],
            'features.*.sort_order' => ['integer'],
        ]);

        $keepIds = [];
        foreach ($data['features'] as $index => $item) {
            CategoryFeature::updateOrCreate(
                ['category_id' => $category->id, 'feature_id' => $item['feature_id']],
                [
                    'is_required' => $item['is_required'] ?? false,
                    'sort_order' => $item['sort_order'] ?? ($index + 1),
                ]
            );
            $keepIds[] = $item['feature_id'];
        }

        // Listede olmayan eski atamaları kaldır.
        CategoryFeature::where('category_id', $category->id)
            ->whereNotIn('feature_id', $keepIds)
            ->delete();

        return $this->show($category->fresh());
    }

    private function validateData(Request $request, ?int $ignoreId = null): array
    {
        return $request->validate([
            'name' => [$ignoreId ? 'sometimes' : 'required', 'string', 'max:255'],
            'slug' => ['nullable', 'string', 'max:255', Rule::unique('listing_categories', 'slug')->ignore($ignoreId)],
            'description' => ['nullable', 'string'],
            'image' => ['nullable', 'string', 'max:1000'],
            'image_alt' => ['nullable', 'string', 'max:255'],
            'sort_order' => ['nullable', 'integer'],
            'is_active' => ['nullable', 'boolean'],
            'is_featured' => ['nullable', 'boolean'],
        ]);
    }

    private function toArray(ListingCategory $category): array
    {
        return [
            'id' => $category->id,
            'name' => $category->name,
            'slug' => $category->slug,
            'description' => $category->description,
            'image' => $category->image,
            'image_alt' => $category->image_alt,
            'sort_order' => $category->sort_order,
            'is_active' => $category->is_active,
            'is_featured' => $category->is_featured,
            'listings_count' => $category->listings_count ?? null,
            'features_count' => $category->category_features_count ?? null,
        ];
    }

    private function uniqueSlug(string $name): string
    {
        $base = Str::slug($name) ?: 'category';
        $slug = $base;
        $i = 1;
        while (ListingCategory::where('slug', $slug)->exists()) {
            $slug = "{$base}-{$i}";
            $i++;
        }
        return $slug;
    }
}
