<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\AdminBundle\List;

use Ferienpass\CoreBundle\Entity\Debtor;
use Psr\EventDispatcher\EventDispatcherInterface;
use Twig\Attribute\AsTwigFunction;

/**
 * Single source for the debtors list rendering: the column/layout config used
 * by the {@see \Ferienpass\AdminBundle\Components\SearchableQueryableList}, and
 * the per-row render context used to replace a debtor's row in place via a
 * Turbo Stream after its balance changes (e.g. once an attendance is settled).
 */
final class DebtorsList
{
    public function __construct(private readonly EventDispatcherInterface $dispatcher)
    {
    }

    /**
     * Column/layout config consumed by the generic list component.
     */
    public function config(): array
    {
        return [
            'rightAlignedColumns' => ['balance', 'due', 'total'],
            'title' => <<<'TWIG'
                <div class="flex items-center space-x-2">
                {% if item.user|default %}
                <span class="inline-flex items-center justify-center h-6 w-6 rounded-full bg-gray-400 shrink-0">
                    <span class="text-xs font-medium leading-none text-white">{{ item.user.firstname|first|upper ~ item.user.lastname|first|upper }}</span>
                </span>
                {% endif %}
                <span>{{ item.user.name|default("") }}</span>
                </div>
                TWIG,
            'info' => [
                '{% set debit = (item.getDueSum(dispatcher))/100*(-1) %}{% set balance = item.balance/100 %}{% set debit_balance = debit+balance %}Gesamt: {{ debit_balance|format_currency("EUR", locale="de") }}',
                'Guthaben: {{ (item.balance/100)|format_currency("EUR", locale="de") }}',
            ],
            'aside' => '<div class="text-teal-700 dark:text-teal-400 font-semibold leading-6 shrink-0">{% set debit = (item.getDueSum(dispatcher))/100*(-1) %}{% set balance = item.balance/100 %}{% set debit_balance = debit+balance %}{{ debit_balance|format_currency("EUR", locale="de") }}</div>',
            'columns' => [
                'debtor' => <<<'TWIG'
                    <a href="{{ path("admin_payments_debtor", { uuid: item.uuid.toBase58 }) }}" class="hover:bg-gray-200/75 dark:hover:bg-gray-800 hover:text-gray-900 dark:hover:text-gray-100 rounded-md px-1.5 py-1 -mx-1.5 -my-1 transition-colors font-medium text-gray-900 dark:text-gray-100" data-turbo-frame="slideover">{{ item.user.name|default("") ?: item.id }}</a>
                    TWIG,
                'balance' => <<<'TWIG'
                    {% set editionAliases = routeParameters.edition is defined and routeParameters.edition ? routeParameters.edition|split('+') : [] %}
                    {% set balance = item.getBalance(editionAliases)/100 %}
                    {% set balanceFull = item.balance/100 %}
                    <p class="font-medium {{ balance > 0 ? 'text-green-600' : (balance < 0 ? 'text-red-600' : 'text-gray-600') }}">
                        {{ balance|format_currency("EUR", locale="de") }}
                    </p>
                    {% if editionAliases is not empty and balance != balanceFull %}
                        <p class="text-xs text-gray-400 dark:text-gray-500">{{ balanceFull|format_currency("EUR", locale="de") }}</p>
                    {% endif %}
                    TWIG,
                'due' => <<<'TWIG'
                    {% set editionAliases = routeParameters.edition is defined and routeParameters.edition ? routeParameters.edition|split('+') : [] %}
                    {% set debit = (item.getDueSum(dispatcher, editionAliases))/100*(-1) %}
                    {% set debitFull = (item.getDueSum(dispatcher))/100*(-1) %}
                    <p class="font-medium {{ debit > 0 ? 'text-green-600' : (debit < 0 ? 'text-red-600' : 'text-gray-600') }}">
                        {{ debit|format_currency("EUR", locale="de") }}
                    </p>
                    {% if editionAliases is not empty and debit != debitFull %}
                        <p class="text-xs text-gray-400 dark:text-gray-500">{{ debitFull|format_currency("EUR", locale="de") }}</p>
                    {% endif %}
                    TWIG,
                'total' => <<<'TWIG'
                    {% set editionAliases = routeParameters.edition is defined and routeParameters.edition ? routeParameters.edition|split('+') : [] %}
                    {% set debit = (item.getDueSum(dispatcher, editionAliases))/100*(-1) %}
                    {% set balance = item.getBalance(editionAliases)/100 %}
                    {% set debit_balance = debit+balance %}
                    {% set debitFull = (item.getDueSum(dispatcher))/100*(-1) %}
                    {% set balanceFull = item.balance/100 %}
                    {% set debit_balance_full = debitFull+balanceFull %}
                    <p class="font-medium {{ debit_balance > 0 ? 'text-green-600' : (debit_balance < 0 ? 'text-red-600' : 'text-gray-600') }}">
                        {{ debit_balance|format_currency("EUR", locale="de") }}
                    </p>
                    {% if editionAliases is not empty and debit_balance != debit_balance_full %}
                        <p class="text-xs text-gray-400 dark:text-gray-500">{{ debit_balance_full|format_currency("EUR", locale="de") }}</p>
                    {% endif %}
                    TWIG,
            ],
        ];
    }

    /**
     * Full `_list_row` / `_list_item` render context for a single debtor. The
     * settle slideover includes the row partials with this to replace the
     * debtor's row in the list via a Turbo Stream.
     *
     * @return array<string, mixed>
     */
    #[AsTwigFunction('debtor_row_context')]
    public function rowContext(Debtor $debtor, ?string $edition = null): array
    {
        return [
            ...$this->config(),
            'item' => $debtor,
            'dispatcher' => $this->dispatcher,
            'routeName' => 'admin_payments_debtors',
            'routeParameters' => array_filter(['edition' => $edition]),
            'translationPrefix' => 'payments',
            'selected' => [],
            'showActions' => true,
        ];
    }
}
