<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Api\V1\Concerns\RespondsWithApi;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

class PaymentController extends Controller
{
    use RespondsWithApi;

    public function createForBooking(Request $request, int $booking)
    {
        $row = DB::table('bookings')->where('id', $booking)->where('user_id', $request->user()->id)->first();

        if (! $row) {
            return $this->fail('BOOKING_NOT_FOUND', 'Booking not found.', [], 404);
        }

        $paymentId = DB::table('payments')->insertGetId([
            'payment_number' => 'PY-' . now()->format('Ymd') . '-' . strtoupper(Str::random(6)),
            'user_id' => $request->user()->id,
            'booking_id' => $booking,
            'quote_id' => $row->quote_id,
            'gateway' => env('PAYMENT_GATEWAY', 'local'),
            'gateway_order_id' => 'order_' . strtolower(Str::random(12)),
            'amount' => $row->payable_total,
            'currency' => 'INR',
            'status' => 'created',
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        return $this->ok(DB::table('payments')->where('id', $paymentId)->first(), 'Payment order created.', [], 201);
    }

    public function verify(Request $request, int $payment)
    {
        $data = $request->validate([
            'gateway_payment_id' => ['nullable', 'string', 'max:120'],
            'method' => ['nullable', 'string', 'max:40'],
            'status' => ['nullable', 'in:authorized,captured,failed'],
        ]);

        $row = DB::table('payments')->where('id', $payment)->where('user_id', $request->user()->id)->first();

        if (! $row) {
            return $this->fail('PAYMENT_NOT_FOUND', 'Payment not found.', [], 404);
        }

        $status = $data['status'] ?? 'captured';

        DB::table('payment_attempts')->insert([
            'payment_id' => $payment,
            'gateway_payment_id' => $data['gateway_payment_id'] ?? 'local_' . Str::random(10),
            'method' => $data['method'] ?? 'upi',
            'status' => $status,
            'response_json' => json_encode($data),
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        DB::table('payments')->where('id', $payment)->update([
            'status' => $status,
            'paid_at' => $status === 'captured' ? now() : null,
            'updated_at' => now(),
        ]);

        if ($row->booking_id && $status === 'captured') {
            DB::table('bookings')->where('id', $row->booking_id)->update([
                'payment_status' => 'paid',
                'updated_at' => now(),
            ]);
        }

        return $this->ok(DB::table('payments')->where('id', $payment)->first(), 'Payment verified.');
    }

    public function payments(Request $request)
    {
        return $this->ok(DB::table('payments')->where('user_id', $request->user()->id)->latest('id')->paginate(20));
    }

    public function wallet(Request $request)
    {
        $wallet = DB::table('wallet_accounts')->where('user_id', $request->user()->id)->first();

        if (! $wallet) {
            $id = DB::table('wallet_accounts')->insertGetId([
                'user_id' => $request->user()->id,
                'balance' => 0,
                'currency' => 'INR',
                'status' => 'active',
                'created_at' => now(),
                'updated_at' => now(),
            ]);
            $wallet = DB::table('wallet_accounts')->where('id', $id)->first();
        }

        return $this->ok($wallet);
    }

    public function topUpWallet(Request $request)
    {
        $data = $request->validate(['amount' => ['required', 'numeric', 'min:1', 'max:10000']]);
        $wallet = $this->wallet($request)->getData()->data;
        $balance = (float) $wallet->balance + (float) $data['amount'];

        DB::table('wallet_accounts')->where('id', $wallet->id)->update(['balance' => $balance, 'updated_at' => now()]);
        DB::table('wallet_transactions')->insert([
            'wallet_account_id' => $wallet->id,
            'transaction_type' => 'topup',
            'amount' => $data['amount'],
            'balance_after' => $balance,
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        return $this->ok(DB::table('wallet_accounts')->where('id', $wallet->id)->first(), 'Wallet topped up.');
    }

    public function walletTransactions(Request $request)
    {
        $wallet = DB::table('wallet_accounts')->where('user_id', $request->user()->id)->first();

        return $this->ok($wallet ? DB::table('wallet_transactions')->where('wallet_account_id', $wallet->id)->latest('id')->paginate(20) : []);
    }

    public function refunds(Request $request)
    {
        return $this->ok(DB::table('refunds')
            ->join('bookings', 'bookings.id', '=', 'refunds.booking_id')
            ->where('bookings.user_id', $request->user()->id)
            ->select('refunds.*')
            ->latest('refunds.id')
            ->paginate(20));
    }
}
