<?php

namespace App\State;

use ApiPlatform\Metadata\CollectionOperationInterface;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\Pagination\Pagination;
use ApiPlatform\State\Pagination\TraversablePaginator;
use ApiPlatform\State\ProviderInterface;
use App\ApiResource\SaleSummary;
use App\ApiResource\UserApi;
use App\Entity\User;
use App\Repository\UserRepository;
use Symfonycasts\MicroMapper\MicroMapperInterface;

class SaleSummaryStateProvider implements ProviderInterface
{
    public function __construct(
        private UserRepository$userRepository,
        private Pagination $pagination,
        private MicroMapperInterface $microMapper,
    )
    {
    }

    public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
    {
        if ($operation instanceof CollectionOperationInterface) {
            $currentPage = $this->pagination->getPage($context);
            $itemsPerPage = $this->pagination->getLimit($operation, $context);
            $offset = $this->pagination->getOffset($operation, $context);
            $salesSummaries = $this->createSaleSummaries($offset, $itemsPerPage);

            return new TraversablePaginator(
                new \ArrayIterator($salesSummaries),
                $currentPage,
                $itemsPerPage,
                count($salesSummaries),
            );
        }
        $user = $this->userRepository->find($uriVariables['userId']);
        if ($user !== null) {
            return $this->createSaleSummary($user);
        }
        return null;
    }

    private function createSaleSummaries(int $offset, int $limit = 50): array
    {
        $users = $this->userRepository->findBy([], [], $limit, $offset);
        $salesSummaries = [];
        /** @var User $user */
        foreach ($users as $user) {
            $salesSummary = $this->createSaleSummary($user);
            if ($salesSummary !== null) {
                $salesSummaries[] = $salesSummary;
            }
            $sales = $user->getSales();
        }
        usort($salesSummaries, function(SaleSummary $a, SaleSummary $b) {
            return $b->turnover - $a->turnover;
        });
        return $salesSummaries;
    }

    private function createSaleSummary(User $user)
    {
        $sales = $user->getSales();
        $salesSummary = new SaleSummary($user->getId());
        $salesSummary->owner = $this->microMapper->map($user, UserApi::class);
        $salesSummary->turnover = 0;
        $salesSummary->profit = 0;
        if (count($sales) > 0) {
            foreach ($sales as $sale) {
                $salesSummary->turnover += $sale->getTurnover();
                $salesSummary->profit += $sale->getProfit();
            }
        }
        return $salesSummary;
    }
}
