<?php

namespace App\Http\Controllers\Invest\Admin;

use App\Enums\LedgerTnxType;
use App\Enums\InvestmentStatus;
use App\Models\IvInvest;
use App\Models\IvLedger;
use App\Models\IvProfit;

use App\Filters\LedgerFilter;
use App\Filters\ProfitFilter;
use App\Services\InvestormService;
use App\Services\Investment\IvProfitCalculator;
use App\Traits\WrapInTransaction;


use Illuminate\Support\Arr;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class LedgerProfitsController extends Controller
{
    use WrapInTransaction;

    private $investment;

    public function __construct(InvestormService $investment)
    {
        $this->investment = $investment;
    }

    public function transactionList(Request $request, $type = null)
    {
        $input = array_filter($request->only(['type', 'source', 'query']));
        $filterCount = count(array_filter($input, function ($item) {
            return !empty($item) && $item !== 'any';
        }));
        $filter = new LedgerFilter(new Request(array_merge($input, ['type' => $type ?? $request->get('type')])));
        $ledgers = get_enums(LedgerTnxType::class, false);
        $sources = [AccType('main'), AccType('invest')];

        $transactionQuery = IvLedger::orderBy('id', user_meta('iv_tnx_order', 'desc'))
            ->filter($filter);

        $transactions = $transactionQuery->paginate(user_meta('iv_tnx_perpage', 10))->onEachSide(0);


        return view('investment.admin.statement.transactions', [
            'transactions' => $transactions,
            'sources' => $sources,
            'ledgers' => $ledgers,
            'type' => $type ?? 'all',
            'filter_count' => $filterCount,
            'input' => $input,
        ]);
    }

    public function profitList(Request $request, ProfitFilter $filter, $type = null)
    {
        $profitQuery = IvProfit::orderBy('id', user_meta('iv_profit_order', 'desc'))->with(['invest', 'invest_by'])
            ->filter($filter);

        if ($type == 'pending') {
            $profitQuery->whereNull('payout');
        }

        $profits = $profitQuery->paginate(user_meta('iv_profit_perpage', 20))->onEachSide(0);

        return view('investment.admin.statement.profits', [
            'profits' => $profits,
            'type' => $type ?? 'all'
        ]);
    }

    public function profitsPayout(Request $request)
    {
        $payoutPending = IvProfit::whereNull('payout')->orderBy('id', 'asc')->get()->groupBy('user_id');

        if (!blank($payoutPending)) {
            foreach ($payoutPending as $user_id => $profits) {
                $this->wrapInTransaction(function ($profits, $user_id) {
                    $profit_ids = $profits->keyBy('id')->keys()->toArray();
                    $this->investment->proceedPayout($user_id, $profit_ids);
                }, $profits, $user_id);
            }
        }

        $invests = IvInvest::where('status', InvestmentStatus::ACTIVE)->get();
        if (!blank($invests)) {
            foreach ($invests as $invest) {
                $this->wrapInTransaction(function ($invest) {
                    $this->investment->processCompleteInvestment($invest);
                }, $invest);
            }
        }

        if (blank($payoutPending)) {
            return response()->json(['type' => 'info', 'title' => __('Nothing to do!'), 'msg' => __('No pending profits to adjust into account.')]);
        }

        $reload = ($request->get('reload') == true) ? 1200 : false;
        return response()->json([
            'title' => __('Paid the Profit to Investors'),
            'msg' => __('The profits paid & available in invstors account.'),
            'reload' => $reload
        ]);
    }
}
