<?php

namespace App\Services;

use App\Models\Listing;
use App\Models\ListingCategory;
use App\Models\ListingFeature;
use App\Models\ListingFeatureValue;
use Illuminate\Validation\ValidationException;

class ListingFeatureService
{
    /**
     * Kategoriye atanmış feature'ları (pivot bilgisiyle) döndürür.
     * Frontend formu, dinamik alanları bu listeye göre çizer.
     */
    public function categoryFeatures(ListingCategory $category): array
    {
        return $category->features()
            ->where('listing_features.is_active', true)
            ->get()
            ->map(function (ListingFeature $feature) {
                return [
                    'id' => $feature->id,
                    'name' => $feature->name,
                    'key' => $feature->key,
                    'input_type' => $feature->input_type,
                    'unit' => $feature->unit,
                    'options' => $feature->options,
                    // Kanonik değer → aktif dil etiketi (görünüm için; değerler kanonik).
                    'option_labels' => $feature->localizedOptionLabels() ?: null,
                    'is_required' => (bool) $feature->pivot->is_required,
                    'sort_order' => (int) $feature->pivot->sort_order,
                ];
            })
            ->values()
            ->all();
    }

    /**
     * Gelen feature değerlerini, kategorinin tanımına ve feature tiplerine göre
     * doğrular. Hatalı/eksik değerlerde ValidationException fırlatır.
     * Dönen dizi: [feature_id => [value_text, value_number, value_boolean, value_json]]
     */
    public function validate(ListingCategory $category, array $input): array
    {
        $features = $category->features()
            ->where('listing_features.is_active', true)
            ->get();

        $errors = [];
        $prepared = [];

        foreach ($features as $feature) {
            $required = (bool) $feature->pivot->is_required;
            $hasValue = array_key_exists($feature->key, $input)
                && $input[$feature->key] !== null
                && $input[$feature->key] !== '';

            if (! $hasValue) {
                if ($required) {
                    $errors["features.{$feature->key}"][] = "{$feature->name} alanı zorunludur.";
                }
                continue;
            }

            $value = $input[$feature->key];
            $columns = ['value_text' => null, 'value_number' => null, 'value_boolean' => null, 'value_json' => null];

            switch ($feature->input_type) {
                case 'number':
                    if (! is_numeric($value)) {
                        $errors["features.{$feature->key}"][] = "{$feature->name} sayısal olmalıdır.";
                        continue 2;
                    }
                    $columns['value_number'] = $value;
                    break;

                case 'boolean':
                    $columns['value_boolean'] = filter_var($value, FILTER_VALIDATE_BOOLEAN);
                    break;

                case 'select':
                    if (is_array($feature->options) && ! in_array($value, $feature->options, true)) {
                        $errors["features.{$feature->key}"][] = "{$feature->name} için geçersiz seçim.";
                        continue 2;
                    }
                    $columns['value_text'] = (string) $value;
                    break;

                case 'multiselect':
                    $values = is_array($value) ? $value : [$value];
                    if (is_array($feature->options)) {
                        foreach ($values as $item) {
                            if (! in_array($item, $feature->options, true)) {
                                $errors["features.{$feature->key}"][] = "{$feature->name} için geçersiz seçim: {$item}";
                                continue 3;
                            }
                        }
                    }
                    $columns['value_json'] = array_values($values);
                    break;

                default: // text, date vb.
                    $columns['value_text'] = (string) $value;
                    break;
            }

            $prepared[$feature->id] = $columns;
        }

        if (! empty($errors)) {
            throw ValidationException::withMessages($errors);
        }

        return $prepared;
    }

    /**
     * Doğrulanmış feature değerlerini ilana yazar (upsert).
     * Bu kategoride artık geçerli olmayan eski değerleri temizler.
     */
    public function sync(Listing $listing, array $prepared): void
    {
        foreach ($prepared as $featureId => $columns) {
            ListingFeatureValue::updateOrCreate(
                ['listing_id' => $listing->id, 'feature_id' => $featureId],
                $columns
            );
        }

        // Bu güncellemede gönderilmeyen feature değerlerini sil.
        $listing->featureValues()
            ->whereNotIn('feature_id', array_keys($prepared))
            ->delete();
    }
}
