<?php

namespace App\Http\Controllers;

use App\Models\User;
use App\Models\LeadershipRank;
use App\Models\LeadershipClaim;
use App\Models\BalanceLog;
use App\Models\IncomeHistory;
use App\Models\GeneralSetting;
use App\Services\LeadershipService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class LeadershipController extends Controller
{
    public function myProgress(LeadershipService $svc)
    {
        $user  = auth()->user();
        $ranks = LeadershipRank::where('is_active', 1)->orderBy('sort_order')->get();
        $settings = GeneralSetting::first();

        $counts = $svc->progress($user);

        $claimCounts = LeadershipClaim::where('user_id', $user->id)
            ->selectRaw('rank_id, COUNT(*) as total')
            ->groupBy('rank_id')
            ->pluck('total', 'rank_id')
            ->toArray();

        $lastClaims = LeadershipClaim::where('user_id', $user->id)
            ->latest('claimed_at')
            ->get()
            ->groupBy('rank_id')
            ->map(fn ($g) => $g->first());

        return view('user.leadership.progress', compact('user', 'ranks', 'counts', 'claimCounts', 'lastClaims', 'settings'));
    }

    public function showRank(LeadershipService $svc, $key)
    {
        $user = auth()->user();
        $rank = LeadershipRank::where('is_active', 1)->where('key', $key)->firstOrFail();

        $counts = $svc->progress($user);

        $lastClaim = LeadershipClaim::where('user_id', $user->id)
            ->where('rank_id', $rank->id)
            ->latest('claimed_at')
            ->first();

        $cycleStartAt = $lastClaim?->claimed_at;
        if ($rank->count_start_at && (!$cycleStartAt || $rank->count_start_at->gt($cycleStartAt))) {
            $cycleStartAt = $rank->count_start_at;
        }

        $keepAfterUnverify = (bool)$rank->keep_count_after_unverify;
        $verifiedNow = $svc->verifiedCountForRank(
            $user,
            (bool)$rank->include_level2_verified,
            (bool)$rank->include_level3_verified,
            null,
            $keepAfterUnverify
        );

        $baseV = (int)($lastClaim->snapshot_verified ?? 0);
        $baseG = (int)($lastClaim->snapshot_gmail ?? 0);
        $baseF = (int)($lastClaim->snapshot_fb ?? 0);

        $cycleVerified = $svc->verifiedCountForRank(
            $user,
            (bool)$rank->include_level2_verified,
            (bool)$rank->include_level3_verified,
            $cycleStartAt,
            $keepAfterUnverify
        );
        $cycleGmail    = max(0, $counts['gmail']    - $baseG);
        $cycleFb       = max(0, $counts['fb']       - $baseF);

        $svcLevel1Total = $svc->level1($user, null, $keepAfterUnverify)->count();
        $svcLevel2Total = $svc->level2($user, null, $keepAfterUnverify)->count();
        $svcLevel3Total = $svc->level3($user, null, $keepAfterUnverify)->count();

        $verifiedRefs = $svc->level1($user, $cycleStartAt, $keepAfterUnverify)
            ->map(function ($u) {
                $u->level = 'L1';
                return $u;
            });

        if ($rank->include_level2_verified) {
            $level2 = $svc->level2($user, $cycleStartAt, $keepAfterUnverify)
                ->map(function ($u) {
                    $u->level = 'L2';
                    return $u;
                });
            $verifiedRefs = $verifiedRefs->merge($level2);
        }

        if ($rank->include_level3_verified) {
            $level3 = $svc->level3($user, $cycleStartAt, $keepAfterUnverify)
                ->map(function ($u) {
                    $u->level = 'L3';
                    return $u;
                });
            $verifiedRefs = $verifiedRefs->merge($level3);
        }

        $verifiedRefs = $verifiedRefs->sortByDesc('id')->values();
        $cycleLevel1Total = $verifiedRefs->where('level', 'L1')->count();
        $cycleLevel2Total = $verifiedRefs->where('level', 'L2')->count();
        $cycleLevel3Total = $verifiedRefs->where('level', 'L3')->count();

        $ordered = LeadershipRank::where('is_active', 1)
            ->orderBy('sort_order')
            ->orderBy('id')
            ->get()
            ->values();

        $position = $ordered->search(fn ($r) => $r->id === $rank->id);
        $position = ($position === false ? 0 : $position) + 1;

        $claimCount = LeadershipClaim::where('user_id', $user->id)
            ->where('rank_id', $rank->id)
            ->count();

        return view('user.leadership.rank-show', compact(
            'user', 'rank', 'counts', 'position', 'claimCount', 'verifiedRefs',
            'cycleVerified', 'cycleGmail', 'cycleFb', 'lastClaim', 'verifiedNow', 'cycleStartAt',
            'svcLevel1Total', 'svcLevel2Total', 'svcLevel3Total',
            'cycleLevel1Total', 'cycleLevel2Total', 'cycleLevel3Total'
        ));
    }

    public function claim(Request $request, LeadershipService $svc, $rankId)
    {
        $user = auth()->user();
        $rank = LeadershipRank::where('is_active', 1)->findOrFail($rankId);

        $counts = $svc->progress($user);

        $last = LeadershipClaim::where('user_id', $user->id)
            ->where('rank_id', $rank->id)
            ->latest('claimed_at')
            ->first();

        $cycleStartAt = $last?->claimed_at;
        if ($rank->count_start_at && (!$cycleStartAt || $rank->count_start_at->gt($cycleStartAt))) {
            $cycleStartAt = $rank->count_start_at;
        }

        $keepAfterUnverify = (bool)$rank->keep_count_after_unverify;
        $verifiedCount = $svc->verifiedCountForRank(
            $user,
            (bool)$rank->include_level2_verified,
            (bool)$rank->include_level3_verified,
            null,
            $keepAfterUnverify
        );

        $baseV = (int)($last->snapshot_verified ?? 0);
        $baseG = (int)($last->snapshot_gmail ?? 0);
        $baseF = (int)($last->snapshot_fb ?? 0);

        $cycleLevel1 = $svc->level1($user, $cycleStartAt, $keepAfterUnverify)->count();
        $cycleLevel2 = $rank->include_level2_verified
            ? $svc->level2($user, $cycleStartAt, $keepAfterUnverify)->count()
            : 0;
        $cycleLevel3 = $rank->include_level3_verified
            ? $svc->level3($user, $cycleStartAt, $keepAfterUnverify)->count()
            : 0;
        $cycleG = max(0, (int)$counts['gmail']    - $baseG);
        $cycleF = max(0, (int)$counts['fb']       - $baseF);

        $needLevel1 = (int)$rank->need_verified_members;
        $needLevel2 = (int)$rank->need_level2_members;
        $needLevel3 = (int)$rank->need_level3_members;

        $eligibleVerified =
            $cycleLevel1 >= $needLevel1 &&
            (!$rank->include_level2_verified || $cycleLevel2 >= $needLevel2) &&
            (!$rank->include_level3_verified || $cycleLevel3 >= $needLevel3);
        $eligible =
            $eligibleVerified &&
            $cycleG >= (int)$rank->need_gmail_completed &&
            $cycleF >= (int)$rank->need_fb_approved;

        if (!$eligible) {
            return back()->with('error', 'আপনি এখনো টার্গেট পূরণ করেননি।');
        }

        DB::transaction(function () use ($user, $rank, $counts, $verifiedCount) {

            LeadershipClaim::create([
                'user_id'            => $user->id,
                'rank_id'            => $rank->id,
                'reward_amount'      => (float)$rank->reward_amount,
                'claimed_at'         => now(),
                'snapshot_verified'  => (int)$verifiedCount,
                'snapshot_gmail'     => (int)$counts['gmail'],
                'snapshot_fb'        => (int)$counts['fb'],
            ]);

            $amount = (float)$rank->reward_amount;
            if ($amount > 0) {
                $user->increment('balance', $amount);

                BalanceLog::create(['user_id' => $user->id, 'amount' => $amount]);

                IncomeHistory::create([
                    'user_id'     => $user->id,
                    'source'      => 'leadership_reward',
                    'amount'      => $amount,
                    'description' => "অভিনন্দন! আপনি {$rank->name} অর্জন করে {$amount}৳ পেয়েছেন।",
                ]);
            }
        });

        return back()->with('success', "অভিনন্দন! {$rank->name} রিওয়ার্ড সফলভাবে ক্লেইম হয়েছে।");
    }

    public function history()
    {
        $user = auth()->user();
        $claims = LeadershipClaim::with('rank')
            ->where('user_id', $user->id)
            ->latest('claimed_at')
            ->get();

        return view('user.leadership.history', compact('claims'));
    }
}
