<?php

namespace App\Http\Controllers;

use App\Services\SuccessTopupClient;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Validator;
use App\Models\BalanceLog;
use App\Models\IncomeHistory;
use App\Services\VoucherTransactionService;

class DrivePackController extends Controller
{
    // ড্রাইভ প্যাক লিস্ট
    public function index(Request $req, SuccessTopupClient $st)
    {
        $operator = $req->query('operator'); // GP/RB/AT/BL/TT/SK বা null
        $number   = old('number');

        $resp = $st->drives($operator ?: null);
        $list = [];
        if ($resp->ok()) {
            $json = $resp->json();
            $list = is_array($json['drives'] ?? null) ? $json['drives'] : [];
        }

        // নোট: UI-তে অফার/কমিশন দেখানোর সময় ২% কাটার কথা কোথাও দেখাবেন না।
        // offer = max(0, round(commission - (commission * 0.02), 2))

        $ops = ['GP'=>'Grameenphone','RB'=>'Robi','AT'=>'Airtel','BL'=>'Banglalink','TT'=>'Teletalk','SK'=>'Skitto'];

        return view('drive.index', [
            'operator' => $operator,
            'ops'      => $ops,
            'drives'   => $list,
            'number'   => $number,
            'user'     => Auth::user(),
        ]);
    }

    // ফিল্টার রিফ্রেশ
    public function refresh(Request $req)
    {
        $op     = $req->input('operator');
        $number = $req->input('number');
        return redirect()->route('drive.index', $op ? ['operator'=>$op] : [])->withInput(['number'=>$number]);
    }

    // ড্রাইভ প্যাক পার্চেজ
    public function purchase(Request $req, SuccessTopupClient $st)
    {
        $v = Validator::make($req->all(), [
            'number'     => ['required','regex:/^(01)\\d{9}$/'],
            'operator'   => ['required','in:GP,RB,AT,BL,TT,SK'],
            'type'       => ['required','in:prepaid,postpaid'],
            'package_id' => ['required','string'],
            'price'      => ['required','numeric','min:1'],
            'password'   => ['required','string','min:6'],
            'commission_display' => ['nullable'],
            'title'      => ['nullable','string','max:255'],
            'duration'   => ['nullable','numeric'],
        ],[
            'number.regex' => 'সঠিক ১১ সংখ্যার মোবাইল নম্বর দিন।',
            'password.required' => 'ক্রয় করতে পাসওয়ার্ড দিন।',
        ]);

        if ($v->fails()) return back()->withErrors($v)->withInput($req->except('password'));

        $user = Auth::user();
        if (!$user) return redirect()->route('login');

        if (!Hash::check((string) $req->input('password'), (string) $user->password)) {
            return back()
                ->with('error', 'ভুল পাসওয়ার্ড।')
                ->withInput($req->except('password'));
        }

        $number    = (string) $req->input('number');
        $operator  = (string) $req->input('operator');
        $type      = (string) $req->input('type');
        $packageId = (string) $req->input('package_id');
        $price     = (float)  $req->input('price');

        // provider commission (numeric sanitize)
        $providerCommission = (float) preg_replace('/[^\d.]/', '', (string)$req->input('commission_display', 0));

        if ($user->voucher_balance < $price) {
            return back()->with('error', 'ভাউচার ব্যালেন্স পর্যাপ্ত নয়।')->withInput($req->except('password'));
        }

        $trxid = 'DX'.now()->format('YmdHis').Str::upper(Str::random(6));

        // --- ডেবিট + লোকাল রেকর্ড ---
        DB::beginTransaction();
        try {
            $lockedUser = DB::table('users')->where('id', $user->id)->lockForUpdate()->first(['id', 'voucher_balance']);
            $beforeVoucher = (float) ($lockedUser->voucher_balance ?? 0);

            if ($beforeVoucher < $price) {
                DB::rollBack();
                return back()->with('error','ভাউচার ব্যালেন্স পর্যাপ্ত নয় (race condition)।')->withInput($req->except('password'));
            }

            $afterVoucher = $beforeVoucher - $price;
            DB::table('users')->where('id', $user->id)->update(['voucher_balance' => $afterVoucher]);

            $recId = DB::table('recharges')->insertGetId([
                'user_id'      => $user->id,
                'trxid'        => $trxid,
                'number'       => $number,
                'type'         => $type,
                'operator'     => $operator,
                'amount'       => $price,          // শুধু রেকর্ড—কমিশন ক্যাল্কে লাগবে না
                'package_id'   => $packageId,
                'is_drive'     => 1,
                'status'       => 'pending',
                'api_status'   => null,
                'message'      => null,
                'api_response' => null,
                'debited'      => 1,
                'refunded'     => 0,
                'commissioned' => 0,
                'commission'   => 0,
                'meta'         => json_encode([
                    'title'               => (string)$req->input('title'),
                    'duration'            => $req->input('duration'),
                    'provider_commission' => $providerCommission, // ✅ raw provider commission (টাকায়)
                    'source'              => 'drive_pack',
                ]),
                'created_at'   => now(),
                'updated_at'   => now(),
            ]);

            VoucherTransactionService::record(
                userId: (int) $user->id,
                direction: 'debit',
                amount: $price,
                before: $beforeVoucher,
                after: $afterVoucher,
                source: 'drive_pack_debit',
                description: 'ড্রাইভ প্যাক রিচার্জ #' . $recId . ' করার জন্য ভাউচার কাটা হয়েছে।',
                referenceType: 'recharge',
                referenceId: $recId,
                metadata: [
                    'trxid' => $trxid,
                    'mobile' => $number,
                    'operator' => $operator,
                    'package_id' => $packageId,
                ]
            );

            DB::commit();
        } catch (\Throwable $e) {
            DB::rollBack();
            return back()->with('error', 'লোকাল রেকর্ড তৈরির সময় সমস্যা: '.$e->getMessage())->withInput($req->except('password'));
        }

        // --- API কল (package_id সহ) ---
        $res = $st->rechargeDrive($number, $type, $operator, $packageId, $trxid);

        if ($res->failed()) {
            DB::beginTransaction();
            try {
                $lockedUser = DB::table('users')->where('id', $user->id)->lockForUpdate()->first(['id', 'voucher_balance']);
                $beforeVoucher = (float) ($lockedUser->voucher_balance ?? 0);
                $afterVoucher = $beforeVoucher + $price;
                DB::table('users')->where('id', $user->id)->update(['voucher_balance' => $afterVoucher]);

                DB::table('recharges')->where('id',$recId)->update([
                    'status'      => 'failed',
                    'api_status'  => 'Failed',
                    'message'     => 'HTTP error: '.$res->status(),
                    'api_response'=> json_encode($res->json()),
                    'refunded'    => 1,
                    'updated_at'  => now(),
                ]);

                VoucherTransactionService::record(
                    userId: (int) $user->id,
                    direction: 'credit',
                    amount: $price,
                    before: $beforeVoucher,
                    after: $afterVoucher,
                    source: 'drive_pack_refund',
                    description: 'ড্রাইভ প্যাক রিচার্জ #' . $recId . ' API ব্যর্থ হওয়ায় ভাউচার রিফান্ড।',
                    referenceType: 'recharge',
                    referenceId: $recId,
                    metadata: [
                        'trxid' => $trxid,
                        'http_status' => $res->status(),
                    ]
                );

                DB::commit();
            } catch (\Throwable $e) {
                DB::rollBack();
            }
            return redirect()->route('recharge.show', $recId)->with('error','API রিকোয়েস্ট ব্যর্থ (HTTP '.$res->status().')');
        }

        $body    = $res->json();
        $result  = (bool)($body['result'] ?? false);
        $message = (string)($body['message'] ?? 'No message');

        DB::table('recharges')->where('id',$recId)->update([
            'status'      => $result ? 'pending' : 'failed',
            'api_status'  => $result ? 'Pending' : 'Failed',
            'message'     => $message,
            'api_response'=> json_encode($body),
            'updated_at'  => now(),
        ]);

        if (!$result) {
            // ব্যর্থ -> রিফান্ড
            DB::beginTransaction();
            try {
                $rec = DB::table('recharges')->lockForUpdate()->where('id',$recId)->first();
                if ($rec && !$rec->refunded && $rec->debited) {
                    $lockedUser = DB::table('users')->where('id', $user->id)->lockForUpdate()->first(['id', 'voucher_balance']);
                    $beforeVoucher = (float) ($lockedUser->voucher_balance ?? 0);
                    $afterVoucher = $beforeVoucher + $price;
                    DB::table('users')->where('id', $user->id)->update(['voucher_balance' => $afterVoucher]);

                    DB::table('recharges')->where('id',$recId)->update([
                        'refunded'  => 1,
                        'updated_at'=> now(),
                    ]);

                    VoucherTransactionService::record(
                        userId: (int) $user->id,
                        direction: 'credit',
                        amount: $price,
                        before: $beforeVoucher,
                        after: $afterVoucher,
                        source: 'drive_pack_refund',
                        description: 'ড্রাইভ প্যাক রিচার্জ #' . $recId . ' ব্যর্থ হওয়ায় ভাউচার রিফান্ড।',
                        referenceType: 'recharge',
                        referenceId: $recId,
                        metadata: [
                            'trxid' => $trxid,
                            'api_result' => 'failed',
                        ]
                    );
                }
                DB::commit();
            } catch (\Throwable $e) {
                DB::rollBack();
            }
        }

        return redirect()->route('recharge.show', $recId)->with($result ? 'success' : 'error', $message);
    }

    /**
     * 🔁 Drive Pack স্ট্যাটাস রিফ্রেশ:
     * SUCCESS ➜ ইউজার পাবে: provider_commission - (provider_commission * 2%)
     * FAILED  ➜ রিফান্ড (যদি ডেবিটেড হয়ে থাকে এবং এখনও রিফান্ড না হয়ে থাকে)
     */
    public function refreshStatus($id, SuccessTopupClient $st)
    {
        $rec = DB::table('recharges')->where('id',$id)->first();
        abort_if(!$rec, 404);
        abort_if($rec->user_id !== Auth::id(), 403);
        abort_if((int) ($rec->is_drive ?? 0) !== 1, 404);
        if (empty($rec->trxid)) {
            return back()->with('error', 'ট্রানজেকশন আইডি পাওয়া যায়নি।');
        }

        $res = $st->status($rec->trxid);
        if ($res->failed()) {
            return back()->with('error','স্ট্যাটাস আনতে সমস্যা (HTTP '.$res->status().')');
        }

        $body      = $res->json();
        $apiStatus = (string)($body['status'] ?? 'Pending'); // Success|Pending|Failed
        $map       = ['Success'=>'success','Pending'=>'pending','Failed'=>'failed'];
        $local     = $map[$apiStatus] ?? 'pending';

        DB::beginTransaction();
        try {
            $row = DB::table('recharges')->lockForUpdate()->where('id',$id)->first();
            if (!$row) { DB::rollBack(); return back()->with('error','রেকর্ড নেই'); }

            // লোকাল আপডেট
            DB::table('recharges')->where('id',$id)->update([
                'status'      => $local,
                'api_status'  => $apiStatus,
                'api_response'=> json_encode($body),
                'updated_at'  => now(),
            ]);

            // ✅ SUCCESS → ইউজার কমিশন = provider_commission - (provider_commission * 2%)
            if ($local === 'success' && !$row->commissioned) {

                if ((int)$row->is_drive === 1) {
                    $meta = json_decode($row->meta ?? '{}', true) ?: [];
                    $providerCommission = (float)($meta['provider_commission'] ?? 0);

                    // ⚠️ ইউজারকে কোথাও জানানো হবে না—শুধু অভ্যন্তরীণ হিসাব
                    $twoPctOnCommission = round($providerCommission * 0.02, 2);
                    $creditToUser       = max(0, round($providerCommission - $twoPctOnCommission, 2));

                    if ($creditToUser > 0) {
                        DB::update("UPDATE users SET `balance` = `balance` + ? WHERE id = ?", [$creditToUser, $row->user_id]);

                        DB::table('recharges')->where('id',$id)->update([
                            'commissioned' => 1,
                            'commission'   => $creditToUser, // credited amount
                            'updated_at'   => now(),
                        ]);

                        BalanceLog::create([
                            'user_id' => $row->user_id,
                            'amount'  => $creditToUser,
                        ]);

                        // ✅ ইউজার-ফেসিং মেসেজে ২% বা চার্জের কথা নেই
                        $creditFormatted = number_format((float)$creditToUser, 2, '.', '');
                        IncomeHistory::create([
                            'user_id'     => $row->user_id,
                            'source'      => 'drive_provider_commission',
                            'amount'      => $creditToUser,
                            'description' => 'অভিনন্দন! আপনি ড্রাইভ প্যাক থেকে '.$creditFormatted.' টাকা কমিশন পেয়েছেন।',
                        ]);
                    } else {
                        DB::table('recharges')->where('id',$id)->update([
                            'commissioned' => 1,
                            'commission'   => 0,
                            'updated_at'   => now(),
                        ]);
                    }

                } else {
                    // সেফটি-নেট (ড্রাইভ নয়) — এখানে সাধারণ রিচার্জ লজিক থাকলে প্রয়োজনে রাখুন/না-ও লাগতে পারে
                    $commission = round(((float)$row->amount) * 0.02, 2);
                    if ($commission > 0) {
                        DB::update("UPDATE users SET `balance` = `balance` + ? WHERE id = ?", [$commission, $row->user_id]);

                        DB::table('recharges')->where('id',$id)->update([
                            'commissioned' => 1,
                            'commission'   => $commission,
                            'updated_at'   => now(),
                        ]);

                        BalanceLog::create([
                            'user_id' => $row->user_id,
                            'amount'  => $commission,
                        ]);

                        $commissionFormatted = number_format((float)$commission, 2, '.', '');
                        IncomeHistory::create([
                            'user_id'     => $row->user_id,
                            'source'      => 'recharge_commission',
                            'amount'      => $commission,
                            'description' => 'অভিনন্দন! আপনি রিচার্জ থেকে '.$commissionFormatted.' টাকা কমিশন পেয়েছেন।',
                        ]);
                    } else {
                        DB::table('recharges')->where('id',$id)->update([
                            'commissioned' => 1,
                            'commission'   => 0,
                            'updated_at'   => now(),
                        ]);
                    }
                }
            }

            // ❌ FAILED → রিফান্ড
            if ($local === 'failed' && $row->debited && !$row->refunded) {
                $lockedUser = DB::table('users')->where('id', $row->user_id)->lockForUpdate()->first(['id', 'voucher_balance']);
                $beforeVoucher = (float) ($lockedUser->voucher_balance ?? 0);
                $refundAmount = (float) $row->amount;
                $afterVoucher = $beforeVoucher + $refundAmount;

                DB::table('users')->where('id', $row->user_id)->update(['voucher_balance' => $afterVoucher]);

                DB::table('recharges')->where('id',$id)->update([
                    'refunded'  => 1,
                    'updated_at'=> now(),
                ]);

                VoucherTransactionService::record(
                    userId: (int) $row->user_id,
                    direction: 'credit',
                    amount: $refundAmount,
                    before: $beforeVoucher,
                    after: $afterVoucher,
                    source: 'drive_pack_refund',
                    description: 'ড্রাইভ প্যাক রিচার্জ #' . $id . ' ফেইল হওয়ায় ভাউচার রিফান্ড।',
                    referenceType: 'recharge',
                    referenceId: $id,
                    metadata: [
                        'trxid' => $row->trxid,
                        'api_status' => $apiStatus,
                    ]
                );
            }

            DB::commit();
        } catch (\Throwable $e) {
            DB::rollBack();
            return back()->with('error','আপডেটের সময় সমস্যা: '.$e->getMessage());
        }

        return back()->with('success','স্ট্যাটাস: '.$apiStatus);
    }
}
