<?php
namespace App\Domain\Votes\Services;

use DB;
use Carbon\Carbon;
use App\Models\User;
use App\Domain\Points\Models\Point;
use App\Domain\Points\Enums\DirectionEnum;
use App\Domain\Subscriptions\Models\Subscription;
use App\Domain\Subscriptions\Service\SubscriptionService;

class VoteServiceOld
{
    public $vote;
    public $leaders;

    public function __construct($vote)
    {
        $leaders = SubscriptionService::leaders();
        $leaders = array_column(array_slice($leaders, 0, 2), 'user_id');
        $this->leaders = $leaders;
        $this->vote = $vote;
    }


    public function accrualPoints()
    {
        DB::beginTransaction();

        $procent_site = (int)$this->vote->procent_site;
        $procent_site = $procent_site / 100;
        $procent_top = (int)$this->vote->procent_top;
        $procent_top = $procent_top / 100;

        $subscriptions = Subscription::with('user.subscribers.subscription')->where('ends_at', '>', Carbon::now())
        ->where('status', 'complete')->get();

        $sum_site = 0;
        $sdr_leader_pay = 0;
        $sdr_users_pay = [];
        foreach ($subscriptions as $subscription) {
            $subscribers_simple = collect([]);
            $user = $subscription->user;

            $subscribers = $this->activeSubs($user->subscribers);
            $one_sub_is_leader = $this->oneLeaders($subscribers);

            if (! $one_sub_is_leader) {
                $subscribers_simple = $subscribers->filter(function ($subscriber) {
                    return ! in_array($subscriber->id, $this->leaders);
                });
            }

            $price = $subscription->price;
            $to_site = $price * $procent_site;
            $sum_site += $to_site;
            $sdr = round($price - $to_site);

            $sdr_leader = round($sdr * $procent_top);
            $sdr_simple = $sdr - $sdr_leader;

            if ($one_sub_is_leader) {
                //выплачиваем весь sdr если чел. подписан на лидеров, и у него больше нет простых
                $sdr_leader_pay += $sdr;
            } else {
                $sdr_leader_pay += $sdr_leader;
            }

            if ($subscribers_simple->isNotEmpty()) {
                //Выплачиваем каждому юзеру
                $sdr_parts = round($sdr_simple / $subscribers_simple->count());
                //сохраняем транзакции простых пользователей
                foreach ($subscribers_simple as $subs) {
                    $sdr_users_pay[$subs->id][] = $sdr_parts;
                }
            }

            $this->updateSubs($subscription);
        }

        $this->payForSimpleUser($sdr_users_pay);
        $this->payForLeaderUser($sdr_leader_pay);
        $this->payForSystemUser($sum_site);

        DB::commit();
    }

    public function payForSystemUser($sum_site)
    {
        $system_user_id = User::system()->id;
        $this->addPoint($system_user_id, $sum_site);
    }

    //оплата лидеров
    public function payForLeaderUser($sdr_leader_pay)
    {
        $part_for_leader = round($sdr_leader_pay/count($this->leaders));

        foreach ($this->leaders as $leader) {
            $this->addPoint($leader, $part_for_leader);
        }
    }

    //оплата обычных
    public function payForSimpleUser($sdr_users_pay)
    {
        $sdr_users_pay = array_map(function ($lines) {
            return array_sum($lines);
        }, $sdr_users_pay);

        foreach ($sdr_users_pay as $user_pay_id => $sdr_users) {
            $this->addPoint($user_pay_id, $sdr_users);
        }
    }

    public function addPoint($user_id, $amount)
    {
        $point = new Point;
        $point->user_id = $user_id;
        $point->point = $amount;
        $point->type = 'votes';  //YSV ENUM!
        $point->direction = DirectionEnum::COMING();
        $point->save();

        $this->vote->users()->attach($user_id, ['payment' => $amount]);
    }

    public function updateSubs($sub)
    {
        $sub->status = 'end'; //YSV ENUM!
        $sub->save();
    }

    // есть в списке только лидеры
    public function oneLeaders($subscribers)
    {
        if ($subscribers->count() <= count($this->leaders)) {
            $contains = $subscribers->filter(function ($subscriber) {
                return in_array($subscriber->id, $this->leaders);
            });
            if ($contains->count() === $subscribers->count()) {
                return true;
            }
        }
        return false;
    }

    //проверка на акт. подписки
    public function activeSubs($subscribers)
    {
        return $subscribers->filter(function ($subscriber) {
            return optional($subscriber->subscription->first())->ends_at > Carbon::now();
        });
    }
}
