<?php

namespace Modules\VrcPortalApi\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Modules\Vrc\Entities\VrcPortalOwner;
use Modules\Vrc\Entities\VrcPortalOwnerToken;
use Modules\Vrc\Services\Contracts\NotificationServiceContract;
use Modules\Vrc\Services\Settings\VrcSettings;

/**
 * VRC owner PWA auth — phone OTP. Mirrors the web OwnerPortalController flow but
 * issues a bearer token (VrcPortalOwnerToken) instead of a session.
 */
class OwnerAuthController extends Controller
{
    public function otpRequest(Request $request): JsonResponse
    {
        $data = $request->validate(['phone' => 'required|string|max:30']);
        $phone = trim($data['phone']);

        $owner = VrcPortalOwner::where('phone', $phone)->where('is_active', true)->first();
        $payload = ['sent' => false];

        if ($owner) {
            $code = (string) random_int(100000, 999999);
            $owner->update(['otp_code' => $code, 'otp_expires_at' => now()->addMinutes(10)]);
            $this->dispatchOtp($owner, $code);
            $payload['sent'] = true;

            if (env('DEMO_LOGIN', false) || config('app.debug')) {
                $payload['dev_code'] = $code; // demo convenience only
            }
        }

        // Never disclose whether a number is registered.
        return response()->json($payload + ['message' => 'If the number is registered, a code has been sent.']);
    }

    public function otpVerify(Request $request): JsonResponse
    {
        $data = $request->validate([
            'phone' => 'required|string|max:30',
            'otp'   => 'required|string|max:10',
        ]);

        $owner = VrcPortalOwner::where('phone', trim($data['phone']))->where('is_active', true)->first();

        if (! $owner || ! $owner->otp_code || ! hash_equals((string) $owner->otp_code, (string) $data['otp'])
            || ! $owner->otp_expires_at || $owner->otp_expires_at->isPast()) {
            return response()->json(['message' => 'Invalid or expired code.'], 422);
        }

        $owner->update(['otp_code' => null, 'otp_expires_at' => null, 'last_login_at' => now()]);
        $token = VrcPortalOwnerToken::issue($owner, $request->userAgent(),
            (int) config('vrcportalapi.owner_token_ttl_days', 90));

        return response()->json([
            'token' => $token,
            'me'    => $this->mePayload($owner),
        ]);
    }

    public function logout(Request $request): JsonResponse
    {
        VrcPortalOwnerToken::revoke((string) $request->bearerToken());
        return response()->json(['ok' => true]);
    }

    private function mePayload(VrcPortalOwner $owner): array
    {
        return [
            'id'    => $owner->id,
            'name'  => $owner->name,
            'phone' => $owner->phone,
            'email' => $owner->email,
        ];
    }

    private function dispatchOtp(VrcPortalOwner $owner, string $code): void
    {
        try {
            if (! $owner->erp_customer_id) {
                return;
            }
            $channel = VrcSettings::get((int) $owner->business_id, 'comms_channel', 'sms');
            $body = __('vrc::lang.portal_otp_body', ['code' => $code, 'app' => config('app.name', 'Service Center')]);
            app(NotificationServiceContract::class)->send(
                (int) $owner->business_id, (int) $owner->erp_customer_id, $channel, $body,
                ['dedupe_key' => 'vrc_portal_app_otp:' . $owner->id . ':' . $code]
            );
        } catch (\Throwable $e) {
            \Log::warning('[vrc.portalapi] OTP dispatch failed: ' . $e->getMessage());
        }
    }
}
