<?php

declare(strict_types=1);

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Affiliate;
use App\Models\AffiliateCommission;
use App\Models\AffiliatePayout;
use App\Models\AuditLog;
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 index(Request $request): Response
    {
        $query = Affiliate::query()
            ->with('user:id,name,email')
            ->withCount('referrals', 'commissions');

        if ($request->filled('status') && $request->input('status') !== 'all') {
            $query->where('status', $request->input('status'));
        }

        if ($request->filled('search')) {
            $search = $request->input('search');
            $query->whereHas('user', function ($q) use ($search): void {
                $q->where('name', 'like', "%{$search}%")
                    ->orWhere('email', 'like', "%{$search}%");
            });
        }

        $affiliates = $query->latest()->paginate(25);

        return Inertia::render('Admin/Affiliates/Index', [
            'affiliates' => $affiliates,
            'filters' => [
                'status' => $request->input('status', 'all'),
                'search' => $request->input('search', ''),
            ],
        ]);
    }

    public function show(Affiliate $affiliate): Response
    {
        $affiliate->load('user:id,name,email');
        $affiliate->loadCount('referrals', 'commissions', 'payouts');

        $referrals = $affiliate->referrals()
            ->with('referredUser:id,name,email')
            ->latest()
            ->paginate(10, ['*'], 'referrals_page');

        $commissions = $affiliate->commissions()
            ->with('referral.referredUser:id,name,email')
            ->latest()
            ->paginate(10, ['*'], 'commissions_page');

        $payouts = $affiliate->payouts()
            ->latest()
            ->paginate(10, ['*'], 'payouts_page');

        return Inertia::render('Admin/Affiliates/Show', [
            'affiliate' => $affiliate,
            'referrals' => $referrals,
            'commissions' => $commissions,
            'payouts' => $payouts,
        ]);
    }

    public function approve(Request $request, Affiliate $affiliate): RedirectResponse
    {
        $this->affiliateService->approve($affiliate);

        AuditLog::create([
            'user_id' => $affiliate->user_id,
            'admin_id' => $request->user()->id,
            'action' => 'affiliate_approved',
            'resource_type' => 'Affiliate',
            'resource_id' => $affiliate->id,
            'ip_address' => $request->ip(),
            'user_agent' => $request->userAgent(),
        ]);

        return back()->with('success', 'Affiliate approved successfully.');
    }

    public function suspend(Request $request, Affiliate $affiliate): RedirectResponse
    {
        $affiliate->update(['status' => 'suspended']);

        AuditLog::create([
            'user_id' => $affiliate->user_id,
            'admin_id' => $request->user()->id,
            'action' => 'affiliate_suspended',
            'resource_type' => 'Affiliate',
            'resource_id' => $affiliate->id,
            'ip_address' => $request->ip(),
            'user_agent' => $request->userAgent(),
        ]);

        return back()->with('success', 'Affiliate suspended.');
    }

    public function commissions(Request $request): Response
    {
        $commissions = AffiliateCommission::query()
            ->where('status', 'pending')
            ->with([
                'affiliate.user:id,name,email',
                'referral.referredUser:id,name,email',
            ])
            ->latest()
            ->paginate(25);

        return Inertia::render('Admin/Affiliates/Commissions', [
            'commissions' => $commissions,
        ]);
    }

    public function approveCommission(Request $request, AffiliateCommission $commission): RedirectResponse
    {
        $this->affiliateService->approveCommission($commission);

        AuditLog::create([
            'user_id' => $commission->affiliate->user_id,
            'admin_id' => $request->user()->id,
            'action' => 'affiliate_commission_approved',
            'resource_type' => 'AffiliateCommission',
            'resource_id' => $commission->id,
            'ip_address' => $request->ip(),
            'user_agent' => $request->userAgent(),
            'changes' => ['amount' => (float) $commission->amount],
        ]);

        return back()->with('success', 'Commission approved successfully.');
    }

    public function payouts(Request $request): Response
    {
        $payouts = AffiliatePayout::query()
            ->whereIn('status', ['pending', 'processing'])
            ->with('affiliate.user:id,name,email')
            ->latest()
            ->paginate(25);

        return Inertia::render('Admin/Affiliates/Payouts', [
            'payouts' => $payouts,
        ]);
    }

    public function processPayout(Request $request, AffiliatePayout $payout): RedirectResponse
    {
        $this->affiliateService->processPayout($payout);

        AuditLog::create([
            'user_id' => $payout->affiliate->user_id,
            'admin_id' => $request->user()->id,
            'action' => 'affiliate_payout_processed',
            'resource_type' => 'AffiliatePayout',
            'resource_id' => $payout->id,
            'ip_address' => $request->ip(),
            'user_agent' => $request->userAgent(),
            'changes' => ['amount' => (float) $payout->amount, 'method' => $payout->method],
        ]);

        return back()->with('success', 'Payout processed successfully.');
    }

    public function settings(): Response
    {
        return Inertia::render('Admin/Affiliates/Settings', [
            'settings' => [
                'default_commission_type' => config('affiliate.default_commission_type'),
                'default_commission_rate' => config('affiliate.default_commission_rate'),
                'default_recurring_commissions' => config('affiliate.default_recurring_commissions'),
                'default_minimum_payout' => config('affiliate.default_minimum_payout'),
                'cookie_lifetime_days' => config('affiliate.cookie_lifetime_days'),
                'auto_approve' => config('affiliate.auto_approve'),
            ],
        ]);
    }
}
