<?php

declare(strict_types=1);

namespace Maestro\Core\Modules\HourRegistration\Services;

use Illuminate\Validation\ValidationException;
use Maestro\Core\Modules\HourRegistration\Enums\HourRegistrationType;

final class HourLineTargetValidator
{
    /**
     * @param  array<string, mixed>  $payload
     *
     * @throws ValidationException
     */
    public function assertValidTargets(HourRegistrationType $type, array $payload): void
    {
        switch ($type) {
            case HourRegistrationType::Internal:
                $this->onlySet($payload, ['internal_category_id'], ['customer_id', 'hour_project_id', 'hour_task_id']);

                break;
            case HourRegistrationType::Customer:
                $this->onlySet($payload, ['customer_id'], ['internal_category_id', 'hour_project_id', 'hour_task_id']);

                break;
            case HourRegistrationType::Project:
                $this->onlySet($payload, ['hour_project_id'], ['internal_category_id', 'customer_id', 'hour_task_id']);

                break;
            case HourRegistrationType::Task:
                $this->onlySet($payload, ['hour_task_id'], ['internal_category_id', 'customer_id', 'hour_project_id']);

                break;
        }
    }

    /**
     * @param  array<string, mixed>  $payload
     * @param  list<string>  $requiredFkKeys
     * @param  list<string>  $mustBeUnset
     *
     * @throws ValidationException
     */
    private function onlySet(array $payload, array $requiredFkKeys, array $mustBeUnset): void
    {
        foreach ($mustBeUnset as $key) {
            if (($payload[$key] ?? null) !== null) {
                throw ValidationException::withMessages([
                    $key => ['Must not be set for this registration type.'],
                ]);
            }
        }

        foreach ($requiredFkKeys as $key) {
            if (! isset($payload[$key]) || $payload[$key] === '' || $payload[$key] === null) {
                throw ValidationException::withMessages([
                    $key => ["Field {$key} is required."],
                ]);
            }
        }
    }
}
