<?php

namespace Modules\Finance\ViewModels;

use Carbon\Carbon;
use Illuminate\Contracts\Routing\UrlRoutable;

class TransactionView implements UrlRoutable
{
    /**
     * @param  array<string, mixed>  $data
     */
    public function __construct(
        private readonly array $data,
    ) {}

    /**
     * @param  array<string, mixed>  $data
     */
    public static function fromArray(array $data): self
    {
        return new self($data);
    }

    /**
     * @param  list<array<string, mixed>>  $items
     * @return list<self>
     */
    public static function collection(array $items): array
    {
        return array_map(
            fn (array $item) => self::fromArray($item),
            $items
        );
    }

    public function __get(string $name): mixed
    {
        return match ($name) {
            'type' => (object) ['value' => (string) ($this->data['type'] ?? 'income')],
            'transaction_at' => Carbon::parse($this->data['transaction_at'] ?? now()),
            'amount' => (float) ($this->data['amount'] ?? 0),
            'reference_number' => $this->data['reference_number'] ?? null,
            'note' => $this->data['note'] ?? null,
            'id' => (int) ($this->data['id'] ?? 0),
            'income_category_id' => $this->data['income_category_id'] ?? ($this->data['income_category']['id'] ?? null),
            'expense_category_id' => $this->data['expense_category_id'] ?? ($this->data['expense_category']['id'] ?? null),
            default => $this->data[$name] ?? null,
        };
    }

    public function categoryName(): string
    {
        $type = (string) ($this->data['type'] ?? 'income');

        if ($type === 'income') {
            return (string) ($this->data['income_category']['name'] ?? $this->data['incomeCategory']['name'] ?? '—');
        }

        return (string) ($this->data['expense_category']['name'] ?? $this->data['expenseCategory']['name'] ?? '—');
    }

    public function getKey(): int
    {
        return (int) ($this->data['id'] ?? 0);
    }

    public function getRouteKey(): mixed
    {
        return $this->getKey();
    }

    public function getRouteKeyName(): string
    {
        return 'id';
    }

    public function resolveRouteBinding($value, $field = null): static
    {
        return $this;
    }

    public function resolveChildRouteBinding($childType, $value, $field = null): never
    {
        abort(404);
    }
}
