<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\Invite;
use App\Models\RegistrationRequest;
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rules;
use Illuminate\View\View;

class RegisteredUserController extends Controller
{
    /**
     * Display the registration view.
     */
    public function create(Request $request): View
    {
        // Check for invite token
        if ($request->has('invite_token')) {
            $invite = Invite::where('token', $request->invite_token)->first();
            
            // Check if invite exists and is valid
            if ($invite && !$invite->used && (!$invite->expires_at || $invite->expires_at > now())) {
                return view('auth.register', compact('invite'));
            }
        }
        
        // Check for signup request ID
        if ($request->has('signup_request_id')) {
            $signupRequest = RegistrationRequest::find($request->signup_request_id);
            
            // Check if request exists and is approved
            if ($signupRequest && $signupRequest->status === 'approved') {
                return view('auth.register', compact('signupRequest'));
            }
        }
        
        // Default public registration
        return view('auth.register');
    }

    /**
     * Handle an incoming registration request.
     *
     * @throws \Illuminate\Validation\ValidationException
     */
    public function store(Request $request): RedirectResponse
    {
        // Priority 1: Invite token
        if ($request->has('invite_token')) {
            return $this->registerWithInvite($request);
        }
        
        // Priority 2: Signup request ID
        if ($request->has('signup_request_id')) {
            return $this->registerWithSignupRequest($request);
        }
        
        // Priority 3: Default public registration
        return $this->registerPublic($request);
    }
    
    /**
     * Register user with invite token
     */
    protected function registerWithInvite(Request $request): RedirectResponse
    {
        $request->validate([
            'invite_token' => ['required', 'string'],
            'name' => ['required', 'string', 'max:255'],
            'password' => ['required', 'confirmed', Rules\Password::defaults()],
        ]);
        
        // Find the invite
        $invite = Invite::where('token', $request->invite_token)->first();
        
        // Validate invite
        if (!$invite) {
            return redirect()->back()->withErrors(['invite_token' => 'Invalid invite token.']);
        }
        
        if ($invite->used) {
            return redirect()->back()->withErrors(['invite_token' => 'This invite has already been used.']);
        }
        
        if ($invite->expires_at && $invite->expires_at < now()) {
            return redirect()->back()->withErrors(['invite_token' => 'This invite has expired.']);
        }
        
        // Validate email matches invite
        if ($request->email !== $invite->email) {
            return redirect()->back()->withErrors(['email' => 'Email must match the invite.']);
        }
        
        // Create user
        $user = User::create([
            'name' => $request->name,
            'email' => $invite->email,
            'password' => Hash::make($request->password),
            'tenant_id' => $invite->tenant_id,
        ]);
        
        // Assign role from invite
        $user->assignRole($invite->role);
        
        // Mark invite as used
        $invite->update(['used' => true]);
        
        // Log the registration
        \App\Models\AuditLog::create([
            'actor_id' => $user->id,
            'action' => 'user_registered_via_invite',
            'target_type' => 'user',
            'target_id' => $user->id,
            'meta' => [
                'invite_token' => $invite->token,
                'role' => $invite->role,
            ]
        ]);
        
        event(new Registered($user));
        
        Auth::login($user);
        
        // Redirect based on role
        return $this->redirectByRole($user);
    }
    
    /**
     * Register user with signup request
     */
    protected function registerWithSignupRequest(Request $request): RedirectResponse
    {
        $request->validate([
            'signup_request_id' => ['required', 'integer'],
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255'],
            'password' => ['required', 'confirmed', Rules\Password::defaults()],
        ]);
        
        // Find the signup request
        $signupRequest = RegistrationRequest::find($request->signup_request_id);
        
        // Validate request
        if (!$signupRequest) {
            return redirect()->back()->withErrors(['signup_request_id' => 'Invalid signup request.']);
        }
        
        if ($signupRequest->status !== 'approved') {
            return redirect()->back()->withErrors(['signup_request_id' => 'This request has not been approved.']);
        }
        
        // Validate email matches request
        if ($request->email !== $signupRequest->email) {
            return redirect()->back()->withErrors(['email' => 'Email must match the approved request.']);
        }
        
        // Create user
        $user = User::create([
            'name' => $request->name,
            'email' => $signupRequest->email,
            'password' => Hash::make($request->password),
            'tenant_id' => $signupRequest->tenant_id,
        ]);
        
        // Assign role from request
        $user->assignRole($signupRequest->requested_role);
        
        // Mark request as processed
        $signupRequest->update([
            'status' => 'processed',
            'processed_by' => $user->id,
        ]);
        
        // Log the registration
        \App\Models\AuditLog::create([
            'actor_id' => $user->id,
            'action' => 'user_registered_via_request',
            'target_type' => 'user',
            'target_id' => $user->id,
            'meta' => [
                'signup_request_id' => $signupRequest->id,
                'role' => $signupRequest->requested_role,
            ]
        ]);
        
        event(new Registered($user));
        
        Auth::login($user);
        
        // Redirect based on role
        return $this->redirectByRole($user);
    }
    
    /**
     * Register user via public registration
     */
    protected function registerPublic(Request $request): RedirectResponse
    {
        $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:'.User::class],
            'password' => ['required', 'confirmed', Rules\Password::defaults()],
            'role' => ['required', 'string', 'in:brand_admin,agency_admin,creator,user'],
            // Role-specific fields validation
            'company_name' => ['nullable', 'string', 'max:255'],
            'brand_handle' => ['nullable', 'string', 'max:255'],
        ]);
        
        // Determine role and create user
        $role = $request->role;
        
        // Handle brand registration specially
        if ($role === 'brand_admin') {
            // Create tenant for brand
            $tenant = \App\Models\Tenant::create([
                'name' => $request->company_name,
                'domain' => \Illuminate\Support\Str::slug($request->company_name) . '-' . time(), // Simple domain generation
                'active' => true,
            ]);
            
            // Create brand record
            $brand = \App\Models\Brand::create([
                'tenant_id' => $tenant->id,
                'name' => $request->company_name,
                'slug' => \Illuminate\Support\Str::slug($request->company_name) . '-' . $tenant->id,
                'settings' => [],
            ]);
            
            // Create user with tenant_id and brand_id
            $user = User::create([
                'name' => $request->name,
                'email' => $request->email,
                'password' => Hash::make($request->password),
                'tenant_id' => $tenant->id,
                'brand_id' => $brand->id,
            ]);
            
            // Assign role based on selection
            $user->assignRole($role);
            
            // Refresh the user to ensure brand relationship is loaded
            $user = $user->fresh();
            
            // Log the registration
            \App\Models\AuditLog::create([
                'actor_id' => $user->id,
                'action' => 'user_registered_public',
                'target_type' => 'user',
                'target_id' => $user->id,
                'meta' => [
                    'role' => $role,
                    'company_name' => $request->company_name,
                    'brand_handle' => $request->brand_handle,
                    'tenant_id' => $tenant->id,
                    'brand_id' => $brand->id,
                ]
            ]);
        } else {
            // Create user for other roles
            $user = User::create([
                'name' => $request->name,
                'email' => $request->email,
                'password' => Hash::make($request->password),
                // tenant_id will be null for public registration
                'influencer_type' => $role === 'creator' ? 'general' : null, // Default influencer type for creators
            ]);
            
            // Assign role based on selection
            $user->assignRole($role);
            
            // Refresh the user to ensure all relationships are loaded
            $user = $user->fresh();
            
            // Log the registration
            \App\Models\AuditLog::create([
                'actor_id' => $user->id,
                'action' => 'user_registered_public',
                'target_type' => 'user',
                'target_id' => $user->id,
                'meta' => [
                    'role' => $role,
                    'company_name' => $request->company_name,
                    'brand_handle' => $request->brand_handle,
                ]
            ]);
        }
        
        event(new Registered($user));
        
        Auth::login($user);
        
        // Redirect based on role
        return $this->redirectByRole($user);
    }
    
    /**
     * Redirect user based on their role
     */
    protected function redirectByRole($user)
    {
        if ($user->hasRole('superadmin')) {
            return redirect()->route('superadmin.dashboard');
        } elseif ($user->hasRole('brand_admin')) {
            return redirect()->route('brand.dashboard');
        } elseif ($user->hasRole('agency_admin')) {
            return redirect()->route('agency.dashboard');
        } elseif ($user->hasRole('creator')) {
            return redirect()->route('creator.dashboard'); // Changed from content.index to dashboard
        } else {
            return redirect(route('dashboard', absolute: false));
        }
    }
}
