<?php

namespace App\Http\Controllers;

use App\Http\Responses\TwoFactorLoginResponse;
use Illuminate\Http\Request;
use Mtc\MercuryDataModels\TwoFactorRememberedDevice;

class TwoFactorDeviceController extends Controller
{
    /**
     * List all remembered devices for the authenticated user.
     */
    public function index(Request $request)
    {
        $devices = TwoFactorRememberedDevice::query()
            ->where('user_id', $request->user()->id)
            ->where('expires_at', '>', now())
            ->orderBy('created_at', 'desc')
            ->get()
            ->map(function (TwoFactorRememberedDevice $device) use ($request) {
                return [
                    'id' => $device->id,
                    'user_agent' => $device->user_agent,
                    'ip_address' => $device->ip_address,
                    'created_at' => $device->created_at->toIso8601String(),
                    'expires_at' => $device->expires_at->toIso8601String(),
                    'is_current' => $this->isCurrentDevice($device, $request),
                    'browser' => $this->parseBrowser($device->user_agent),
                    'device' => $this->parseDevice($device->user_agent),
                ];
            });

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

    /**
     * Revoke a specific remembered device.
     */
    public function destroy(Request $request, $id)
    {
        $device = TwoFactorRememberedDevice::query()
            ->where('user_id', $request->user()->id)
            ->where('id', $id)
            ->first();

        if (!$device) {
            return response()->json(['message' => 'Device not found'], 404);
        }

        $device->delete();

        return response()->json(['message' => 'Device removed successfully']);
    }

    /**
     * Revoke all remembered devices for the authenticated user.
     */
    public function destroyAll(Request $request)
    {
        TwoFactorRememberedDevice::query()
            ->where('user_id', $request->user()->id)
            ->delete();

        return response()->json(['message' => 'All devices removed successfully']);
    }

    /**
     * Check if the device matches the current request.
     */
    protected function isCurrentDevice(TwoFactorRememberedDevice $device, Request $request): bool
    {
        $cookieName = TwoFactorLoginResponse::COOKIE_NAME;
        $cookie = $request->cookie($cookieName);

        if (!$cookie) {
            return false;
        }

        $parts = explode('|', $cookie);
        if (count($parts) !== 2) {
            return false;
        }

        [$userId, $token] = $parts;

        return $device->token === hash('sha256', $token);
    }

    /**
     * Parse browser from user agent string.
     */
    protected function parseBrowser(?string $userAgent): string
    {
        if (!$userAgent) {
            return 'Unknown';
        }

        if (str_contains($userAgent, 'Firefox')) {
            return 'Firefox';
        }
        if (str_contains($userAgent, 'Edg')) {
            return 'Edge';
        }
        if (str_contains($userAgent, 'Chrome')) {
            return 'Chrome';
        }
        if (str_contains($userAgent, 'Safari')) {
            return 'Safari';
        }
        if (str_contains($userAgent, 'Opera') || str_contains($userAgent, 'OPR')) {
            return 'Opera';
        }

        return 'Unknown';
    }

    /**
     * Parse device/OS from user agent string.
     */
    protected function parseDevice(?string $userAgent): string
    {
        if (!$userAgent) {
            return 'Unknown';
        }

        if (str_contains($userAgent, 'Windows')) {
            return 'Windows';
        }
        if (str_contains($userAgent, 'Macintosh') || str_contains($userAgent, 'Mac OS')) {
            return 'macOS';
        }
        if (str_contains($userAgent, 'Linux')) {
            return 'Linux';
        }
        if (str_contains($userAgent, 'iPhone')) {
            return 'iPhone';
        }
        if (str_contains($userAgent, 'iPad')) {
            return 'iPad';
        }
        if (str_contains($userAgent, 'Android')) {
            return 'Android';
        }

        return 'Unknown';
    }
}
