<?php

declare(strict_types=1);

namespace Builder\Core\Foundation\Tables;

use Closure;

final class RowAction
{
    private string $label;

    private ?string $icon = null;

    private ?string $staticUrl = null;

    private ?Closure $urlUsing = null;

    private ?string $permission = null;

    private string $httpMethod = 'get';

    private bool $destructive = false;

    private ?string $confirmTitle = null;

    private ?string $confirmMessage = null;

    private function __construct(private readonly string $key)
    {
        $this->label = $key;
    }

    public static function make(string $key): self
    {
        return new self($key);
    }

    public function label(string $label): self
    {
        $this->label = $label;

        return $this;
    }

    public function icon(string $icon): self
    {
        $this->icon = $icon;

        return $this;
    }

    public function url(string $url): self
    {
        $this->staticUrl = $url;

        return $this;
    }

    /** @param Closure(array<string, mixed>): string $fn */
    public function urlUsing(Closure $fn): self
    {
        $this->urlUsing = $fn;

        return $this;
    }

    public function permission(string $permission): self
    {
        $this->permission = $permission;

        return $this;
    }

    public function method(string $method): self
    {
        $this->httpMethod = strtolower($method);

        return $this;
    }

    public function destructive(bool $value = true): self
    {
        $this->destructive = $value;

        return $this;
    }

    public function confirm(string $title, string $message): self
    {
        $this->confirmTitle = $title;
        $this->confirmMessage = $message;

        return $this;
    }

    public function getKey(): string
    {
        return $this->key;
    }

    public function getLabel(): string
    {
        return $this->label;
    }

    public function getIcon(): ?string
    {
        return $this->icon;
    }

    public function getPermission(): ?string
    {
        return $this->permission;
    }

    public function isDestructive(): bool
    {
        return $this->destructive;
    }

    public function getConfirmTitle(): ?string
    {
        return $this->confirmTitle;
    }

    public function getConfirmMessage(): ?string
    {
        return $this->confirmMessage;
    }

    /** @param array<string, mixed> $record */
    public function resolveUrl(array $record): ?string
    {
        if ($this->urlUsing !== null) {
            return ($this->urlUsing)($record);
        }

        return $this->staticUrl;
    }

    /**
     * @param  array<string, mixed>  $record
     * @return array<string, mixed>
     */
    public function toArray(array $record): array
    {
        return [
            'key' => $this->key,
            'label' => $this->label,
            'icon' => $this->icon,
            'url' => $this->resolveUrl($record),
            'method' => $this->httpMethod,
            'permission' => $this->permission,
            'destructive' => $this->destructive,
            'confirm' => $this->confirmTitle !== null ? [
                'title' => $this->confirmTitle,
                'message' => $this->confirmMessage,
            ] : null,
        ];
    }
}
