<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\FaceVerification;
use App\Models\Notification;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class FaceVerificationsController extends Controller
{
    public function index(Request $request)
    {
        $verifications = FaceVerification::with(['user', 'duplicateOfUser', 'withdrawal'])
            ->when($request->filled('status'), fn ($query) => $query->where('status', $request->input('status')))
            ->when($request->filled('context'), fn ($query) => $query->where('context', $request->input('context')))
            ->latest()
            ->paginate(24)
            ->withQueryString();

        return view('admin.face-verifications', compact('verifications'));
    }

    public function update(Request $request, FaceVerification $faceVerification)
    {
        $data = $request->validate([
            'action' => ['required', 'in:approve,reject,review'],
            'admin_note' => ['nullable', 'string', 'max:1000'],
        ]);

        $this->review($faceVerification, $data['action'], $request->user()->id, $data['admin_note'] ?? null);

        return back()->with('success', 'Face verification updated.');
    }

    public function bulk(Request $request)
    {
        $data = $request->validate([
            'ids' => ['required', 'array', 'min:1'],
            'ids.*' => ['integer', 'exists:face_verifications,id'],
            'action' => ['required', 'in:approve,reject,review,delete'],
        ]);

        $query = FaceVerification::whereIn('id', $data['ids']);
        if ($data['action'] === 'delete') {
            $checks = $query->with('withdrawal')->get();
            foreach ($checks as $check) {
                if ($check->withdrawal?->status === 'pending' && $check->withdrawal->verification_status !== 'approved') {
                    $this->review($check, 'reject', $request->user()->id, 'Face check removed by administrator.');
                }
                $check->delete();
            }
            $count = $checks->count();
        } else {
            $checks = $query->get();
            foreach ($checks as $check) {
                $this->review($check, $data['action'], $request->user()->id);
            }
            $count = $checks->count();
        }

        return back()->with('success', "Bulk action applied to {$count} face check(s).");
    }

    private function review(FaceVerification $faceVerification, string $action, int $reviewerId, ?string $note = null): void
    {
        DB::transaction(function () use ($faceVerification, $action, $reviewerId, $note) {
            $check = FaceVerification::whereKey($faceVerification->id)->lockForUpdate()->firstOrFail();
            $status = match ($action) {
                'approve' => 'approved',
                'reject' => 'rejected',
                default => 'duplicate_review',
            };

            $check->update([
                'status' => $status,
                'admin_note' => $note,
                'reviewed_at' => now(),
                'reviewed_by' => $reviewerId,
            ]);

            if (!$check->withdrawal_id) {
                return;
            }

            $withdrawal = $check->withdrawal()->lockForUpdate()->first();
            if (!$withdrawal || $withdrawal->status !== 'pending') {
                return;
            }

            if ($action === 'approve') {
                if ($withdrawal->verification_status !== 'approved') {
                    $withdrawal->update(['verification_status' => 'approved']);
                    Notification::create([
                        'user_id' => $withdrawal->user_id,
                        'title' => 'Face check approved',
                        'message' => 'Your '.format_coins_as_usd($withdrawal->amount).' cashout moved to payment review.',
                    ]);
                }
                return;
            }

            if ($action === 'reject' && $withdrawal->verification_status !== 'rejected') {
                $withdrawal->update([
                    'verification_status' => 'rejected',
                    'status' => 'rejected',
                ]);
                $user = User::whereKey($withdrawal->user_id)->lockForUpdate()->firstOrFail();
                $user->increment('current_points', (float) $withdrawal->amount);
                Notification::create([
                    'user_id' => $withdrawal->user_id,
                    'title' => 'Cashout face check rejected',
                    'message' => 'Your reserved cashout was cancelled and '.number_format($withdrawal->amount, 0).' coins were returned.',
                ]);
                return;
            }

            if ($action === 'review' && $withdrawal->verification_status !== 'approved') {
                $withdrawal->update(['verification_status' => 'review']);
            }
        }, 3);
    }
}
