<?php

namespace App\Livewire\Modals;

use App\Domains\Link\Models\Link;
use App\Domains\Link\Models\LinkVariant;
use Illuminate\View\View;
use LivewireUI\Modal\ModalComponent;

class LinkVariants extends ModalComponent
{
    public string $linkUlid = '';

    public int $linkId = 0;

    public string $linkTarget = '';

    /** @var array<int, array{id: int|null, label: string, target_url: string, weight: int}> */
    public array $variants = [];

    public function mount(string $linkUlid): void
    {
        $link = Link::where('ulid', $linkUlid)->firstOrFail();

        $this->linkUlid = $linkUlid;
        $this->linkId = $link->id;
        $this->linkTarget = $link->target_url;

        $existing = $link->variants()->orderBy('id')->get();

        if ($existing->isEmpty()) {
            $this->variants = [
                ['id' => null, 'label' => 'Variant A', 'target_url' => $link->target_url, 'weight' => 50],
                ['id' => null, 'label' => 'Variant B', 'target_url' => '', 'weight' => 50],
            ];
        } else {
            $this->variants = $existing->map(fn ($v) => [
                'id' => $v->id,
                'label' => $v->label,
                'target_url' => $v->target_url,
                'weight' => $v->weight,
            ])->toArray();
        }
    }

    public function addVariant(): void
    {
        if (count($this->variants) >= 5) {
            return;
        }
        $this->variants[] = [
            'id' => null,
            'label' => 'Variant '.chr(64 + count($this->variants) + 1),
            'target_url' => '',
            'weight' => 0,
        ];
        $this->rebalanceWeights();
    }

    public function removeVariant(int $index): void
    {
        if (count($this->variants) <= 2) {
            return;
        }
        array_splice($this->variants, $index, 1);
        $this->rebalanceWeights();
    }

    public function rebalanceWeights(): void
    {
        $count = count($this->variants);
        if ($count === 0) {
            return;
        }
        $base = intdiv(100, $count);
        $remainder = 100 - ($base * $count);

        foreach ($this->variants as $i => &$variant) {
            $variant['weight'] = $base + ($i === 0 ? $remainder : 0);
        }
        unset($variant);
    }

    public function save(): void
    {
        $this->validate([
            'variants' => 'required|array|min:2|max:5',
            'variants.*.label' => 'required|string|max:64',
            'variants.*.target_url' => 'required|url|max:2048',
            'variants.*.weight' => 'required|integer|min:1|max:99',
        ]);

        $totalWeight = array_sum(array_column($this->variants, 'weight'));
        if ($totalWeight !== 100) {
            $this->addError('variants', 'Weights must sum to 100%.');

            return;
        }

        $existingIds = collect($this->variants)->pluck('id')->filter()->values()->all();

        LinkVariant::where('link_id', $this->linkId)
            ->whereNotIn('id', $existingIds)
            ->delete();

        foreach ($this->variants as $v) {
            if ($v['id']) {
                LinkVariant::where('id', $v['id'])->update([
                    'label' => $v['label'],
                    'target_url' => $v['target_url'],
                    'weight' => $v['weight'],
                ]);
            } else {
                LinkVariant::create([
                    'link_id' => $this->linkId,
                    'label' => $v['label'],
                    'target_url' => $v['target_url'],
                    'weight' => $v['weight'],
                ]);
            }
        }

        $this->dispatch('toast', message: 'A/B variants saved', type: 'success');
        $this->closeModal();
    }

    public static function modalMaxWidth(): string
    {
        return 'xl';
    }

    public function render(): View
    {
        return view('livewire.modals.link-variants');
    }
}
