<?php

declare(strict_types=1);

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class StorePlanRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    /** @return array<string, array<int, mixed>> */
    public function rules(): array
    {
        $uniqueSlugRule = Rule::unique('plans', 'slug');

        if ($this->route('plan')) {
            $uniqueSlugRule->ignore($this->route('plan'));
        }

        return [
            'name' => ['required', 'string', 'max:255'],
            'slug' => ['required', 'string', 'max:255', $uniqueSlugRule],
            'description' => ['nullable', 'string'],
            'service_type' => ['required', Rule::in(['vps', 'dedicated', 'hosting', 'mysql', 'game', 'backups'])],
            'price' => ['required', 'numeric', 'min:0'],
            'billing_cycle' => ['required', Rule::in(['monthly', 'quarterly', 'semi_annual', 'annual'])],
            'features' => ['nullable', 'array'],
            'features.*.key' => ['required_with:features', 'string', 'max:255'],
            'features.*.value' => ['required_with:features', 'string', 'max:255'],
            'provisioning_config' => ['nullable', 'array'],
            'provisioning_config.package_id' => ['nullable', 'integer', Rule::requiredIf(fn () => in_array($this->input('service_type'), ['vps', 'dedicated']))],
            'provisioning_config.hypervisor_id' => ['nullable', 'integer'],
            'stock_quantity' => ['nullable', 'integer', 'min:0'],
            'sort_order' => ['integer', 'min:0'],
            'days_to_suspend' => ['nullable', 'integer', 'min:1'],
            'days_to_terminate' => ['nullable', 'integer', 'min:1'],
            'auto_suspend_enabled' => ['boolean'],
            'auto_terminate_enabled' => ['boolean'],
        ];
    }

    /** @return array<string, string> */
    public function messages(): array
    {
        return [
            'name.required' => 'Plan name is required.',
            'slug.required' => 'Slug is required.',
            'slug.unique' => 'This slug is already in use.',
            'service_type.required' => 'Service type is required.',
            'service_type.in' => 'Invalid service type selected.',
            'price.required' => 'Price is required.',
            'price.min' => 'Price must be at least 0.',
            'billing_cycle.required' => 'Billing cycle is required.',
            'billing_cycle.in' => 'Invalid billing cycle selected.',
        ];
    }

    /**
     * Get the features as a key-value array suitable for storing.
     *
     * @return array<string, string>|null
     */
    public function featuresForStorage(): ?array
    {
        $features = $this->input('features');

        if (empty($features) || ! is_array($features)) {
            return null;
        }

        $result = [];
        foreach ($features as $feature) {
            if (! empty($feature['key']) && isset($feature['value'])) {
                $result[$feature['key']] = $feature['value'];
            }
        }

        return empty($result) ? null : $result;
    }
}
