<?php

namespace App\Models;

use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use App\Models\ResellerRechargeReport;
use Illuminate\Database\Eloquent\Model;
use App\Models\SubResellerRechargeReport;
use App\Models\SubResellerBalanceLogReport;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\Log;

class Balance extends Model
{
    use HasFactory;

    protected $fillable = [
        'type',
        'type_id',
        'amount'
    ];





    public static function ResellerRechargeLog($type, $type_id, $amount, $remarks, $paid_amount = 0, $user_id = null, $payment_type = null, $payment_gateway = null, $payment_gateway_transaction_id = null, $txn_id = null)
    {

        $reseller = Reseller::find($type_id);
        if ($user_id == null) {
            $user_id = auth()->user()->id;
        }

        $balance = Balance::where('type', $type)
            ->where('type_id', $type_id)
            ->first();


        if ($reseller->reseller_type == 'other') {

            $income =   Income::create([
                'name' => 'Reseller Recharge',
                'date' => now(),
                'amount' => $paid_amount,
                'description' => 'Reseller Recharge Name: ' . $reseller->name . ' ID: ' . $reseller->id,
                'incomeHead' => 10
            ]);
        }

        $id_redcharge = ResellerRechargeReport::create([
            'reseller_id'                       => $type_id,
            'amount'                            => $amount,
            'after_recharge_balance'            => $balance->amount,
            'remarks'                           => $remarks ?? '',
            'user_id'                           => $user_id,
            'income_id'                         => $income->id ?? null,
            'paid_amount'                       => $paid_amount,
            'payment_type'                      => $payment_type,
            'payment_gateway'                   => $payment_gateway,
            'payment_gateway_transaction_id'    => $payment_gateway_transaction_id,
            'txn_id'                            => $txn_id,
        ]);

        // Check if the record was successfully created and log the result
        if ($id_redcharge && $id_redcharge->id) {
            Log::info("Payment completed successfully. Recharge ID: " . $id_redcharge->id);
        } else {
            Log::error("Payment creation failed. Recharge ID not found.");
        }

        return true;
    }


    static function SubResellerRechargeLog($type, $type_id, $amount, $remarks, $user_id = null, $payment_type = null, $payment_gateway = null, $payment_gateway_transaction_id = null, $txn_id = null)
    {
        if ($user_id == null) {
            $user_id = auth()->user()->id;
        }
        $balance = Balance::where('type', $type)
            ->where('type_id', $type_id)
            ->first();



        SubResellerRechargeReport::create([
            'pop_id'                            => $type_id,
            'amount'                            => $amount,
            'after_recharge_balance'            => $balance->amount,
            'remarks'                           => $remarks ?? '',
            'user_id'                           => $user_id,
            'payment_type'                      => $payment_type,
            'payment_gateway'                   => $payment_gateway,
            'payment_gateway_transaction_id'    => $payment_gateway_transaction_id,
            'txn_id'                            => $txn_id,
        ]);

        return true;
    }

    public static function balanceDeductForUserRecharge($type, $type_id, $amount)
    {
        return  Balance::whereType($type)
            ->whereType_id($type_id)
            ->decrement('amount', $amount);
    }

    public static function balanceUpdate($type, $type_id, $amount, $remarks = '', $paid_amount = 0, $user_id = null, $payment_type = null, $payment_gateway = null, $payment_gateway_transaction_id = null, $txn_id = null)
    {

        $paid_amount = round($paid_amount);
        $amount = round($amount);
        $user_id = $user_id == null ? auth()->user()->id : $user_id;

        // Use lockForUpdate to prevent race conditions
        $balance = Balance::where('type', $type)
            ->where('type_id', $type_id)
            ->lockForUpdate()
            ->first();

        if ($balance == null) {
            // Use firstOrCreate to handle race condition where balance might be created between check and creation
            Balance::firstOrCreate(
                [
                    'type' => $type,
                    'type_id' => $type_id,
                ],
                [
                    'amount' => $amount,
                    'remarks' => $remarks
                ]
            );

            if ($type == 'reseller') {
                Balance::ResellerRechargeLog($type, $type_id, $amount, $remarks, $paid_amount, $user_id, $payment_type, $payment_gateway, $payment_gateway_transaction_id, $txn_id);
            } elseif ($type == 'pop') {
                Balance::SubResellerRechargeLog($type, $type_id, $amount, $remarks, $user_id, $payment_type, $payment_gateway, $payment_gateway_transaction_id, $txn_id);
            }
            return  'success';
        } else {

            // Use increment for atomic operation instead of separate read and update
            $balance->increment('amount', $amount);

            if ($type == 'reseller') {
                Balance::ResellerRechargeLog($type, $type_id, $amount, $remarks, $paid_amount, $user_id, $payment_type, $payment_gateway, $payment_gateway_transaction_id, $txn_id);
            } elseif ($type == 'pop') {
                Balance::SubResellerRechargeLog($type, $type_id, $amount, $remarks, $user_id, $payment_type, $payment_gateway, $payment_gateway_transaction_id, $txn_id);
            }
            return 'success';
        }
    }

    static function deduct_balance_on_payment_for_pop($client_id, $pop, $paymentAmount, $cac, $payment_id)
    {

        $created_by = isset(Auth::user()->email) ?? 'Online Payment';

        $previously_deduct_amount = SubResellerBalanceLogReport::where('client_id', $client_id)->sum('amount');

        $didactableAmount = ($cac->totalBillAmount - $cac->totalDiscount) - $previously_deduct_amount;

        if ($didactableAmount > 0) {

            $dif = $cac->dueAmount - $didactableAmount;
            // echo '<br>'.$dif;
            if ($dif < 0) {

                // echo 'dif true'.$dif;
                // dd();
                Balance::balanceDeductForUserRecharge('pop', $pop->id, abs($dif));

                SubResellerBalanceLogReport::create(
                    [
                        'reseller_id'       => $pop->reseller_id,
                        'client_id'         => $client_id,
                        'action'            => 'Bill payment from payment option payment id: ' . $payment_id,
                        'amount'            => abs($dif),
                        'sub_reseller_id'   => $pop->id,
                        'remarks'           => 'Created BY ' . $created_by,
                        'commission_amount' => getCommissionForSubResellerRecharge($client_id, abs($dif)),
                    ]
                );

                Billpayment::where('id', $payment_id)
                    ->update([
                        'pop_balance_deduct' => abs($dif)
                    ]);
            } else {

                SubResellerBalanceLogReport::create(
                    [
                        'reseller_id'       => $pop->reseller_id,
                        'client_id'         => $client_id,
                        'action'            => 'Bill payment from payment option payment id: ' . $payment_id,
                        'amount'            => abs($dif),
                        'sub_reseller_id'   => $pop->id,
                        'remarks'           => 'Created BY ' . $created_by,
                        'commission_amount' => getCommissionForSubResellerRecharge($client_id, abs($dif)),
                    ]
                );
            }
        } else {
            // dd('false true');

            Balance::balanceDeductForUserRecharge('pop', $pop->id, $paymentAmount);

            SubResellerBalanceLogReport::create(
                [
                    'reseller_id'       => $pop->reseller_id,
                    'client_id'         => $client_id,
                    'action'            => 'Bill payment from payment option payment id: ' . $payment_id,
                    'amount'            => abs($paymentAmount),
                    'sub_reseller_id'   => $pop->id,
                    'remarks'           => 'Created BY ' . $created_by,
                    'commission_amount' => getCommissionForSubResellerRecharge($client_id, abs($paymentAmount)),
                ]
            );

            Billpayment::where('id', $payment_id)
                ->update([
                    'pop_balance_deduct' => $paymentAmount
                ]);
        }

        //    / dd($previously_deduct_amount);
    }

    static function deductBalanceOnPaymentFromReseller($client_id, $reseller_id, $paymentAmount, $cac, $payment_id, $pop_id)
    {
        $created_by = isset(Auth::user()->email) ?? 'Online Payment';

        $previously_deduct_amount = ReselleBalanceLogReport::where('client_id', $client_id)->sum('amount');

        // dd($previously_deduct_amount);


        $didactableAmount = ($cac->totalBillAmount - $cac->totalDiscount)  - $previously_deduct_amount;

        if ($didactableAmount > 0) {

            $dif = $cac->dueAmount - $didactableAmount;

            if ($dif < 0) {

                Balance::balanceDeductForUserRecharge('reseller', $reseller_id, abs($dif));
                $pop = Pop::with('reseller')->find($pop_id);

                ReselleBalanceLogReport::create(
                    [
                        'reseller_id' => $reseller_id,
                        'client_id'   => $client_id,
                        'action'      => 'Bill payment from payment option payment id: ' . $payment_id,
                        'amount'      => abs($dif),
                        'remarks'     => 'Created BY ' . $created_by,
                        'uniqueId'     => createUUID(),
                        'pop_id'       => $pop_id,
                        'commission_amount' => getCommissionForResellerRecharge($client_id, abs($dif)),
                        'reseller_commission_percentage' => $pop->reseller->commission_percentage,
                        'pop_commission_percentage' => $pop->commission_percentage,
                    ]
                );

                Billpayment::where('id', $payment_id)
                    ->update([
                        'reseller_balance_deduct' => abs($dif)
                    ]);
            } else {
                $pop = Pop::with('reseller')->find($pop_id);
                ReselleBalanceLogReport::create(
                    [
                        'reseller_id' => $reseller_id,
                        'client_id'   => $client_id,
                        'action'      => 'Bill payment from payment option payment id: ' . $payment_id,
                        'amount'      => 0,
                        'remarks'     => 'Created BY ' . $created_by,
                        'uniqueId'     => createUUID(),
                        'pop_id'       => $pop_id,
                        'commission_amount' => 0,
                        'reseller_commission_percentage' => $pop->reseller->commission_percentage,
                        'pop_commission_percentage' => $pop->commission_percentage,
                    ]
                );
            }
        } else {
            // dd('false true');

            Balance::balanceDeductForUserRecharge('reseller', $reseller_id, $paymentAmount);

            $pop = Pop::with('reseller')->find($pop_id);

            ReselleBalanceLogReport::create(
                [
                    'reseller_id' => $reseller_id,
                    'client_id'   => $client_id,
                    'action'      => 'Bill payment from payment option payment id: ' . $payment_id,
                    'amount'      => $paymentAmount,
                    'remarks'     => 'Created BY ' . $created_by,
                    'uniqueId'     => createUUID(),
                    'pop_id'       => $pop_id,
                    'commission_amount' => getCommissionForResellerRecharge($client_id, $paymentAmount),
                    'reseller_commission_percentage' => $pop->reseller->commission_percentage,
                    'pop_commission_percentage' => $pop->commission_percentage,
                ]
            );

            Billpayment::where('id', $payment_id)
                ->update([
                    'reseller_balance_deduct' => $paymentAmount
                ]);
        }
        // dd();


    }


    static function getBalance($type, $id)
    {
        $balance = Balance::whereType($type)
            ->whereType_id($id)
            ->first();

        if ($balance !== null) {
            return $balance->amount;
        } else {
            return 0;
        }
    }
}
