<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use App\Models\BinaryLedger;
use App\Models\MemberTreeClosure;
use App\Models\Rank;
use App\Models\UserBinaryCarry;
use App\Models\WalletBalance;
use App\Models\WalletTransaction;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Contracts\View\View;
use Illuminate\Http\JsonResponse;

class DashboardController extends Controller
{
    public function index(): View
    {
        $user = auth()->user();
        $payload = $this->buildDashboardData($user);
        return view('user.dashboard', [
            'stats' => $payload['stats'],
            'labels' => $payload['labels'],
            'incomeSeries' => $payload['incomeSeries'],
            'joiningSeries' => $payload['joiningSeries'],
            'bonusLabels' => $payload['bonusLabels'],
            'bonusSeries' => $payload['bonusSeries'],
            'links' => $payload['links'],
            'autoLeg' => $payload['autoLeg'],
            'sponsor' => $user->sponsor,
        ]);
    }

    public function metrics(): JsonResponse
    {
        return response()->json($this->buildDashboardData(auth()->user()));
    }

    private function buildDashboardData(User $user): array
    {
        $wallet = WalletBalance::query()->where('user_id', $user->id)->first();
        $carry = UserBinaryCarry::query()->firstOrCreate(['user_id' => $user->id]);
        $today = now()->toDateString();

        $todayIncome = (float) WalletTransaction::query()
            ->where('user_id', $user->id)
            ->where('wallet_type', 'income')
            ->where('direction', 'credit')
            ->whereDate('transacted_at', $today)
            ->sum('amount');

        $totalIncome = (float) WalletTransaction::query()
            ->where('user_id', $user->id)
            ->where('wallet_type', 'income')
            ->where('direction', 'credit')
            ->sum('amount');

        $todayBv = (float) BinaryLedger::query()
            ->where('beneficiary_user_id', $user->id)
            ->whereIn('ledger_type', ['joining', 'repurchase', 'reversal_joining', 'reversal_repurchase'])
            ->whereDate('posted_at', $today)
            ->selectRaw("COALESCE(SUM(CASE WHEN direction = 'credit' THEN units ELSE -units END), 0) as total")
            ->value('total');

        $leftBusiness = (float) BinaryLedger::query()
            ->where('beneficiary_user_id', $user->id)
            ->where('leg', 'left')
            ->whereIn('ledger_type', ['repurchase', 'joining'])
            ->selectRaw("COALESCE(SUM(CASE WHEN direction = 'credit' THEN units ELSE -units END), 0) as total")
            ->value('total');

        $rightBusiness = (float) BinaryLedger::query()
            ->where('beneficiary_user_id', $user->id)
            ->where('leg', 'right')
            ->whereIn('ledger_type', ['repurchase', 'joining'])
            ->selectRaw("COALESCE(SUM(CASE WHEN direction = 'credit' THEN units ELSE -units END), 0) as total")
            ->value('total');

        $leftTeam = (int) MemberTreeClosure::query()
            ->where('ancestor_id', $user->id)
            ->where('path_leg', 'left')
            ->where('depth', '>', 0)
            ->count();

        $rightTeam = (int) MemberTreeClosure::query()
            ->where('ancestor_id', $user->id)
            ->where('path_leg', 'right')
            ->where('depth', '>', 0)
            ->count();

        $matchingIncome = (float) WalletTransaction::query()
            ->where('user_id', $user->id)
            ->where('wallet_type', 'income')
            ->where('direction', 'credit')
            ->whereIn('source_type', ['binary_matching', 'joining_matching'])
            ->sum('amount');

        $directIncome = (float) WalletTransaction::query()
            ->where('user_id', $user->id)
            ->where('wallet_type', 'income')
            ->where('direction', 'credit')
            ->whereIn('source_type', ['direct_income', 'direct_bonus', 'referral_income', 'direct'])
            ->sum('amount');

        $rankName = $user->current_rank_id
            ? (string) Rank::query()->whereKey($user->current_rank_id)->value('name')
            : null;

        $walletTotal = (float) (
            (optional($wallet)->income_balance ?? 0)
            + (optional($wallet)->repurchase_balance ?? 0)
            + (optional($wallet)->withdrawable_balance ?? 0)
        );

        $autoLeg = $leftBusiness <= $rightBusiness ? 'left' : 'right';

        $labels = [];
        $incomeSeries = [];
        $joiningSeries = [];
        for ($i = 6; $i >= 0; $i--) {
            $date = Carbon::now()->subDays($i)->toDateString();
            $labels[] = $date;
            $incomeSeries[] = (float) WalletTransaction::query()
                ->where('user_id', $user->id)
                ->where('wallet_type', 'income')
                ->where('direction', 'credit')
                ->whereDate('transacted_at', $date)
                ->sum('amount');
            $joiningSeries[] = (int) User::query()
                ->where('sponsor_id', $user->id)
                ->whereDate('created_at', $date)
                ->count();
        }

        $bonusRows = WalletTransaction::query()
            ->where('user_id', $user->id)
            ->where('wallet_type', 'income')
            ->where('direction', 'credit')
            ->selectRaw("COALESCE(NULLIF(source_type, ''), 'other') as source, SUM(amount) as total")
            ->groupByRaw("COALESCE(NULLIF(source_type, ''), 'other')")
            ->orderByDesc('total')
            ->limit(6)
            ->get();
        $bonusLabels = $bonusRows->pluck('source')->map(fn ($label) => ucfirst(str_replace('_', ' ', (string) $label)))->values();
        $bonusSeries = $bonusRows->pluck('total')->map(fn ($value) => (float) $value)->values();

        $stats = [
            'wallet_balance' => $walletTotal,
            'withdrawable_balance' => (float) (optional($wallet)->withdrawable_balance ?? 0),
            'today_income' => $todayIncome,
            'total_income' => $totalIncome,
            'today_bv' => $todayBv,
            'carry_forward_left' => (float) $carry->repurchase_left,
            'carry_forward_right' => (float) $carry->repurchase_right,
            'rank' => $rankName,
            'active_directs' => (int) User::query()
                ->where('sponsor_id', $user->id)
                ->where('status', 'active')
                ->count(),
            'team_left' => $leftTeam,
            'team_right' => $rightTeam,
            'left_business' => $leftBusiness,
            'right_business' => $rightBusiness,
            'matching_income' => $matchingIncome,
            'direct_income' => $directIncome,
        ];

        $links = [
            'left' => url('/register-user').'?sponsor='.$user->referral_code.'&leg=left',
            'right' => url('/register-user').'?sponsor='.$user->referral_code.'&leg=right',
            'auto' => url('/register-user').'?sponsor='.$user->referral_code.'&leg=auto',
        ];

        return [
            'stats' => $stats,
            'labels' => $labels,
            'incomeSeries' => $incomeSeries,
            'joiningSeries' => $joiningSeries,
            'bonusLabels' => $bonusLabels,
            'bonusSeries' => $bonusSeries,
            'links' => $links,
            'autoLeg' => $autoLeg,
        ];
    }
}
