<?php

namespace App\Http\Controllers\Api;

use App\Enums\UserRole;
use App\Http\Controllers\Controller;
use App\Models\DeviceToken;
use App\Models\User;
use App\Jobs\SendAdminNotification;
use App\Services\ImageService;
use App\Services\NetGsmService;
use App\Services\ReservationGuestLinker;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Str;
use Illuminate\Validation\Rules\Password as PasswordRule;
use Illuminate\Validation\ValidationException;

class AuthController extends Controller
{
    /**
     * Register a new user
     */
    public function register(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'phone' => ['required', 'string', 'max:20'],
            'password' => ['required', 'confirmed', PasswordRule::defaults()],
            'role' => ['nullable', 'string', 'in:customer,boat_owner'],
        ]);

        $role = $validated['role'] ?? UserRole::CUSTOMER;
        $user = User::create([
            'name' => $validated['name'],
            'email' => $validated['email'],
            'phone' => $validated['phone'],
            'password' => Hash::make($validated['password']),
            'role' => $role,
        ]);

        $user->update(['username' => User::generateUsername($validated['name'])]);

        SendAdminNotification::dispatch('new_user', ['user_id' => $user->id]);

        // Telefon dogrulama kodu gonder
        $this->sendPhoneVerificationCode($user);

        $token = $user->createToken('auth-token')->plainTextToken;

        return response()->json([
            'message' => 'Kayıt başarılı',
            'user' => $user,
            'token' => $token,
            'phone_verified' => false,
        ], 201);
    }

    /**
     * Login user
     */
    public function login(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'login' => ['required', 'string'],
            'password' => ['required', 'string'],
        ]);

        $loginValue = $validated['login'];
        $isEmail = str_contains($loginValue, '@');

        if (!$isEmail) {
            // Telefon: yalnızca rakamlar + TR öneki (0 / 90 / +90) sonra 10 hane — forgotPasswordSms ile aynı eşleme
            $loginDigits = preg_replace('/[^0-9]/', '', $loginValue);
            $loginDigits = preg_replace('/^(?:\+?90|0)/', '', $loginDigits);

            $user = User::where(function ($q) use ($loginDigits) {
                $q->where('phone', $loginDigits)
                    ->orWhere('phone', '0' . $loginDigits)
                    ->orWhere('phone', '+90' . $loginDigits)
                    ->orWhere('phone', '90' . $loginDigits);
            })->first();
        } else {
            $user = User::where('email', $loginValue)->first();
        }

        if (!$user || !Hash::check($validated['password'], $user->password)) {
            throw ValidationException::withMessages([
                'login' => ['Girilen bilgiler hatalı.'],
            ]);
        }

        if (!$user->is_active) {
            throw ValidationException::withMessages([
                'login' => ['Hesabınız devre dışı bırakılmış.'],
            ]);
        }

        $token = $user->createToken('auth-token')->plainTextToken;

        $phoneVerified = $user->role === \App\Enums\UserRole::ADMIN || $user->phone_verified_at !== null;

        return response()->json([
            'message' => 'Giriş başarılı',
            'user' => $user,
            'token' => $token,
            'phone_verified' => $phoneVerified,
        ]);
    }

    /**
     * Logout user
     */
    public function logout(Request $request): JsonResponse
    {
        $user = $request->user();

        // Sadece mevcut cihazın token'ını sil (diğer cihazlar etkilenmesin)
        $token = $request->input('device_token');
        if ($token) {
            DeviceToken::where('user_id', $user->id)
                ->where('token', $token)
                ->delete();
        }

        $user->currentAccessToken()->delete();

        return response()->json([
            'message' => 'Çıkış başarılı',
        ]);
    }

    /**
     * Belirli bir device token'ı sil (logout sırasında Flutter tarafından çağrılır)
     */
    public function removeDeviceToken(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'token' => ['required', 'string'],
        ]);

        DeviceToken::where('user_id', $request->user()->id)
            ->where('token', $validated['token'])
            ->delete();

        return response()->json([
            'message' => 'Cihaz token\'ı silindi',
        ]);
    }

    /**
     * Get current authenticated user
     */
    public function me(Request $request): JsonResponse
    {
        $user = $request->user()->load(['province', 'city']);

        return response()->json([
            'user' => $user,
            'phone_verified' => $user->role === \App\Enums\UserRole::ADMIN || $user->phone_verified_at !== null,
        ]);
    }

    /**
     * Update user profile
     */
    public function updateProfile(Request $request): JsonResponse
    {
        $user = $request->user();

        $validated = $request->validate([
            'name' => ['sometimes', 'string', 'max:255'],
            'phone' => ['nullable', 'string', 'max:20'],
            'bio' => ['nullable', 'string', 'max:1000'],
            'avatar' => ['nullable', 'image', 'max:2048'],
            'notifications_enabled' => ['sometimes', 'boolean'],
            'role' => ['sometimes', 'string', 'in:customer,boat_owner'],
            'province_id' => ['nullable', 'integer', 'exists:provinces,id'],
            'city_id' => ['nullable', 'integer', 'exists:cities,id'],
        ]);

        if ($request->hasFile('avatar')) {
            $imageService = app(ImageService::class);
            $validated['avatar'] = $imageService->compress(
                $request->file('avatar'),
                'avatars',
                ImageService::PRESET_AVATAR,
            );
        }

        $user->update($validated);

        return response()->json([
            'message' => 'Profil güncellendi',
            'user' => $user->fresh(),
        ]);
    }

    public function changePhone(Request $request, NetGsmService $netGsm): JsonResponse
    {
        $validated = $request->validate([
            'phone' => ['required', 'string', 'max:20'],
        ]);

        $user = $request->user();
        $phone = $validated['phone'];

        $cleanPhone = preg_replace('/[^0-9]/', '', $phone);
        if (str_starts_with($cleanPhone, '0')) {
            $cleanPhone = substr($cleanPhone, 1);
        }

        $existing = User::where('id', '!=', $user->id)
            ->where(function ($q) use ($cleanPhone) {
                $q->where('phone', $cleanPhone)
                  ->orWhere('phone', '0' . $cleanPhone)
                  ->orWhere('phone', '+90' . $cleanPhone);
            })->first();

        if ($existing) {
            throw ValidationException::withMessages([
                'phone' => ['Bu telefon numarası başka bir hesapta kayıtlı.'],
            ]);
        }

        if ($user->phone_verification_expires_at) {
            $allowedTimestamp = $user->phone_verification_expires_at->copy()->subMinutes(3)->timestamp;
            if (now()->timestamp < $allowedTimestamp) {
                $waitSeconds = min($allowedTimestamp - now()->timestamp, 120);
                return response()->json([
                    'message' => "Lütfen {$waitSeconds} saniye bekleyin.",
                    'wait_seconds' => $waitSeconds,
                ], 429);
            }
        }

        $code = str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT);

        // Kodu ve yeni numarayı geçici olarak kaydet (mevcut numarayı değiştirmeden)
        $user->update([
            'phone_verification_code' => $code,
            'phone_verification_expires_at' => now()->addMinutes(5),
            'phone_verification_attempts' => 0,
        ]);

        // Yeni numarayı cache'de sakla
        cache()->put("phone_change_{$user->id}", $phone, now()->addMinutes(10));

        $sent = $netGsm->sendVerificationCode($phone, $code);

        if (!$sent && !app()->environment('local', 'development')) {
            return response()->json(['message' => 'SMS gönderilemedi.'], 500);
        }

        $response = ['message' => 'Doğrulama kodu gönderildi.'];
        if (!$sent && app()->environment('local', 'development')) {
            $response['dev_code'] = $code;
        }

        return response()->json($response);
    }

    public function verifyChangePhone(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'code' => ['required', 'string', 'size:6'],
        ]);

        $user = $request->user();

        if (!$user->phone_verification_code) {
            return response()->json(['message' => 'Önce doğrulama kodu göndermeniz gerekiyor.'], 422);
        }

        if ($user->phone_verification_expires_at && $user->phone_verification_expires_at->lt(now())) {
            $user->update([
                'phone_verification_code' => null,
                'phone_verification_expires_at' => null,
                'phone_verification_attempts' => 0,
            ]);
            return response()->json(['message' => 'Doğrulama kodunun süresi dolmuş.'], 422);
        }

        if ($user->phone_verification_attempts >= 3) {
            $user->update([
                'phone_verification_code' => null,
                'phone_verification_expires_at' => null,
                'phone_verification_attempts' => 0,
            ]);
            return response()->json(['message' => 'Çok fazla hatalı deneme.'], 422);
        }

        if ($validated['code'] !== $user->phone_verification_code) {
            $user->increment('phone_verification_attempts');
            $remaining = 3 - $user->phone_verification_attempts;
            return response()->json([
                'message' => "Geçersiz kod. {$remaining} deneme hakkınız kaldı.",
            ], 422);
        }

        $newPhone = cache()->pull("phone_change_{$user->id}");
        if (!$newPhone) {
            return response()->json(['message' => 'Telefon değişiklik isteği süresi dolmuş.'], 422);
        }

        $user->update([
            'phone' => $newPhone,
            'phone_verified_at' => now(),
            'phone_verification_code' => null,
            'phone_verification_expires_at' => null,
            'phone_verification_attempts' => 0,
        ]);

        ReservationGuestLinker::claimFor($user->fresh());

        return response()->json([
            'message' => 'Telefon numaranız güncellendi.',
            'user' => $user->fresh(),
        ]);
    }

    public function changeEmail(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'email' => ['required', 'email', 'max:255'],
        ]);

        $user = $request->user();

        $existing = User::where('id', '!=', $user->id)
            ->where('email', $validated['email'])
            ->first();

        if ($existing) {
            throw ValidationException::withMessages([
                'email' => ['Bu e-posta adresi başka bir hesapta kayıtlı.'],
            ]);
        }

        $code = str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT);

        cache()->put("email_change_{$user->id}", [
            'email' => $validated['email'],
            'code' => $code,
            'attempts' => 0,
            'expires_at' => now()->addMinutes(10)->timestamp,
        ], now()->addMinutes(10));

        try {
            \Illuminate\Support\Facades\Mail::raw(
                "KaptanGo e-posta doğrulama kodunuz: {$code}",
                function ($message) use ($validated) {
                    $message->to($validated['email'])
                        ->subject('KaptanGo E-posta Doğrulama');
                }
            );
        } catch (\Throwable $e) {
            \Log::warning('Email doğrulama kodu gönderilemedi: ' . $e->getMessage());
            if (app()->environment('local', 'development')) {
                return response()->json(['message' => 'Doğrulama kodu gönderildi.', 'dev_code' => $code]);
            }
            return response()->json(['message' => 'E-posta gönderilemedi.'], 500);
        }

        return response()->json(['message' => 'Doğrulama kodu e-posta adresinize gönderildi.']);
    }

    public function verifyChangeEmail(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'code' => ['required', 'string', 'size:6'],
        ]);

        $user = $request->user();
        $data = cache()->get("email_change_{$user->id}");

        if (!$data) {
            return response()->json(['message' => 'E-posta değişiklik isteği bulunamadı veya süresi dolmuş.'], 422);
        }

        if ($data['attempts'] >= 3) {
            cache()->forget("email_change_{$user->id}");
            return response()->json(['message' => 'Çok fazla hatalı deneme.'], 422);
        }

        if ($validated['code'] !== $data['code']) {
            $data['attempts']++;
            cache()->put("email_change_{$user->id}", $data, now()->addMinutes(10));
            $remaining = 3 - $data['attempts'];
            return response()->json(['message' => "Geçersiz kod. {$remaining} deneme hakkınız kaldı."], 422);
        }

        cache()->forget("email_change_{$user->id}");

        $user->update([
            'email' => $data['email'],
            'email_verified_at' => now(),
        ]);

        return response()->json([
            'message' => 'E-posta adresiniz güncellendi.',
            'user' => $user->fresh(),
        ]);
    }

    public function convertToCaptain(Request $request): JsonResponse
    {
        $request->validate([
            'captain_agreement_accepted' => ['required', 'boolean', 'accepted'],
        ]);

        $user = $request->user();

        if ($user->role !== UserRole::CUSTOMER) {
            return response()->json([
                'message' => 'Hesabınız zaten kaptan veya yönetici rolünde.',
            ], 422);
        }

        $user->update([
            'role' => UserRole::BOAT_OWNER,
            'captain_agreement_accepted_at' => now(),
            'username' => User::generateUsername($user->name),
        ]);

        return response()->json([
            'message' => 'Hesabınız başarıyla kaptan hesabına dönüştürüldü.',
            'user' => $user->fresh(),
        ]);
    }

    public function updateUsername(Request $request): JsonResponse
    {
        $user = $request->user();

        if ($user->role !== UserRole::BOAT_OWNER && $user->role !== UserRole::ADMIN) {
            return response()->json(['message' => 'Sadece kaptanlar kullanıcı adı belirleyebilir.'], 403);
        }

        $validated = $request->validate([
            'username' => [
                'required', 'string', 'min:3', 'max:30',
                'regex:/^[a-z0-9]+$/',
                'unique:users,username,' . $user->id,
            ],
        ], [
            'username.regex' => 'Kullanıcı adı sadece küçük harf ve rakam içerebilir.',
            'username.unique' => 'Bu kullanıcı adı zaten kullanılıyor.',
            'username.min' => 'Kullanıcı adı en az 3 karakter olmalıdır.',
            'username.max' => 'Kullanıcı adı en fazla 30 karakter olabilir.',
        ]);

        $reserved = [
            'admin', 'login', 'register', 'api', 'listings', 'help', 'settings',
            'profile', 'home', 'about', 'contact', 'privacy', 'terms', 'support',
            'captains', 'owner', 'chat', 'notifications', 'favorites', 'reservations',
            'search', 'explore', 'kaptango', 'www', 'mail', 'blog', 'app',
        ];

        if (in_array($validated['username'], $reserved, true)) {
            return response()->json(['message' => 'Bu kullanıcı adı kullanılamaz.'], 422);
        }

        $user->update(['username' => $validated['username']]);

        return response()->json([
            'message' => 'Kullanıcı adı güncellendi.',
            'user' => $user->fresh(),
        ]);
    }

    public function checkUsername(string $username): JsonResponse
    {
        $reserved = [
            'admin', 'login', 'register', 'api', 'listings', 'help', 'settings',
            'profile', 'home', 'about', 'contact', 'privacy', 'terms', 'support',
            'captains', 'owner', 'chat', 'notifications', 'favorites', 'reservations',
            'search', 'explore', 'kaptango', 'www', 'mail', 'blog', 'app',
        ];

        $available = !in_array($username, $reserved, true)
            && preg_match('/^[a-z0-9]{3,30}$/', $username)
            && !User::where('username', $username)->exists();

        return response()->json(['available' => $available]);
    }

    public function updatePassword(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'current_password' => ['required', 'string'],
            'password' => ['required', 'confirmed', PasswordRule::defaults()],
        ]);

        $user = $request->user();

        if (!Hash::check($validated['current_password'], $user->password)) {
            throw ValidationException::withMessages([
                'current_password' => ['Mevcut şifre hatalı.'],
            ]);
        }

        $user->update([
            'password' => Hash::make($validated['password']),
        ]);

        return response()->json([
            'message' => 'Şifre güncellendi',
        ]);
    }

    /**
     * Send password reset link
     */
    public function forgotPassword(Request $request): JsonResponse
    {
        $request->validate([
            'email' => ['required', 'email'],
        ]);

        $status = Password::sendResetLink(
            $request->only('email')
        );

        if ($status === Password::RESET_LINK_SENT) {
            return response()->json([
                'message' => 'Şifre sıfırlama bağlantısı e-posta adresinize gönderildi.',
            ]);
        }

        throw ValidationException::withMessages([
            'email' => [__($status)],
        ]);
    }

    /**
     * Reset password
     */
    public function resetPassword(Request $request): JsonResponse
    {
        $request->validate([
            'token' => ['required'],
            'email' => ['required', 'email'],
            'password' => ['required', 'confirmed', PasswordRule::defaults()],
        ]);

        $status = Password::reset(
            $request->only('email', 'password', 'password_confirmation', 'token'),
            function ($user, $password) {
                $user->forceFill([
                    'password' => Hash::make($password),
                ])->save();
            }
        );

        if ($status === Password::PASSWORD_RESET) {
            return response()->json([
                'message' => 'Şifreniz başarıyla sıfırlandı.',
            ]);
        }

        throw ValidationException::withMessages([
            'email' => [__($status)],
        ]);
    }

    /**
     * Register device token (OneSignal subscription ID) for push notifications
     */
    public function registerDeviceToken(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'token' => ['required', 'string'],
            'platform' => ['required', 'string', 'in:ios,android,web'],
        ]);

        $user = $request->user();
        $token = $validated['token'];
        $platform = $validated['platform'];

        // Aynı token başka bir kullanıcıya aitse eski kaydı deaktif et
        DeviceToken::where('token', $token)
            ->where('user_id', '!=', $user->id)
            ->update(['is_active' => false]);

        // Token'ı kaydet veya güncelle (cihaz el değiştirdiyse user_id güncellenir)
        DeviceToken::updateOrCreate(
            ['token' => $token],
            [
                'user_id' => $user->id,
                'platform' => $platform,
                'is_active' => true,
            ]
        );

        \Log::info('Cihaz token kaydedildi', [
            'user_id' => $user->id,
            'platform' => $platform,
            'subscription_id' => substr($token, 0, 12) . '...',
        ]);

        return response()->json([
            'message' => 'Cihaz token\'ı kaydedildi',
        ]);
    }

    /**
     * Google ile giris/kayit
     */
    public function googleLogin(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'id_token' => ['required', 'string'],
            'role' => ['nullable', 'string', 'in:customer,boat_owner'],
        ]);

        // Google ID Token'i dogrula
        $googleUser = $this->verifyGoogleToken($validated['id_token']);

        if (!$googleUser) {
            return response()->json([
                'message' => 'Google doğrulama başarısız.',
            ], 401);
        }

        $user = User::where('google_id', $googleUser['sub'])->first();
        $isNew = false;

        if (!$user) {
            $user = User::where('email', $googleUser['email'])->first();

            if ($user) {
                $user->update(['google_id' => $googleUser['sub']]);
            } else {
                $isNew = true;
                $googleRole = $validated['role'] ?? UserRole::CUSTOMER;
                $googleName = $googleUser['name'] ?? $googleUser['email'];
                $user = User::create([
                    'name' => $googleName,
                    'email' => $googleUser['email'],
                    'google_id' => $googleUser['sub'],
                    'role' => $googleRole,
                    'password' => null,
                ]);

                $user->update(['username' => User::generateUsername($googleName)]);
            }
        }

        if (!$user->username) {
            $user->update(['username' => User::generateUsername($user->name)]);
        }

        if ($user->is_active === false) {
            return response()->json([
                'message' => 'Hesabınız devre dışı bırakılmış.',
            ], 403);
        }

        if ($user->is_active === null) {
            $user->update(['is_active' => true]);
        }

        if ($isNew) {
            SendAdminNotification::dispatch('new_user', ['user_id' => $user->id]);
        }

        $token = $user->createToken('auth-token')->plainTextToken;

        return response()->json([
            'message' => 'Google ile giriş başarılı',
            'user' => $user,
            'token' => $token,
            'phone_verified' => $user->role === \App\Enums\UserRole::ADMIN || $user->phone_verified_at !== null,
            'is_new' => $isNew,
        ]);
    }

    /**
     * Google ID Token'i dogrula
     */
    private function verifyGoogleToken(string $idToken): ?array
    {
        try {
            $response = Http::get('https://oauth2.googleapis.com/tokeninfo', [
                'id_token' => $idToken,
            ]);

            if ($response->failed()) {
                \Log::warning('Google token dogrulama basarisiz', [
                    'status' => $response->status(),
                    'body' => $response->body(),
                ]);
                return null;
            }

            $data = $response->json();

            // Audience (client ID) kontrolu
            $validClientIds = array_filter([
                config('services.google.client_id'),
                config('services.google.ios_client_id'),
            ]);

            if (!empty($validClientIds) && !in_array($data['aud'] ?? '', $validClientIds)) {
                \Log::warning('Google token: Gecersiz audience', [
                    'aud' => $data['aud'] ?? null,
                    'valid' => $validClientIds,
                ]);
                return null;
            }

            return $data;
        } catch (\Throwable $e) {
            \Log::error('Google token dogrulama hatasi', [
                'error' => $e->getMessage(),
            ]);
            return null;
        }
    }

    /**
     * Apple ile giris/kayit
     */
    public function appleLogin(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'identity_token' => ['required', 'string'],
            'name' => ['nullable', 'string', 'max:255'],
            'email' => ['nullable', 'string', 'email', 'max:255'],
            'role' => ['nullable', 'string', 'in:customer,boat_owner'],
        ]);

        $appleUser = $this->verifyAppleToken($validated['identity_token']);

        if (!$appleUser) {
            return response()->json([
                'message' => 'Apple doğrulama başarısız.',
            ], 401);
        }

        $appleSub = $appleUser['sub'];
        $appleEmail = $appleUser['email'] ?? $validated['email'] ?? null;

        $user = User::where('apple_id', $appleSub)->first();
        $isNew = false;

        if (!$user) {
            if ($appleEmail) {
                $user = User::where('email', $appleEmail)->first();
            }

            if ($user) {
                $updateData = ['apple_id' => $appleSub];
                if (!empty($validated['name']) && ($user->name === $user->email || empty($user->name))) {
                    $updateData['name'] = $validated['name'];
                }
                $user->update($updateData);
            } else {
                $isNew = true;
                $userName = $validated['name'] ?? $appleEmail ?? 'Apple Kullanıcı';
                $appleRole = $validated['role'] ?? UserRole::CUSTOMER;
                $user = User::create([
                    'name' => $userName,
                    'email' => $appleEmail,
                    'apple_id' => $appleSub,
                    'role' => $appleRole,
                    'password' => null,
                ]);

                $user->update(['username' => User::generateUsername($userName)]);
            }
        }

        if (!$user->username) {
            $user->update(['username' => User::generateUsername($user->name)]);
        }

        if ($user->is_active === false) {
            return response()->json([
                'message' => 'Hesabınız devre dışı bırakılmış.',
            ], 403);
        }

        if ($user->is_active === null) {
            $user->update(['is_active' => true]);
        }

        if ($isNew) {
            SendAdminNotification::dispatch('new_user', ['user_id' => $user->id]);
        }

        $token = $user->createToken('auth-token')->plainTextToken;

        return response()->json([
            'message' => 'Apple ile giriş başarılı',
            'user' => $user,
            'token' => $token,
            'phone_verified' => $user->role === UserRole::ADMIN || $user->phone_verified_at !== null,
            'is_new' => $isNew,
        ]);
    }

    /**
     * Apple Identity Token dogrulama (JWT)
     */
    private function verifyAppleToken(string $identityToken): ?array
    {
        try {
            cache()->forget('apple_jwks');

            $response = Http::timeout(10)->get('https://appleid.apple.com/auth/keys');

            if ($response->failed()) {
                \Log::error('Apple public keys alinamadi', [
                    'status' => $response->status(),
                    'body' => $response->body(),
                ]);
                return null;
            }

            $jwks = $response->json();

            if (!$jwks || empty($jwks['keys'] ?? [])) {
                \Log::error('Apple JWKS bos veya gecersiz', ['jwks' => $jwks]);
                return null;
            }

            \Log::info('Apple JWKS basariyla alindi', ['key_count' => count($jwks['keys'])]);

            $keySet = \Firebase\JWT\JWK::parseKeySet($jwks, 'RS256');
            $decoded = \Firebase\JWT\JWT::decode($identityToken, $keySet);
            $payload = (array) $decoded;

            \Log::info('Apple token decoded', [
                'sub' => $payload['sub'] ?? null,
                'aud' => $payload['aud'] ?? null,
                'iss' => $payload['iss'] ?? null,
                'email' => $payload['email'] ?? null,
            ]);

            $bundleId = config('services.apple.client_id', 'com.anilkurtaran.kaptango');
            if (($payload['aud'] ?? '') !== $bundleId) {
                \Log::warning('Apple token: Gecersiz audience', [
                    'aud' => $payload['aud'] ?? null,
                    'expected' => $bundleId,
                ]);
                return null;
            }

            if (($payload['iss'] ?? '') !== 'https://appleid.apple.com') {
                \Log::warning('Apple token: Gecersiz issuer', [
                    'iss' => $payload['iss'] ?? null,
                ]);
                return null;
            }

            return $payload;
        } catch (\Firebase\JWT\ExpiredException $e) {
            \Log::warning('Apple token suresi dolmus', ['error' => $e->getMessage()]);
            return null;
        } catch (\Throwable $e) {
            \Log::error('Apple token dogrulama hatasi', [
                'error' => $e->getMessage(),
                'class' => get_class($e),
                'trace' => $e->getTraceAsString(),
            ]);
            return null;
        }
    }

    /**
     * Apple server-to-server bildirimleri
     */
    public function appleNotification(Request $request): JsonResponse
    {
        try {
            $payload = $request->input('payload');

            if (!$payload) {
                return response()->json(['status' => 'no payload'], 400);
            }

            $parts = explode('.', $payload);
            if (count($parts) !== 3) {
                return response()->json(['status' => 'invalid jwt'], 400);
            }

            $body = json_decode(base64_decode($parts[1]), true);
            $events = $body['events'] ?? null;

            if (!$events) {
                return response()->json(['status' => 'no events'], 200);
            }

            $eventType = $events['type'] ?? null;
            $sub = $events['sub'] ?? null;

            if (!$sub) {
                return response()->json(['status' => 'no sub'], 200);
            }

            \Log::info('Apple server-to-server notification', [
                'type' => $eventType,
                'sub' => $sub,
            ]);

            switch ($eventType) {
                case 'account-delete':
                    $user = User::where('apple_id', $sub)->first();
                    if ($user) {
                        $user->update(['is_active' => false, 'apple_id' => null]);
                        $user->tokens()->delete();
                        \Log::info('Apple kullanici hesabi deaktif edildi', ['user_id' => $user->id]);
                    }
                    break;

                case 'email-disabled':
                case 'email-enabled':
                    \Log::info('Apple email relay degisikligi', [
                        'type' => $eventType,
                        'sub' => $sub,
                        'email' => $events['email'] ?? null,
                    ]);
                    break;

                case 'consent-revoked':
                    $user = User::where('apple_id', $sub)->first();
                    if ($user) {
                        $user->update(['apple_id' => null]);
                        $user->tokens()->delete();
                        \Log::info('Apple kullanici izni geri cekildi', ['user_id' => $user->id]);
                    }
                    break;
            }

            return response()->json(['status' => 'ok']);
        } catch (\Throwable $e) {
            \Log::error('Apple notification islenirken hata', ['error' => $e->getMessage()]);
            return response()->json(['status' => 'error'], 500);
        }
    }

    /**
     * Kullaniciya telefon dogrulama kodu gonder
     */
    private function sendPhoneVerificationCode(User $user): void
    {
        if (!$user->phone) {
            return;
        }

        $code = str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT);

        $user->update([
            'phone_verification_code' => $code,
            'phone_verification_expires_at' => now()->addMinutes(5),
            'phone_verification_attempts' => 0,
        ]);

        try {
            $netGsm = app(NetGsmService::class);
            $netGsm->sendVerificationCode($user->phone, $code);
        } catch (\Throwable $e) {
            \Log::error('Kayit sirasinda SMS gonderilemedi', [
                'error' => $e->getMessage(),
            ]);
        }
    }

    public function forgotPasswordSms(Request $request, NetGsmService $netGsm): JsonResponse
    {
        $validated = $request->validate([
            'phone' => ['required', 'string', 'max:20'],
        ]);

        $phone = preg_replace('/[^0-9]/', '', $validated['phone']);
        if (str_starts_with($phone, '0')) {
            $phone = substr($phone, 1);
        }

        $user = User::where('phone', $phone)
            ->orWhere('phone', '0' . $phone)
            ->orWhere('phone', '+90' . $phone)
            ->first();

        if (!$user) {
            throw ValidationException::withMessages([
                'phone' => ['Bu telefon numarasına ait hesap bulunamadı.'],
            ]);
        }

        if (!$user->phone_verified_at) {
            throw ValidationException::withMessages([
                'phone' => ['Telefon numaranız doğrulanmamış. Şifre sıfırlama yapılamaz.'],
            ]);
        }

        if ($user->phone_verification_expires_at) {
            $allowedTimestamp = $user->phone_verification_expires_at->copy()->subMinutes(3)->timestamp;
            if (now()->timestamp < $allowedTimestamp) {
                $waitSeconds = min($allowedTimestamp - now()->timestamp, 120);
                return response()->json([
                    'message' => "Lütfen {$waitSeconds} saniye bekleyin.",
                    'wait_seconds' => $waitSeconds,
                ], 429);
            }
        }

        $code = str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT);

        $user->update([
            'phone_verification_code' => $code,
            'phone_verification_expires_at' => now()->addMinutes(5),
            'phone_verification_attempts' => 0,
        ]);

        $sent = $netGsm->sendVerificationCode($user->phone, $code);

        if (!$sent && !app()->environment('local', 'development')) {
            return response()->json(['message' => 'SMS gönderilemedi. Lütfen tekrar deneyin.'], 500);
        }

        $response = ['message' => 'Doğrulama kodu gönderildi.'];
        if (!$sent && app()->environment('local', 'development')) {
            $response['dev_code'] = $code;
        }

        return response()->json($response);
    }

    public function resetPasswordSms(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'phone' => ['required', 'string', 'max:20'],
            'code' => ['required', 'string', 'size:6'],
            'password' => ['required', 'confirmed', PasswordRule::defaults()],
        ]);

        $phone = preg_replace('/[^0-9]/', '', $validated['phone']);
        if (str_starts_with($phone, '0')) {
            $phone = substr($phone, 1);
        }

        $user = User::where('phone', $phone)
            ->orWhere('phone', '0' . $phone)
            ->orWhere('phone', '+90' . $phone)
            ->first();

        if (!$user) {
            throw ValidationException::withMessages([
                'phone' => ['Hesap bulunamadı.'],
            ]);
        }

        if (!$user->phone_verification_code) {
            return response()->json(['message' => 'Önce doğrulama kodu göndermeniz gerekiyor.'], 422);
        }

        if ($user->phone_verification_expires_at && $user->phone_verification_expires_at->lt(now())) {
            $user->update([
                'phone_verification_code' => null,
                'phone_verification_expires_at' => null,
                'phone_verification_attempts' => 0,
            ]);
            return response()->json(['message' => 'Doğrulama kodunun süresi dolmuş.'], 422);
        }

        if ($user->phone_verification_attempts >= 3) {
            $user->update([
                'phone_verification_code' => null,
                'phone_verification_expires_at' => null,
                'phone_verification_attempts' => 0,
            ]);
            return response()->json(['message' => 'Çok fazla hatalı deneme. Lütfen yeni kod gönderin.'], 422);
        }

        if ($validated['code'] !== $user->phone_verification_code) {
            $user->increment('phone_verification_attempts');
            $remaining = 3 - $user->phone_verification_attempts;
            return response()->json([
                'message' => "Geçersiz kod. {$remaining} deneme hakkınız kaldı.",
                'remaining_attempts' => $remaining,
            ], 422);
        }

        $user->update([
            'password' => Hash::make($validated['password']),
            'phone_verification_code' => null,
            'phone_verification_expires_at' => null,
            'phone_verification_attempts' => 0,
        ]);

        return response()->json(['message' => 'Şifreniz başarıyla değiştirildi.']);
    }

    /**
     * Kullanici hesabini kalici olarak sil (soft delete + anonimizasyon)
     */
    public function deleteAccount(Request $request): JsonResponse
    {
        $request->validate([
            'password' => ['nullable', 'string'],
        ]);

        $user = $request->user();

        if ($user->password !== null) {
            if (empty($request->password) || !Hash::check($request->password, $user->password)) {
                throw ValidationException::withMessages([
                    'password' => ['Şifre hatalı.'],
                ]);
            }
        }

        try {
            DB::beginTransaction();

            // 1. Tum API tokenlarini iptal et
            $user->tokens()->delete();

            // 2. Cihaz tokenlarini sil
            DeviceToken::where('user_id', $user->id)->delete();

            // 3. Kaptan ise ilanlarini soft delete yap
            if ($user->role === UserRole::BOAT_OWNER || $user->role === UserRole::ADMIN) {
                $user->listings()->each(function ($listing) {
                    $listing->delete(); // Listing modelinde SoftDeletes var
                });
            }

            // 4. Postlari sil (SoftDeletes yok, status ile yonet)
            $user->posts()->update(['status' => 'deleted']);

            // 5. Takip iliskilerini sil
            DB::table('follows')->where('follower_id', $user->id)->orWhere('following_id', $user->id)->delete();

            // 6. Favori ilanlari sil
            $user->favoriteListings()->delete();

            // 7. Kaydedilen postlari sil
            if (\Schema::hasTable('post_saves')) {
                DB::table('post_saves')->where('user_id', $user->id)->delete();
            }

            // 8. Kullanici verisini anonimlestirir
            $timestamp = now()->timestamp;
            $user->forceFill([
                'name' => 'Silinmiş Hesap',
                'email' => "deleted_{$user->id}_{$timestamp}@deleted.local",
                'phone' => null,
                'username' => "deleted_{$user->id}_" . Str::random(6),
                'avatar' => null,
                'bio' => null,
                'google_id' => null,
                'apple_id' => null,
                'is_active' => false,
                'password' => Hash::make(Str::random(40)),
                'province_id' => null,
                'city_id' => null,
                'phone_verification_code' => null,
                'phone_verification_expires_at' => null,
                'phone_verification_attempts' => 0,
            ])->save();

            // 9. Soft delete
            $user->delete();

            DB::commit();

            Log::info('Kullanici hesabi silindi', ['user_id' => $user->id]);

            return response()->json([
                'message' => 'Hesabınız başarıyla silindi.',
            ]);
        } catch (\Throwable $e) {
            DB::rollBack();
            Log::error('Hesap silme hatasi', [
                'user_id' => $user->id,
                'error' => $e->getMessage(),
            ]);

            return response()->json([
                'message' => 'Hesap silinirken bir hata oluştu. Lütfen tekrar deneyin.',
            ], 500);
        }
    }
}
