<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\OtpCode;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class AuthController extends Controller
{
    /**
     * POST /api/auth/request-otp
     * Send a 6-digit OTP to the given phone number.
     */
    public function requestOtp(Request $request): JsonResponse
    {
        $request->validate(['phone' => 'required|string|min:9|max:20']);

        $phone = $this->normalisePhone($request->phone);

        // Demo phone skips SMS in non-production — OTP is always 000000
        if ($this->isDemoPhone($phone)) {
            return response()->json(['message' => 'OTP imetumwa', 'phone' => $phone, 'demo' => true]);
        }

        $code = str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT);

        // Invalidate previous unused OTPs for this phone
        OtpCode::where('phone', $phone)->where('is_used', false)->delete();

        OtpCode::create([
            'phone'      => $phone,
            'code'       => $code,
            'expires_at' => now()->addMinutes(10),
        ]);

        // Send via Africa's Talking (or log in development)
        $this->sendSms($phone, "Njiapanda: Nambari yako ya uthibitisho ni {$code}. Inaisha baada ya dakika 10.");

        return response()->json(['message' => 'OTP imetumwa', 'phone' => $phone]);
    }

    /**
     * POST /api/auth/verify-otp
     * Verify OTP and return a Sanctum token.
     */
    public function verifyOtp(Request $request): JsonResponse
    {
        $request->validate([
            'phone' => 'required|string',
            'code'  => 'required|string|size:6',
            'name'  => 'sometimes|string|max:100',
            'role'  => 'sometimes|in:driver,rider,both',
        ]);

        $phone = $this->normalisePhone($request->phone);

        // ── Demo phone bypass ──────────────────────────────────────────────────
        if ($this->isDemoPhone($phone)) {
            // Accept any code for the demo account (non-production only)
            abort_if(app()->isProduction(), 403, 'Demo account not available in production.');
        } else {
            // Normal OTP check
            $otp = OtpCode::where('phone', $phone)
                ->where('code', $request->code)
                ->where('is_used', false)
                ->where('expires_at', '>', now())
                ->latest()
                ->first();

            if (!$otp) {
                return response()->json(['message' => 'Nambari ya uthibitisho si sahihi au imekwisha muda'], 422);
            }

            $otp->update(['is_used' => true]);
        }

        $isDemoPhone = $this->isDemoPhone($phone);

        $user = User::firstOrCreate(
            ['phone' => $phone],
            [
                'name'              => $isDemoPhone ? 'Demo User' : ($request->name ?? 'Mtumiaji'),
                'role'              => $isDemoPhone ? 'both'       : ($request->role ?? 'rider'),
                'is_verified'       => $isDemoPhone,
                'phone_verified_at' => now(),
                'trip_credits'      => $isDemoPhone ? 10 : 3,
            ]
        );

        if (!$user->phone_verified_at) {
            $user->update(['phone_verified_at' => now()]);
        }

        $token = $user->createToken('mobile')->plainTextToken;

        return response()->json([
            'token' => $token,
            'user'  => $this->userResource($user),
        ]);
    }

    /**
     * POST /api/auth/register-vehicle
     * Register a vehicle for the authenticated driver.
     */
    public function registerVehicle(Request $request): JsonResponse
    {
        $request->validate([
            'make'          => 'required|string|max:50',
            'model'         => 'required|string|max:50',
            'year'          => 'required|integer|min:2000|max:2030',
            'color'         => 'required|string|max:30',
            'plate'         => 'required|string|max:15|unique:vehicles,plate',
            'seat_capacity' => 'required|integer|min:1|max:10',
        ]);

        $vehicle = $request->user()->vehicles()->create($request->only(
            'make', 'model', 'year', 'color', 'plate', 'seat_capacity'
        ));

        return response()->json(['vehicle' => $vehicle], 201);
    }

    /**
     * GET /api/auth/me
     */
    public function me(Request $request): JsonResponse
    {
        $user = $request->user()->load('vehicles', 'badges');
        return response()->json(['user' => $this->userResource($user)]);
    }

    /**
     * PATCH /api/auth/me
     */
    public function updateProfile(Request $request): JsonResponse
    {
        $request->validate([
            'name'                    => 'sometimes|string|max:100',
            'lang'                    => 'sometimes|in:sw,en',
            'role'                    => 'sometimes|in:driver,rider,both',
            'emergency_contact_phone' => 'sometimes|string|max:20',
            'fcm_token'               => 'sometimes|string',
        ]);

        $request->user()->update($request->only(
            'name', 'lang', 'role', 'emergency_contact_phone', 'fcm_token'
        ));

        return response()->json(['user' => $this->userResource($request->user()->fresh())]);
    }

    /**
     * POST /api/auth/logout
     */
    public function logout(Request $request): JsonResponse
    {
        $request->user()->currentAccessToken()->delete();
        return response()->json(['message' => 'Umefanikiwa kutoka.']);
    }

    /**
     * Returns true when the phone matches the configured demo/test account.
     * Only active in non-production environments.
     */
    private function isDemoPhone(string $normalisedPhone): bool
    {
        if (app()->isProduction()) return false;
        $demoPhone = config('app.demo_phone', env('DEMO_PHONE', ''));
        return $demoPhone && $normalisedPhone === $this->normalisePhone($demoPhone);
    }

    private function normalisePhone(string $phone): string
    {
        $phone = preg_replace('/\D/', '', $phone);
        // Tanzania: convert 07xxxxxxxx → +255 7xxxxxxxx
        if (str_starts_with($phone, '0') && strlen($phone) === 10) {
            $phone = '+255' . substr($phone, 1);
        } elseif (!str_starts_with($phone, '+')) {
            $phone = '+' . $phone;
        }
        return $phone;
    }

    private function sendSms(string $phone, string $message): void
    {
        if (app()->isProduction()) {
            // Africa's Talking integration (Phase 1 wires SMS key in .env)
            // \AfricasTalking\SDK\AfricasTalking::sms()->send([...]);
        }
        Log::info("SMS to {$phone}: {$message}");
    }

    private function userResource(User $user): array
    {
        return [
            'id'           => $user->id,
            'phone'        => $user->phone,
            'name'         => $user->name,
            'photo'        => $user->photo_path,
            'role'         => $user->role,
            'rating_avg'   => (float) $user->rating_avg,
            'strike_count' => $user->strike_count,
            'is_verified'  => $user->is_verified,
            'trip_credits' => $user->trip_credits,
            'lang'         => $user->lang,
            'badges'       => $user->badges?->where('revoked_at', null)->pluck('badge_type')->values(),
            'vehicles'     => $user->vehicles?->map(fn($v) => [
                'id'          => $v->id,
                'label'       => "{$v->color} {$v->make} {$v->model} ({$v->plate})",
                'seats'       => $v->seat_capacity,
                'is_verified' => (bool) $v->is_verified,
                'make'        => $v->make,
                'model'       => $v->model,
                'color'       => $v->color,
                'plate'       => $v->plate,
                'year'        => $v->year,
            ]),
        ];
    }
}
