<?php

namespace Modules\Vrc\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Modules\Vrc\Entities\VrcEstimate;
use Modules\Vrc\Entities\VrcPortalOwner;
use Modules\Vrc\Entities\VrcRepairOrder;
use Modules\Vrc\Entities\VrcRepairOrderStatusHistory;
use Modules\Vrc\Entities\VrcVehicle;
use Modules\Vrc\Services\Contracts\NotificationServiceContract;
use Modules\Vrc\Services\Settings\VrcSettings;

/**
 * Phase 3 — authenticated vehicle-owner portal (phone-OTP). Self-contained owner
 * session (key vrc_portal_owner_id), separate from the ERP auth guard. Gives the
 * owner their vehicles, repair history, live tracking, estimates and invoices.
 * Single-tenant resolution (one business per project) mirrors PortalBookingController.
 */
class OwnerPortalController extends Controller
{
    public function loginForm()
    {
        if (session('vrc_portal_owner_id')) {
            return redirect()->route('vrc.portal.account.dashboard');
        }
        return view('vrc::portal.account.login');
    }

    public function requestOtp(Request $request)
    {
        $request->validate(['phone' => 'required|string|max:30']);
        $owner = VrcPortalOwner::where('business_id', $this->businessId())
            ->where('phone', $request->input('phone'))->where('is_active', true)->first();

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

            // Dispatch via the configured channel (SMS/WhatsApp) through the ERP
            // notification boundary. Best-effort: a gateway failure never blocks
            // login — the owner can retry, and the demo fallback below still works.
            $this->dispatchOtp($owner, $code);

            // Demo: surface the code so the flow is testable without a live gateway.
            if (env('DEMO_LOGIN', false) || config('app.debug')) {
                session()->flash('vrc_portal_demo_code', $code);
            }
        }

        // Always report "sent" (don't disclose which phones are registered).
        return back()->with('vrc_portal_msg', 'If the number is registered, a one-time code has been sent.')
            ->with('vrc_portal_phone', $request->input('phone'));
    }

    public function verifyOtp(Request $request)
    {
        $request->validate(['phone' => 'required|string|max:30', 'otp' => 'required|string|max:10']);
        $owner = VrcPortalOwner::where('business_id', $this->businessId())
            ->where('phone', $request->input('phone'))->where('is_active', true)->first();

        if (! $owner || ! $owner->otp_code || $owner->otp_code !== $request->input('otp')
            || ! $owner->otp_expires_at || $owner->otp_expires_at->isPast()) {
            return back()->with('vrc_portal_error', 'Invalid or expired code.')
                ->with('vrc_portal_phone', $request->input('phone'));
        }

        $owner->update(['otp_code' => null, 'otp_expires_at' => null, 'last_login_at' => now()]);
        session(['vrc_portal_owner_id' => $owner->id, 'vrc_portal_business_id' => $owner->business_id]);

        return redirect()->route('vrc.portal.account.dashboard');
    }

    public function dashboard()
    {
        $owner = $this->currentOwner();
        if (! $owner) {
            return redirect()->route('vrc.portal.account.login');
        }
        $bid = $owner->business_id;

        $vehicles = VrcVehicle::where('business_id', $bid)->where('erp_customer_id', $owner->erp_customer_id)->get();
        $orders = VrcRepairOrder::where('business_id', $bid)->where('erp_customer_id', $owner->erp_customer_id)
            ->orderByDesc('id')->limit(20)->get();
        $estimates = VrcEstimate::where('business_id', $bid)->where('erp_customer_id', $owner->erp_customer_id)
            ->orderByDesc('id')->limit(20)->get();

        return view('vrc::portal.account.dashboard', compact('owner', 'vehicles', 'orders', 'estimates'));
    }

    public function vehicle($id)
    {
        $owner = $this->currentOwner();
        if (! $owner) {
            return redirect()->route('vrc.portal.account.login');
        }
        $bid = $owner->business_id;

        $vehicle = VrcVehicle::where('business_id', $bid)->where('erp_customer_id', $owner->erp_customer_id)->findOrFail($id);
        $orders = VrcRepairOrder::where('business_id', $bid)->where('vehicle_id', $vehicle->id)->orderByDesc('id')->get();
        $history = VrcRepairOrderStatusHistory::where('business_id', $bid)
            ->whereIn('repair_order_id', $orders->pluck('id'))->orderByDesc('id')->limit(50)->get();

        return view('vrc::portal.account.vehicle', compact('owner', 'vehicle', 'orders', 'history'));
    }

    public function logout(Request $request)
    {
        $request->session()->forget(['vrc_portal_owner_id', 'vrc_portal_business_id']);
        return redirect()->route('vrc.portal.account.login');
    }

    /**
     * Deliver the one-time code over the business's configured channel
     * (sms|whatsapp) via the ERP notification boundary. Sends to the registered
     * contact on file (not an arbitrary typed number) so a stolen/guessed phone
     * can't redirect the code. Safe no-op when no gateway is configured.
     */
    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_otp:' . $owner->id . ':' . $code]
            );
        } catch (\Throwable $e) {
            // Best-effort: never block login on a delivery failure.
            \Log::warning('[vrc.portal] OTP dispatch failed: ' . $e->getMessage());
        }
    }

    private function currentOwner(): ?VrcPortalOwner
    {
        $id = session('vrc_portal_owner_id');
        return $id ? VrcPortalOwner::find($id) : null;
    }

    private function businessId(): int
    {
        return (int) (\App\Business::min('id') ?? 1);
    }
}
