<?php

declare(strict_types=1);

namespace App\Http\Controllers\Account;

use App\Http\Controllers\Controller;
use App\Http\Requests\RequestAffiliatePayoutRequest;
use App\Services\AffiliateService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;

class AffiliateController extends Controller
{
    public function __construct(
        private AffiliateService $affiliateService,
    ) {}

    public function dashboard(Request $request): Response
    {
        $user = $request->user();
        $affiliate = $user->affiliate;

        if (! $affiliate) {
            return Inertia::render('Account/Affiliate/Dashboard', [
                'affiliate' => null,
                'stats' => null,
            ]);
        }

        $affiliate->loadCount('referrals', 'commissions', 'payouts');

        $monthlyEarnings = $affiliate->commissions()
            ->where('created_at', '>=', now()->startOfMonth())
            ->sum('amount');

        $monthlyChart = $affiliate->commissions()
            ->selectRaw("DATE_FORMAT(created_at, '%Y-%m') as month, SUM(amount) as total")
            ->where('created_at', '>=', now()->subMonths(6))
            ->groupByRaw("DATE_FORMAT(created_at, '%Y-%m')")
            ->orderBy('month')
            ->get();

        return Inertia::render('Account/Affiliate/Dashboard', [
            'affiliate' => $affiliate,
            'stats' => [
                'total_earned' => (float) $affiliate->total_earned,
                'pending_balance' => (float) $affiliate->pending_balance,
                'total_paid' => (float) $affiliate->total_paid,
                'monthly_earnings' => (float) $monthlyEarnings,
                'referral_count' => $affiliate->referrals_count,
                'commission_count' => $affiliate->commissions_count,
            ],
            'monthlyChart' => $monthlyChart,
        ]);
    }

    public function referrals(Request $request): Response
    {
        $affiliate = $request->user()->affiliate;

        if (! $affiliate) {
            return redirect()->route('account.affiliate.dashboard');
        }

        $referrals = $affiliate->referrals()
            ->with('referredUser:id,name,email')
            ->latest()
            ->paginate(25);

        return Inertia::render('Account/Affiliate/Referrals', [
            'referrals' => $referrals,
            'affiliate' => $affiliate,
        ]);
    }

    public function commissions(Request $request): Response
    {
        $affiliate = $request->user()->affiliate;

        if (! $affiliate) {
            return redirect()->route('account.affiliate.dashboard');
        }

        $commissions = $affiliate->commissions()
            ->latest()
            ->paginate(25);

        return Inertia::render('Account/Affiliate/Commissions', [
            'commissions' => $commissions,
            'affiliate' => $affiliate,
        ]);
    }

    public function payouts(Request $request): Response
    {
        $affiliate = $request->user()->affiliate;

        if (! $affiliate) {
            return redirect()->route('account.affiliate.dashboard');
        }

        $payouts = $affiliate->payouts()
            ->latest()
            ->paginate(25);

        return Inertia::render('Account/Affiliate/Payouts', [
            'payouts' => $payouts,
            'affiliate' => $affiliate,
        ]);
    }

    public function requestPayout(RequestAffiliatePayoutRequest $request): RedirectResponse
    {
        $affiliate = $request->user()->affiliate;

        if (! $affiliate || $affiliate->status !== 'active') {
            return back()->with('error', 'You do not have an active affiliate account.');
        }

        try {
            $this->affiliateService->requestPayout(
                $affiliate,
                $request->validated('method'),
            );

            return back()->with('success', 'Payout request submitted successfully.');
        } catch (\InvalidArgumentException $e) {
            return back()->with('error', $e->getMessage());
        }
    }

    public function apply(Request $request): RedirectResponse
    {
        $user = $request->user();

        if ($user->affiliate) {
            return back()->with('error', 'You already have an affiliate account.');
        }

        $this->affiliateService->apply($user);

        return back()->with('success', 'Your affiliate application has been submitted for review.');
    }
}
