<?php

namespace App\Http\Controllers\Wani;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\WaniToken;
use App\Support\XmlResponder;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

class AuthController extends Controller
{
    /**
     * POST /api/wani/v1/auth/initiate
     *
     * Accepts:
     *   <AuthRequest>
     *     <User><Mobile>9999999999</Mobile></User>
     *     <Hotspot>
     *       <SSID>PMWANI_Free_WiFi_1</SSID>
     *       <BSSID>00:11:22:33:44:55</BSSID>
     *     </Hotspot>
     *   </AuthRequest>
     */
    public function initiate(Request $request)
    {
        $mobile = $this->extractMobile($request);
        $hotspot = $this->extractHotspot($request);

        if (empty($mobile)) {
            return XmlResponder::error('MISSING_MOBILE', 'User mobile is required', 400);
        }

        $user = User::where('phone', $mobile)->first();

        if (!$user) {
            Log::channel('single')->info('wani.v1.auth.initiate.user_not_found', [
                'mobile' => $this->maskMobile($mobile),
                'ip' => $request->ip(),
            ]);
            return XmlResponder::error('USER_NOT_FOUND', 'User is not registered', 404);
        }

        if (empty($user->otp_verified_on)) {
            return XmlResponder::error('USER_NOT_VERIFIED', 'User has not completed OTP verification', 403);
        }

        $token = Str::random(48);
        $expirySeconds = 300;

        WaniToken::create([
            'token' => $token,
            'user_id' => $user->id,
            'hotspot_ssid' => $hotspot['ssid'] ?? null,
            'hotspot_bssid' => $hotspot['bssid'] ?? null,
            'pdoa_provider_id' => $hotspot['provider_id'] ?? null,
            'expires_at' => now()->addSeconds($expirySeconds),
            'session_seconds' => 1800,
            'client_ip' => $request->ip(),
        ]);

        Log::channel('single')->info('wani.v1.auth.initiate.success', [
            'user_id' => $user->id,
            'mobile' => $this->maskMobile($mobile),
            'ssid' => $hotspot['ssid'] ?? null,
            'ip' => $request->ip(),
        ]);

        return XmlResponder::make([
            'Status' => 'SUCCESS',
            'Token' => $token,
            'Expiry' => (string) $expirySeconds,
            'SessionTime' => '1800',
        ], 'AuthResponse');
    }

    /**
     * POST /api/wani/v1/auth/validate
     *
     * Accepts:
     *   <TokenValidation>
     *     <Token>abc123...</Token>
     *   </TokenValidation>
     */
    public function validateToken(Request $request)
    {
        $token = $this->extractToken($request);

        if (empty($token)) {
            return XmlResponder::error('MISSING_TOKEN', 'Token is required', 400);
        }

        $record = WaniToken::where('token', $token)->first();

        if (!$record) {
            return XmlResponder::error('INVALID_TOKEN', 'Token not found', 401);
        }

        if ($record->isExpired()) {
            return XmlResponder::error('EXPIRED_TOKEN', 'Token has expired', 401);
        }

        if ($record->isUsed()) {
            return XmlResponder::error('TOKEN_ALREADY_USED', 'Token was already consumed', 409);
        }

        $record->update(['used_at' => now()]);

        Log::channel('single')->info('wani.v1.auth.validate.success', [
            'user_id' => $record->user_id,
            'token_id' => $record->id,
            'ip' => $request->ip(),
        ]);

        return XmlResponder::make([
            'Status' => 'AUTHORIZED',
            'SessionTime' => (string) $record->session_seconds,
            'UserId' => (string) $record->user_id,
        ], 'AccessResponse');
    }

    protected function extractMobile(Request $request): ?string
    {
        $mobile = $request->input('User.Mobile')
            ?? $request->input('Mobile')
            ?? data_get($request->all(), 'User.Mobile');

        return $mobile ? trim((string) $mobile) : null;
    }

    protected function extractHotspot(Request $request): array
    {
        $hotspot = $request->input('Hotspot') ?? [];

        return [
            'ssid' => $hotspot['SSID'] ?? null,
            'bssid' => $hotspot['BSSID'] ?? null,
            'provider_id' => $hotspot['ProviderId'] ?? $hotspot['Provider']['Id'] ?? null,
        ];
    }

    protected function extractToken(Request $request): ?string
    {
        $token = $request->input('Token') ?? $request->input('TokenValidation.Token');
        return $token ? trim((string) $token) : null;
    }

    protected function maskMobile(string $mobile): string
    {
        $len = strlen($mobile);
        if ($len < 4) return str_repeat('*', $len);
        return str_repeat('*', $len - 4) . substr($mobile, -4);
    }
}
