<?php

namespace Modules\Mailgateway\Components;

use App\Mailgateway\Models\Mailgateway;
use App\Mailgateway\Types\Type;
use Illuminate\Support\Collection;
use Illuminate\Validation\ValidationException;
use Livewire\Attributes\On;
use Livewire\Attributes\Validate;
use Livewire\Component;

class Form extends Component
{

    public string $name = '';
    public string $domain = '';
    public ?Type $type = null;
    #[Validate('required|string')]
    public ?string $typeClass = null;
    public Collection $types;
    public ?Mailgateway $model = null;

    public function rules()
    {
        return [
            'name' => 'required|string|max:255',
            'domain' => 'required|string|max:255',
            ...$this->type ? collect($this->type::rules())->mapWithKeys(fn ($rules, $key) => ["type.{$key}" => $rules]) : [],
        ];
    }

    public function validationAttributes(): array
    {
        return [
            'type' => 'Typ',
            'name' => 'Beschreibung',
            'domain' => 'Domain',
            ...$this->type ? collect($this->type::fieldNames())->mapWithKeys(fn ($attribute, $key) => ["params.{$key}" => $attribute]) : [],
        ];
    }

    public function mount(?string $id = null): void
    {
        $this->types = app('mail-gateways')->map(fn ($gateway) => [
            'name' => $gateway::name(),
            'id' => $gateway,
        ]);

        if ($id) {
            $this->model = Mailgateway::find($id);
            $this->name = $this->model->name;
            $this->domain = $this->model->domain;
            $this->type = $this->model->type;
            $this->typeClass = get_class($this->model->type);
        }
    }

    public function fields(): array
    {
        return $this->type ? $this->type::fields() : [];
    }

    public function updatedTypeClass(?string $type): void
    {
        if (!$type) {
            return;
        }

        $this->type = $type::from([]);
    }

    #[On('onStoreFromModal')]
    public function onSave(): void
    {
        $this->validate();

        if (!$this->type->works()) {
            throw ValidationException::withMessages(['connection' => 'Verbindung fehlgeschlagen.']);
        }

        $payload = [
            'name' => $this->name,
            'domain' => $this->domain,
            'type' => $this->type,
        ];
        if ($this->model) {
            $this->model->update($payload);
        } else {
            Mailgateway::create($payload);
        }
        $this->dispatch('closeModal');
        $this->dispatch('refresh-page');
        $this->dispatch('success', 'Erfolgreich gespeichert.');
    }

    public function render()
    {
        return <<<'HTML'
            <div>
                <form class="grid grid-cols-2 gap-3">
                    <x-form::text name="name" wire:model="name" label="Beschreibung" required />
                    <x-form::text name="domain" wire:model="domain" label="Domain" required />
                    <x-form::select name="typeClass" wire:model.live="typeClass" label="Typ" :options="$types" required />
                    @foreach($this->fields() as $index => $field)
                        <x-form::text
                            wire:key="index"
                            wire:model="type.{{$field['name']}}"
                            :label="$field['label']"
                            :type="$field['type']"
                            :name="$field['name']"
                            :required="str_contains('required', $field['validator'])"
                        ></x-form::text>
                    @endforeach
                </form>
            </div>
        HTML;
    }
}