<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\AdminUser;
use App\Models\AuditLog;
use App\Models\Investor;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;

class AuthController extends Controller
{
    /**
     * Admin login
     * POST /api/auth/admin/login
     */
    public function adminLogin(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'email' => 'required|email',
            'password' => 'required|string',
        ]);

        $admin = AdminUser::where('email', strtolower($validated['email']))->first();

        if (!$admin || !Hash::check($validated['password'], $admin->password)) {
            throw ValidationException::withMessages([
                'email' => ['The provided credentials are incorrect.'],
            ]);
        }

        if (!$admin->is_active) {
            return response()->json([
                'error' => true,
                'message' => 'Your account is inactive. Please contact an administrator.',
                'code' => 'ACCOUNT_INACTIVE',
            ], 403);
        }

        // Update last login
        $admin->update(['last_login' => now()]);

        // Create token
        $token = $admin->createToken('admin-token', [$admin->role])->plainTextToken;

        // Log the action
        AuditLog::create([
            'admin_user_id' => $admin->id,
            'action' => 'login',
            'ip_address' => $request->ip(),
            'user_agent' => $request->userAgent(),
            'description' => 'Admin logged in',
        ]);

        return response()->json([
            'success' => true,
            'data' => [
                'user' => [
                    'id' => $admin->id,
                    'name' => $admin->name,
                    'email' => $admin->email,
                    'role' => $admin->role,
                ],
                'token' => $token,
                'token_type' => 'Bearer',
            ],
            'meta' => [
                'timestamp' => now()->toIso8601String(),
            ],
        ]);
    }

    /**
     * Admin logout
     * POST /api/auth/admin/logout
     */
    public function adminLogout(Request $request): JsonResponse
    {
        $admin = $request->user();

        // Log the action
        if ($admin) {
            AuditLog::create([
                'admin_user_id' => $admin->id,
                'action' => 'logout',
                'ip_address' => $request->ip(),
                'user_agent' => $request->userAgent(),
                'description' => 'Admin logged out',
            ]);
        }

        // Revoke current token
        $request->user()->currentAccessToken()->delete();

        return response()->json([
            'success' => true,
            'message' => 'Successfully logged out',
            'meta' => [
                'timestamp' => now()->toIso8601String(),
            ],
        ]);
    }

    /**
     * Get current admin user
     * GET /api/auth/admin/me
     */
    public function adminMe(Request $request): JsonResponse
    {
        $admin = $request->user();

        return response()->json([
            'success' => true,
            'data' => [
                'id' => $admin->id,
                'name' => $admin->name,
                'email' => $admin->email,
                'role' => $admin->role,
                'permissions' => AdminUser::ROLE_PERMISSIONS[$admin->role] ?? [],
                'last_login' => $admin->last_login,
            ],
            'meta' => [
                'timestamp' => now()->toIso8601String(),
            ],
        ]);
    }

    /**
     * Investor request access (magic link/OTP)
     * POST /api/auth/investor/request-access
     */
    public function investorRequestAccess(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'email' => 'required|email',
        ]);

        $investor = Investor::where('email', strtolower($validated['email']))->first();

        if (!$investor) {
            // Don't reveal if investor exists or not
            return response()->json([
                'success' => true,
                'message' => 'If an account exists with this email, you will receive an access link.',
                'meta' => [
                    'timestamp' => now()->toIso8601String(),
                ],
            ]);
        }

        // Generate access token
        $token = bin2hex(random_bytes(32));
        $expiresAt = now()->addHours(24);

        // Store token (in a real app, store in database or cache)
        cache()->put(
            "investor_access_{$token}",
            [
                'investor_id' => $investor->id,
                'email' => $investor->email,
                'expires_at' => $expiresAt,
            ],
            $expiresAt
        );

        // Send email with magic link (would implement actual email sending)
        $accessUrl = config('app.frontend_url') . "/investor/access?token={$token}";

        // Log for now
        \Log::info('Investor access link generated', [
            'investor_id' => $investor->id,
            'access_url' => $accessUrl,
        ]);

        return response()->json([
            'success' => true,
            'message' => 'If an account exists with this email, you will receive an access link.',
            'meta' => [
                'timestamp' => now()->toIso8601String(),
            ],
        ]);
    }

    /**
     * Verify investor access token
     * POST /api/auth/investor/verify-access
     */
    public function investorVerifyAccess(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'token' => 'required|string',
        ]);

        $tokenData = cache()->get("investor_access_{$validated['token']}");

        if (!$tokenData) {
            return response()->json([
                'error' => true,
                'message' => 'Invalid or expired access token',
                'code' => 'INVALID_TOKEN',
            ], 401);
        }

        $investor = Investor::find($tokenData['investor_id']);

        if (!$investor) {
            return response()->json([
                'error' => true,
                'message' => 'Investor not found',
                'code' => 'INVESTOR_NOT_FOUND',
            ], 404);
        }

        // Update last login
        $investor->update([
            'last_login' => now(),
            'dashboard_access' => true,
        ]);

        // Invalidate the token
        cache()->forget("investor_access_{$validated['token']}");

        // Generate session token
        $sessionToken = bin2hex(random_bytes(32));
        cache()->put(
            "investor_session_{$sessionToken}",
            ['investor_id' => $investor->id],
            now()->addHours(8)
        );

        return response()->json([
            'success' => true,
            'data' => [
                'investor' => [
                    'id' => $investor->id,
                    'full_name' => $investor->full_name,
                    'email' => $investor->email,
                ],
                'session_token' => $sessionToken,
            ],
            'meta' => [
                'timestamp' => now()->toIso8601String(),
            ],
        ]);
    }

    /**
     * Register new admin (super admin only)
     * POST /api/auth/admin/register
     */
    public function registerAdmin(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|email|unique:admin_users,email',
            'password' => 'required|string|min:8|confirmed',
            'role' => 'required|in:' . implode(',', AdminUser::ROLES),
        ]);

        $admin = AdminUser::create([
            'name' => $validated['name'],
            'email' => strtolower($validated['email']),
            'password' => Hash::make($validated['password']),
            'role' => $validated['role'],
            'is_active' => true,
        ]);

        // Log the action
        AuditLog::log(
            'admin.create',
            'admin_user',
            $admin->id,
            [],
            ['email' => $admin->email, 'role' => $admin->role],
            'New admin user created'
        );

        return response()->json([
            'success' => true,
            'data' => [
                'id' => $admin->id,
                'name' => $admin->name,
                'email' => $admin->email,
                'role' => $admin->role,
            ],
            'meta' => [
                'timestamp' => now()->toIso8601String(),
            ],
        ], 201);
    }
}
