<?php

namespace App\Http\Controllers;

use App\Models\Package;
use App\Models\Tenant;
use App\Models\User;
use App\Support\CheckoutRoutes;
use App\Support\LocaleConfig;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Laravel\Socialite\Facades\Socialite;
use Symfony\Component\HttpFoundation\RedirectResponse;

class CheckoutGoogleController extends Controller
{
    private const SESSION_KEY = 'checkout_google_payload';

    public function redirect(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'package_id' => ['required', 'exists:packages,id'],
            'locale' => ['nullable', 'string'],
        ]);

        $payload = [
            'package_id' => (int) $validated['package_id'],
            'locale' => $validated['locale'] ?? app()->getLocale(),
        ];

        $request->session()->put(self::SESSION_KEY, $payload);
        $request->session()->put('selected_package_id', $payload['package_id']);

        return Socialite::driver('google')
            ->scopes(['email', 'profile'])
            ->with(['prompt' => 'select_account'])
            ->redirect();
    }

    public function callback(Request $request): RedirectResponse
    {
        $payload = $request->session()->get(self::SESSION_KEY, []);
        $packageId = $payload['package_id'] ?? null;
        $locale = $payload['locale'] ?? null;

        try {
            $googleUser = Socialite::driver('google')->user();
        } catch (\Throwable $e) {
            Log::warning('Google checkout login failed', ['message' => $e->getMessage()]);
            $this->flashError($request, __('checkout.google_error_fallback'));

            return $this->redirectBackToWizard($packageId, $locale);
        }

        $email = $googleUser->getEmail();
        if (! $email) {
            $this->flashError($request, __('checkout.google_missing_email'));

            return $this->redirectBackToWizard($packageId, $locale);
        }

        $raw = $googleUser->getRaw();
        $request->session()->put('checkout_google_profile', array_filter([
            'email' => $email,
            'name' => $googleUser->getName(),
            'given_name' => $raw['given_name'] ?? null,
            'family_name' => $raw['family_name'] ?? null,
            'avatar' => $googleUser->getAvatar(),
            'locale' => $raw['locale'] ?? null,
        ]));

        $existing = User::where('email', $email)->first();

        if (! $existing) {
            $request->session()->put('checkout_google_profile', array_filter([
                'email' => $email,
                'name' => $googleUser->getName(),
                'given_name' => $raw['given_name'] ?? null,
                'family_name' => $raw['family_name'] ?? null,
                'avatar' => $googleUser->getAvatar(),
                'locale' => $raw['locale'] ?? null,
            ]));

            $request->session()->put('checkout_google_status', 'prefill');

            return $this->redirectBackToWizard($packageId, $locale);
        }

        $user = DB::transaction(function () use ($existing, $googleUser, $email) {
            $existing->forceFill([
                'name' => $googleUser->getName() ?: $existing->name,
                'pending_purchase' => true,
                'email_verified_at' => $existing->email_verified_at ?? now(),
            ])->save();

            if (! $existing->tenant) {
                $this->createTenantForUser($existing, $googleUser->getName(), $email);
            }

            return $existing->fresh();
        });

        if (! $user->tenant) {
            $this->createTenantForUser($user, $googleUser->getName(), $email);
        }

        Auth::login($user, true);
        $request->session()->regenerate();
        $request->session()->forget(self::SESSION_KEY);
        $request->session()->forget('checkout_google_profile');
        $request->session()->put('checkout_google_status', 'signin');

        if ($packageId) {
            $this->ensurePackageAttached($user, (int) $packageId);
        }

        return $this->redirectBackToWizard($packageId, $locale);
    }

    private function createTenantForUser(User $user, ?string $displayName, string $email): Tenant
    {
        $tenantName = trim($displayName ?: Str::before($email, '@')) ?: 'Fotospiel Tenant';
        $slugBase = Str::slug($tenantName) ?: 'tenant';
        $slug = $slugBase;
        $counter = 1;

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

        $tenant = Tenant::create([
            'user_id' => $user->id,
            'name' => $tenantName,
            'slug' => $slug,
            'email' => $email,
            'contact_email' => $email,
            'is_active' => true,
            'is_suspended' => false,
            'subscription_tier' => 'free',
            'subscription_status' => 'free',
            'subscription_expires_at' => null,
            'settings' => json_encode([
                'branding' => [
                    'logo_url' => null,
                    'primary_color' => '#FF5A5F',
                    'secondary_color' => '#FFF8F5',
                    'font_family' => 'Inter, sans-serif',
                ],
                'features' => [
                    'photo_likes_enabled' => false,
                    'event_checklist' => false,
                    'custom_domain' => false,
                    'advanced_analytics' => false,
                ],
                'custom_domain' => null,
                'contact_email' => $email,
                'event_default_type' => 'general',
            ]),
        ]);

        $user->forceFill(['tenant_id' => $tenant->id])->save();

        return $tenant;
    }

    private function ensurePackageAttached(User $user, int $packageId): void
    {
        $tenant = $user->tenant;
        if (! $tenant) {
            return;
        }

        $package = Package::find($packageId);
        if (! $package) {
            return;
        }

        if ($tenant->packages()->where('package_id', $packageId)->exists()) {
            return;
        }

        $tenant->packages()->attach($packageId, [
            'price' => $package->price,
            'purchased_at' => now(),
            'expires_at' => now()->addYear(),
            'active' => $package->price <= 0,
        ]);
    }

    private function redirectBackToWizard(?int $packageId, ?string $locale = null): RedirectResponse
    {
        if ($packageId) {
            return redirect()->to(CheckoutRoutes::wizardUrl($packageId, $locale));
        }

        $firstPackageId = Package::query()->orderBy('price')->value('id');
        if ($firstPackageId) {
            return redirect()->to(CheckoutRoutes::wizardUrl($firstPackageId, $locale));
        }

        return redirect()->route('packages', [
            'locale' => LocaleConfig::canonicalize($locale ?? app()->getLocale()),
        ]);
    }

    private function flashError(Request $request, string $message): void
    {
        $request->session()->flash('checkout_google_error', $message);
    }
}
