<?php

namespace App\Http\Controllers;

use App\Models\Agent;
use App\Models\PlatformProduct;
use App\Models\User;
use App\Services\ActivityLogger;
use App\Services\TenantLifecycleNotificationService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Illuminate\View\View;

class PublicAgentController extends Controller
{
    public function landing(): View
    {
        return view('public.agents-landing', [
            'agent' => null,
            'featuredAgents' => Agent::query()
                ->with('user')
                ->where('status', Agent::STATUS_ACTIVE)
                ->latest()
                ->limit(6)
                ->get(),
            'platformProducts' => $this->featuredProducts(),
        ]);
    }

    public function show(Agent $agent): View
    {
        abort_unless($agent->status === Agent::STATUS_ACTIVE, 404);

        $agent->load('user');

        return view('public.agents-landing', [
            'agent' => $agent,
            'featuredAgents' => collect(),
            'platformProducts' => $this->featuredProducts(),
        ]);
    }

    public function create(): View
    {
        return view('auth.register-agent');
    }

    public function store(Request $request, TenantLifecycleNotificationService $notifications): RedirectResponse
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'business_name' => ['nullable', 'string', 'max:255'],
            'email' => ['required', 'email', 'max:255', 'unique:users,email'],
            'phone' => ['nullable', 'string', 'max:50'],
            'country' => ['required', 'string', 'max:255'],
            'state' => ['required', 'string', 'max:255'],
            'city' => ['required', 'string', 'max:255'],
            'residential_address' => ['required', 'string', 'max:1000'],
            'bank_name' => ['nullable', 'string', 'max:255'],
            'account_name' => ['nullable', 'string', 'max:255'],
            'account_number' => ['nullable', 'string', 'max:30'],
            'merchant_type' => ['required', 'in:'.implode(',', array_keys(Agent::MERCHANT_TYPES))],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
        ]);

        [$user, $agent] = DB::transaction(function () use ($validated): array {
            $user = User::create([
                'role' => User::ROLE_AGENT,
                'name' => $validated['name'],
                'email' => $validated['email'],
                'phone' => $validated['phone'] ?? null,
                'password' => $validated['password'],
                'status' => 'active',
            ]);

            $agent = Agent::create([
                'user_id' => $user->id,
                'code' => $this->uniqueCode(),
                'slug' => $this->uniqueSlug($validated['business_name'] ?: $validated['name']),
                'business_name' => $validated['business_name'] ?? null,
                'commission_rate' => Agent::SELF_ONBOARDING_COMMISSION_RATE,
                'merchant_type' => $validated['merchant_type'],
                'onboarding_commission_rate' => Agent::SELF_ONBOARDING_COMMISSION_RATE,
                'referral_commission_rate' => Agent::REFERRAL_COMMISSION_RATE,
                'status' => Agent::STATUS_PENDING,
                'country' => filled($validated['country'] ?? null) ? $validated['country'] : 'Nigeria',
                'state' => $validated['state'] ?? null,
                'city' => $validated['city'] ?? null,
                'residential_address' => $validated['residential_address'] ?? null,
                'bank_name' => $validated['bank_name'] ?? null,
                'account_name' => $validated['account_name'] ?? null,
                'account_number' => $validated['account_number'] ?? null,
            ]);

            return [$user, $agent];
        });

        Auth::login($user);
        ActivityLogger::log('merchant_self_registered', $agent->displayName().' signed up as a merchant.', $agent);
        $notifications->merchantRegistered($agent->fresh('user'));

        return redirect()->route('merchant.dashboard')
            ->with('status', 'Your merchant account has been created. The super admin can activate commissions after review.');
    }

    private function uniqueSlug(string $name): string
    {
        $base = Str::slug($name) ?: 'merchant';
        $slug = $base;
        $counter = 2;

        while (Agent::query()->where('slug', $slug)->exists()) {
            $slug = $base.'-'.$counter++;
        }

        return $slug;
    }

    private function uniqueCode(): string
    {
        do {
            $code = 'MCH-'.Str::upper(Str::random(8));
        } while (Agent::query()->where('code', $code)->exists());

        return $code;
    }

    private function featuredProducts()
    {
        return PlatformProduct::query()
            ->where('is_active', true)
            ->orderByDesc('is_featured')
            ->orderBy('sort_order')
            ->orderBy('name')
            ->limit(8)
            ->get();
    }
}
