<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Device;
use App\Models\User;
use App\Models\Voucher;
use App\Services\FirebasePushService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use Illuminate\View\View;

class VouchersController extends Controller
{
    public function index(Request $request): View
    {
        $vouchers = Voucher::withCount('redemptions')
            ->latest()
            ->paginate(25);

        return view('admin.vouchers.index', compact('vouchers'));
    }

    public function create(): View
    {
        return view('admin.vouchers.create');
    }

    public function store(Request $request): RedirectResponse
    {
        $request->validate([
            'plan'       => 'required|in:starter,growth,pro',
            'period'     => 'required|in:monthly,yearly,lifetime',
            'days'       => 'required|integer|min:1|max:36500',
            'max_uses'   => 'required|integer|min:1|max:10000',
            'quantity'   => 'required|integer|min:1|max:100',
            'expires_at' => 'nullable|date',
            'notes'      => 'nullable|string|max:500',
        ]);

        $qty = (int) $request->input('quantity', 1);
        $created = 0;

        for ($i = 0; $i < $qty; $i++) {
            $code = strtoupper(Str::random(4) . '-' . Str::random(4) . '-' . Str::random(4));
            // Avoid duplicates
            while (Voucher::where('code', $code)->exists()) {
                $code = strtoupper(Str::random(4) . '-' . Str::random(4) . '-' . Str::random(4));
            }

            Voucher::create([
                'code'       => $code,
                'plan'       => $request->plan,
                'period'     => $request->period,
                'days'       => $request->days,
                'max_uses'   => $request->max_uses,
                'expires_at' => $request->expires_at,
                'notes'      => $request->notes,
                'created_by' => Auth::id(),
                'is_active'  => true,
            ]);
            $created++;
        }

        return redirect()->route('admin.vouchers.index')
            ->with('success', "{$created} voucher(s) created successfully.");
    }

    public function toggle(Voucher $voucher): RedirectResponse
    {
        $voucher->update(['is_active' => !$voucher->is_active]);
        $status = $voucher->is_active ? 'activated' : 'deactivated';
        return back()->with('success', "Voucher {$voucher->code} {$status}.");
    }

    public function destroy(Voucher $voucher): RedirectResponse
    {
        $voucher->delete();
        return redirect()->route('admin.vouchers.index')->with('success', 'Voucher deleted.');
    }

    /**
     * Returns users with non-revoked FCM devices for the push modal.
     * ?no_sub=1 filters users without an active subscription.
     */
    public function getDevices(Request $request, Voucher $voucher): JsonResponse
    {
        $noSub = (bool) $request->query('no_sub', false);

        $query = User::query()
            ->with(['devices' => fn($q) => $q->whereNotNull('fcm_token')->where('is_revoked', false)])
            ->whereHas('devices', fn($q) => $q->whereNotNull('fcm_token')->where('is_revoked', false));

        if ($noSub) {
            $query->whereDoesntHave('subscriptions', fn($q) =>
                $q->where('is_active', true)
                  ->where(fn($q2) => $q2->whereNull('expires_at')->orWhere('expires_at', '>', now()))
            );
        }

        $users = $query->get()->map(fn($u) => [
            'id'      => $u->id,
            'name'    => $u->name,
            'email'   => $u->email,
            'plan'    => $u->currentPlan(),
            'devices' => $u->devices->map(fn($d) => [
                'id'       => $d->id,
                'platform' => $d->platform,
                'model'    => $d->model ?? 'Unknown',
            ])->values(),
        ]);

        return response()->json(['ok' => true, 'users' => $users]);
    }

    /**
     * Send the voucher code to selected (or all) devices via push notification.
     * Returns JSON so the blade shows result without a full-page reload.
     */
    public function sendPush(Request $request, Voucher $voucher): JsonResponse
    {
        $request->validate([
            'title'        => 'nullable|string|max:120',
            'body'         => 'nullable|string|max:500',
            'device_ids'   => 'nullable|array',
            'device_ids.*' => 'string',
        ]);

        $title     = $request->input('title') ?: 'Your exclusive voucher code';
        $body      = $request->input('body')  ?: 'Use code ' . $voucher->code . ' to get a discount on your subscription.';
        $deviceIds = $request->input('device_ids', []);

        $push = app(FirebasePushService::class);
        if (!$push->isConfigured()) {
            return response()->json(['ok' => false, 'message' => 'Push notifications are not configured (missing Firebase service account).']);
        }

        $query = Device::whereNotNull('fcm_token')->where('is_revoked', false);
        if (!empty($deviceIds)) {
            $query->whereIn('id', $deviceIds);
        }
        $tokens = $query->pluck('fcm_token')->unique()->values();

        if ($tokens->isEmpty()) {
            return response()->json(['ok' => false, 'message' => 'No active devices found for the selected recipients.']);
        }

        $sent = 0;
        $failed = 0;
        foreach ($tokens as $token) {
            $result = $push->sendToToken(
                (string) $token,
                $title,
                $body,
                ['voucher_code' => $voucher->code, 'type' => 'voucher'],
            );
            $result['ok'] ? $sent++ : $failed++;
        }

        return response()->json([
            'ok'      => true,
            'message' => "Sent to {$sent} device(s)." . ($failed ? " {$failed} failed." : ''),
        ]);
    }
}
