<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Models\Agent;
use App\Models\SubscriptionPlan;
use App\Models\RoleProfile;
use App\Models\SystemSetting;
use App\Models\Tenant;
use App\Models\User;
use App\Services\ActivityLogger;
use App\Services\SubscriptionService;
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 TenantRegistrationController extends Controller
{
    public function create(Request $request): View
    {
        $agentSlug = $request->query('merchant') ?: $request->query('agent') ?: $request->session()->get('agent_referral');
        $commissionType = in_array($request->query('merchant_type'), [Agent::MERCHANT_ONBOARDING, Agent::MERCHANT_REFERRAL], true)
            ? $request->query('merchant_type')
            : $request->session()->get('agent_commission_type', Agent::MERCHANT_ONBOARDING);
        $agent = $agentSlug
            ? Agent::query()->with('user')->where('slug', $agentSlug)->where('status', Agent::STATUS_ACTIVE)->first()
            : null;

        if ($agent) {
            $request->session()->put('agent_referral', $agent->slug);
            $request->session()->put('agent_commission_type', $commissionType);
        } else {
            $request->session()->forget('agent_referral');
            $request->session()->forget('agent_commission_type');
        }

        return view('auth.register-tenant', [
            'plans' => SubscriptionPlan::query()->where('is_active', true)->orderBy('price_monthly')->get(),
            'agent' => $agent,
            'commissionType' => $commissionType,
        ]);
    }

    public function store(Request $request, SubscriptionService $subscriptions): RedirectResponse
    {
        $validated = $request->validate([
            'company_name' => ['required', 'string', 'max:255'],
            'owner_name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'email', 'max:255', 'unique:tenants,email', 'unique:users,email'],
            'phone' => ['nullable', 'string', 'max:50'],
            'address' => ['nullable', 'string', 'max:1000'],
            'subscription_plan_id' => ['required', 'exists:subscription_plans,id'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
            'agent_slug' => ['nullable', 'string', 'max:255'],
            'agent_commission_type' => ['nullable', 'in:'.Agent::MERCHANT_ONBOARDING.','.Agent::MERCHANT_REFERRAL],
        ]);

        $agent = filled($validated['agent_slug'] ?? null)
            ? Agent::query()->where('slug', $validated['agent_slug'])->where('status', Agent::STATUS_ACTIVE)->first()
            : null;

        $commissionType = $validated['agent_commission_type'] ?? $request->session()->get('agent_commission_type', Agent::MERCHANT_ONBOARDING);

        [$tenant, $admin] = DB::transaction(function () use ($validated, $agent, $commissionType): array {
            $slug = $this->uniqueSlug($validated['company_name']);

            $tenant = Tenant::create([
                'subscription_plan_id' => $validated['subscription_plan_id'],
                'agent_id' => $agent?->id,
                'agent_assigned_at' => $agent ? now() : null,
                'agent_commission_type' => $agent ? $commissionType : Agent::MERCHANT_ONBOARDING,
                'name' => $validated['company_name'],
                'slug' => $slug,
                'subdomain' => $slug,
                'owner_name' => $validated['owner_name'],
                'email' => $validated['email'],
                'phone' => $validated['phone'] ?? null,
                'address' => $validated['address'] ?? null,
                'status' => 'pending',
                'settings' => [
                    'currency' => 'NGN',
                    'interest_rate' => 5,
                    'penalty_rate' => 1,
                    'timezone' => config('app.timezone'),
                    'account_number_mode' => 'random',
                    'account_number_prefixes' => null,
                ],
            ]);

            $admin = User::create([
                'tenant_id' => $tenant->id,
                'role' => User::ROLE_TENANT_ADMIN,
                'name' => $validated['owner_name'],
                'email' => $validated['email'],
                'phone' => $validated['phone'] ?? null,
                'password' => $validated['password'],
                'status' => 'active',
            ]);

            RoleProfile::createDefaultsForTenant($tenant);
            $admin->update([
                'role_profile_id' => RoleProfile::withoutGlobalScopes()
                    ->where('tenant_id', $tenant->id)
                    ->where('base_role', User::ROLE_TENANT_ADMIN)
                    ->value('id'),
            ]);

            return [$tenant, $admin];
        });

        $trialDays = (int) SystemSetting::getValue('trial_days', 14);
        $subscriptions->approveTenant($tenant, $trialDays);

        ActivityLogger::log('tenant_auto_approved', $tenant->name.' registered and was automatically approved for a '.$trialDays.' day free trial.', $tenant);

        Auth::login($admin);
        $request->session()->forget('agent_referral');
        $request->session()->forget('agent_commission_type');

        return redirect()->route('tenant.dashboard')
            ->with('status', 'Your company is approved automatically. Your '.$trialDays.' day free trial has started.');
    }

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

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

        return $slug;
    }
}
