<?php

namespace App\Http\Controllers\Api\Tenant;

use App\Http\Controllers\Controller;
use App\Http\Requests\Tenant\ProfileUpdateRequest;
use App\Models\User;
use App\Support\ApiError;
use App\Support\TenantAuth;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Response;

class ProfileController extends Controller
{
    public function show(Request $request): JsonResponse
    {
        try {
            $user = TenantAuth::resolveAdminUser($request);
        } catch (\Throwable $exception) {
            Log::warning('[TenantProfile] Unable to resolve user for profile show', [
                'tenant_id' => $request->attributes->get('tenant_id'),
                'error' => $exception->getMessage(),
            ]);

            return ApiError::response(
                'profile_user_missing',
                'Profil nicht verfügbar',
                'Für diesen Tenant konnte kein Account gefunden werden.',
                Response::HTTP_NOT_FOUND
            );
        }

        return response()->json([
            'data' => $this->transformUser($user),
        ]);
    }

    public function update(ProfileUpdateRequest $request): JsonResponse
    {
        try {
            $user = TenantAuth::resolveAdminUser($request);
        } catch (\Throwable $exception) {
            Log::warning('[TenantProfile] Unable to resolve user for profile update', [
                'tenant_id' => $request->attributes->get('tenant_id'),
                'error' => $exception->getMessage(),
            ]);

            return ApiError::response(
                'profile_user_missing',
                'Profil nicht verfügbar',
                'Für diesen Tenant konnte kein Account gefunden werden.',
                Response::HTTP_NOT_FOUND
            );
        }

        $data = $request->validated();
        $updates = [];
        $emailChanged = false;

        if (isset($data['name']) && $data['name'] !== $user->name) {
            $updates['name'] = $data['name'];
        }

        if (array_key_exists('preferred_locale', $data) && $data['preferred_locale'] !== $user->preferred_locale) {
            $updates['preferred_locale'] = $data['preferred_locale'] ? Str::lower($data['preferred_locale']) : null;
        }

        if (isset($data['email']) && Str::lower($data['email']) !== Str::lower((string) $user->email)) {
            $updates['email'] = $data['email'];
            $updates['email_verified_at'] = null;
            $emailChanged = true;
        }

        if ($request->filled('password')) {
            $currentPassword = (string) $request->input('current_password');
            if (! $request->filled('current_password') || ! Hash::check($currentPassword, $user->password)) {
                return ApiError::response(
                    'profile.invalid_current_password',
                    'Aktuelles Passwort ungültig',
                    'Das aktuelle Passwort stimmt nicht.',
                    Response::HTTP_UNPROCESSABLE_ENTITY,
                    [
                        'errors' => [
                            'current_password' => ['Das aktuelle Passwort stimmt nicht.'],
                        ],
                    ]
                );
            }

            $updates['password'] = $request->input('password');
        }

        if ($updates !== []) {
            $user->forceFill($updates);
            $user->save();

            if ($emailChanged) {
                try {
                    $user->sendEmailVerificationNotification();
                } catch (\Throwable $exception) {
                    Log::error('[TenantProfile] Failed to send verification email after profile update', [
                        'user_id' => $user->getKey(),
                        'tenant_id' => $request->attributes->get('tenant_id'),
                        'error' => $exception->getMessage(),
                    ]);
                }
            }
        }

        return response()->json([
            'message' => 'Profil erfolgreich aktualisiert.',
            'data' => $this->transformUser($user->fresh()),
        ]);
    }

    /**
     * @return array<string, mixed>
     */
    private function transformUser(User $user): array
    {
        return [
            'id' => $user->getKey(),
            'name' => $user->name,
            'email' => $user->email,
            'preferred_locale' => $user->preferred_locale,
            'email_verified' => $user->email_verified_at !== null,
            'email_verified_at' => $user->email_verified_at?->toIso8601String(),
        ];
    }
}
