<?php

namespace App;

use App\Models\ImportCondition;
use Illuminate\Support\Collection;
use Mtc\MercuryDataModels\BodyStyleType;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\Franchise;
use Mtc\MercuryDataModels\FuelType;
use Mtc\MercuryDataModels\Label;
use Mtc\MercuryDataModels\TransmissionType;
use Mtc\MercuryDataModels\VehicleMake;
use Mtc\MercuryDataModels\VehicleModel;

class ImportConditionRepository
{
    protected static array $vehicle_fields = [
        [
            'name' => 'type',
            'type' => 'enum',
        ],
        [
            'name' => 'vrm_condensed',
            'type' => 'value_field',
        ],
        [
            'name' => 'vin',
            'type' => 'value_field',
        ],
        [
            'name' => 'make_id',
            'type' => 'related_model',
        ],
        [
            'name' => 'model_id',
            'type' => 'related_model',
        ],
        [
            'name' => 'dealership_id',
            'type' => 'related_model',
        ],
        [
            'name' => 'body_style_id',
            'type' => 'related_model',
        ],
        [
            'name' => 'fuel_type_id',
            'type' => 'related_model',
        ],
        [
            'name' => 'transmission_id',
            'type' => 'related_model',
        ],
        [
            'name' => 'image_count',
            'type' => 'relation_count',
        ],
        [
            'name' => 'finance_count',
            'type' => 'relation_count',
        ],
        [
            'name' => 'price',
            'type' => 'value_field',
        ],
        [
            'name' => 'monthly_price',
            'type' => 'value_field',
        ],
        [
            'name' => 'age',
            'type' => 'value_field',
        ],
        [
            'name' => 'age_months',
            'type' => 'value_field',
        ],
        [
            'name' => 'odometer',
            'type' => 'value_field',
        ],
        [
            'name' => 'label',
            'type' => 'related_model',
        ],
    ];

    protected static array $new_car_fields = [
        [
            'name' => 'make_id',
            'type' => 'related_model',
        ],
        [
            'name' => 'model_id',
            'type' => 'related_model',
        ],
        [
            'name' => 'franchise_id',
            'type' => 'related_model',
        ],
        [
            'name' => 'dealership_id',
            'type' => 'related_model',
        ],
        [
            'name' => 'body_style_id',
            'type' => 'related_model',
        ],
        [
            'name' => 'fuel_type_id',
            'type' => 'related_model',
        ],
        [
            'name' => 'image_count',
            'type' => 'relation_count',
        ],
        [
            'name' => 'price',
            'type' => 'value_field',
        ],
    ];

    protected static array $conditions = [
        [
            'value' => '=',
            'applicable_to' => [
                'related_model',
                'relation_count',
                'value_field',
                'enum',
            ]
        ],
        [
            'value' => '!=',
            'applicable_to' => [
                'related_model',
                'relation_count',
                'value_field',
                'enum',
            ]
        ],
        [
            'value' => '>',
            'applicable_to' => [
                'relation_count',
                'value_field',
            ]
        ],
        [
            'value' => '>=',
            'applicable_to' => [
                'relation_count',
                'value_field',
            ]
        ],
        [
            'value' => '<',
            'applicable_to' => [
                'relation_count',
                'value_field',
            ]
        ],
        [
            'value' => '<=',
            'applicable_to' => [
                'relation_count',
                'value_field',
            ]
        ],
        [
            'value' => 'is_null',
            'applicable_to' => [
                'relation_count',
                'value_field',
            ]
        ],
        [
            'value' => 'exists',
            'applicable_to' => [
                'value_field',
            ]
        ],
        [
            'value' => 'in',
            'applicable_to' => [
                'related_model',
                'value_field',
                'enum',
            ]
        ],
        [
            'value' => 'not_in',
            'applicable_to' => [
                'related_model',
                'value_field',
                'enum',
            ]
        ],
    ];

    public function update(ImportCondition $condition, array $input): void
    {
        $condition->update($input);
        $rules = collect($input['rules'] ?? [])
            ->map(fn($rule) => $this->normalizeRuleValue($rule));

        // Remove rules not in list
        $condition->rules()
            ->whereNotIn('id', $rules->pluck('id'))
            ->delete();

        // Add/Update rules
        $rules->each(fn($rule) => $condition->rules()->updateOrCreate([ 'id' => $rule['id'] ], $rule));
    }

    /**
     * Normalize rule value - convert arrays to JSON for in/not_in conditions.
     */
    private function normalizeRuleValue(array $rule): array
    {
        if (is_array($rule['value'] ?? null)) {
            $rule['value'] = json_encode($rule['value']);
        }

        return $rule;
    }

    public function getFields(?string $type = null): Collection
    {
        $fields = $type === 'new_car' ? self::$new_car_fields : self::$vehicle_fields;

        return collect($fields)
            ->map(fn($field) => [
                'id' => $field['name'],
                'name' => __('vehicles.' . $field['name']),
            ]);
    }

    public function getConditions(?string $field, ?string $type = null): Collection
    {
        if (empty($field)) {
            return collect();
        }

        $fields = $type === 'new_car' ? self::$new_car_fields : self::$vehicle_fields;

        $field_type = collect($fields)
            ->filter(fn($row) => $row['name'] === $field)
            ->first()['type'] ?? null;

        if (empty($field_type)) {
            return collect();
        }

        return collect(self::$conditions)
            ->filter(fn($condition) => in_array($field_type, $condition['applicable_to']))
            ->map(fn($condition) => [
                'id' => $condition['value'],
                'name' => __('labels.conditions.' . $condition['value']),
            ])
            ->values();
    }

    public function getValues(?string $field, ?string $condition): Collection
    {
        if (empty($field)) {
            return collect();
        }

        return match ($field) {
            'type' => collect(VehicleType::cases())
                ->map(fn(VehicleType $value) => [
                    'id' => $value->value,
                    'name' => $value->name,
                ]),
            'make_id' => VehicleMake::query()->select('id', 'name')->get(),
            'model_id' => VehicleModel::query()->select('id', 'name')->get(),
            'dealership_id' => Dealership::query()->select('id', 'name')->get(),
            'franchise_id' => Franchise::query()->select('id', 'name')->get(),
            'fuel_type_id' => FuelType::query()->select('id', 'name')->get(),
            'transmission_id' => TransmissionType::query()->select('id', 'name')->get(),
            'body_style_id' => BodyStyleType::query()->select('id', 'name')->get(),
            'label' => Label::query()->select('id', 'name')->where('active', true)->get(),
            default => collect(),
        };
    }

    public function getValue(string $field, $id)
    {
        return match ($field) {
            'make_id' => VehicleMake::query()->find($id)?->name ?? '',
            'model_id' => VehicleModel::query()->find($id)?->name ?? '',
            'dealership_id' => Dealership::query()->find($id)?->name ?? '',
            'franchise_id' => Franchise::query()->find($id)?->name ?? '',
            'fuel_type_id' => FuelType::query()->find($id)?->name ?? '',
            'transmission_id' => TransmissionType::query()->find($id)?->name ?? '',
            'body_style_id' => BodyStyleType::query()->find($id)?->name ?? '',
            'label' => Label::query()->find($id)?->name ?? '',
            default => $id,
        };
    }
}
