<?php

namespace App\Http\Controllers\Api;

use App\Http\Resources\UserResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Storage;
use Illuminate\Validation\Rules\Password;
use Illuminate\Validation\ValidationException;
use PragmaRX\Google2FALaravel\Facade as Google2FA;

class ProfileController extends ApiController
{
    public function show(Request $request): UserResource
    {
        return new UserResource($request->user()->load(['company', 'branch', 'role.permissions']));
    }

    public function update(Request $request): UserResource
    {
        $user = $request->user();

        $data = $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'phone' => ['nullable', 'string', 'max:30'],
        ]);

        $user->update($data);

        return new UserResource($user->load(['company', 'branch', 'role.permissions']));
    }

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

        $request->validate([
            'current_credential' => ['required', 'string'],
            'password' => ['nullable', 'string', Password::min(8)->letters()->numbers(), 'confirmed'],
            'pin' => ['nullable', 'string', 'size:4'],
        ]);

        // Check current credential (either password or pin)
        $currentMatch = ($user->password && Hash::check($request->string('current_credential'), $user->password)) ||
                        (!$user->password && $user->pin && Hash::check($request->string('current_credential'), $user->pin));

        if (!$currentMatch) {
            throw ValidationException::withMessages([
                'current_credential' => ['The current credential does not match our records.'],
            ]);
        }

        if ($request->filled('password')) {
            $user->password = $request->string('password');
        }

        if ($request->filled('pin')) {
            $user->pin = $request->string('pin');
        }

        $user->save();

        return response()->json(['message' => 'Security credentials updated successfully.']);
    }

    public function updateAvatar(Request $request): JsonResponse
    {
        $request->validate([
            'avatar' => ['required', 'image', 'max:2048'], // 2MB max
        ]);

        $user = $request->user();

        if ($user->avatar_url) {
            // Optional: delete old avatar
            $oldPath = str_replace(url('storage/'), '', $user->avatar_url);
            Storage::disk('public')->delete($oldPath);
        }

        $path = $request->file('avatar')->store('avatars', 'public');
        $user->avatar_url = Storage::url($path);
        $user->save();

        return response()->json([
            'message' => 'Avatar updated successfully.',
            'avatar_url' => $user->avatar_url,
        ]);
    }

    public function mfaSetup(Request $request): JsonResponse
    {
        $user = $request->user();
        
        $secret = Google2FA::generateSecretKey();
        
        // We temporarily store it in session or return it to be sent back during verification
        // For stateless API, we can't use session. We'll return it and the user must provide it in the next step.
        // Or store it in a temporary 'mfa_secret_pending' column.
        
        $qrCodeInline = Google2FA::getQRCodeInline(
            config('app.name'),
            $user->email,
            $secret
        );

        return response()->json([
            'secret' => $secret,
            'qr_code_svg' => $qrCodeInline,
        ]);
    }

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

        $user = $request->user();
        
        $valid = Google2FA::verifyKey($request->string('secret'), $request->string('code'));

        if (!$valid) {
            throw ValidationException::withMessages([
                'code' => ['Invalid verification code.'],
            ]);
        }

        $user->two_factor_secret = $request->string('secret');
        $user->two_factor_enabled = true;
        // Generate recovery codes
        $user->two_factor_recovery_codes = encrypt(json_encode([
            str_pad(random_int(0, 99999999), 8, '0', STR_PAD_LEFT),
            str_pad(random_int(0, 99999999), 8, '0', STR_PAD_LEFT),
            str_pad(random_int(0, 99999999), 8, '0', STR_PAD_LEFT),
            str_pad(random_int(0, 99999999), 8, '0', STR_PAD_LEFT),
        ]));
        
        $user->save();

        return response()->json([
            'message' => 'MFA enabled successfully.',
            'recovery_codes' => json_decode(decrypt($user->two_factor_recovery_codes)),
        ]);
    }

    public function mfaDisable(Request $request): JsonResponse
    {
        $request->validate([
            'current_credential' => ['required', 'string'],
        ]);

        $user = $request->user();
        
        $currentMatch = ($user->password && Hash::check($request->string('current_credential'), $user->password)) ||
                        (!$user->password && $user->pin && Hash::check($request->string('current_credential'), $user->pin));

        if (!$currentMatch) {
            throw ValidationException::withMessages([
                'current_credential' => ['The current credential does not match our records.'],
            ]);
        }

        $user->two_factor_enabled = false;
        $user->two_factor_secret = null;
        $user->two_factor_recovery_codes = null;
        $user->save();

        return response()->json(['message' => 'MFA disabled successfully.']);
    }
}
