<?php

namespace App\Services;

use Carbon\Carbon;
use App\Models\Pop;
use App\Models\Client;
use App\Models\Balance;
use App\Models\Packages;
use App\Models\SubPackage;
use Illuminate\Http\Request;
use App\Services\ExpireCheck;
use App\Models\CustomerAccount;
use App\Services\ClientServices;
use App\Services\PriceCalculate;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use App\Models\ReselleBalanceLogReport;
use App\Models\SubResellerBalanceLogReport;
use App\Http\Controllers\BillGenerateController;
use App\Http\Controllers\SessionRefreshController;

class BillingCycleChange
{

  protected $billCycleChangeIncomeHead = 3;

  public function billingCycleChange($pop, $user, $newBillingDate,$uniqueString)
  {

    $exp = Carbon::parse($user->expire_date);
    $currentBillingDate = $user->billing_cycle;



    if (checkSettings('expire_billing_change_today_from_billing_date') == 'enable' && $exp < today()) {

      $currentBillingDate = today()->day;
      if ($currentBillingDate < $newBillingDate) {

        $total_day = ($newBillingDate - $currentBillingDate) + 1;
        $new_expire = today()->addDay($total_day - 1);

      } else {

        $date = date($newBillingDate . '-' . today()->month . '-' . today()->year);
        $new_expire = Carbon::parse($date)->addMonth();
        $total_day = today()->diffInDays($new_expire) + 1;

      }
    } else {

        if (date('Y') == $exp->year) {
            if ($currentBillingDate < $newBillingDate) {

                $total_day = $newBillingDate - $currentBillingDate;
                $new_expire = $exp->addDay($total_day);
            } else {

                $date = date($newBillingDate . '-' . $exp->month . '-' . $exp->year);
                $new_expire = Carbon::parse($date)->addMonth();

                $total_day = $exp->diffInDays($new_expire);
            }
        } elseif (date('Y') > $exp->year) {

            $date = date($newBillingDate . '-' . $exp->month . '-' . $exp->year);
            $new_expire = Carbon::parse($date)->addMonth();

            $total_day = $exp->diffInDays($new_expire);
        } else {

            if (date('Y') + 1 == $exp->year) {

                if ($currentBillingDate < $newBillingDate) {

                    $total_day = $newBillingDate - $currentBillingDate;
                    $new_expire = $exp->addDay($total_day);
                } else {

                    $date = date($newBillingDate . '-' . $exp->month . '-' . $exp->year);
                    $new_expire = Carbon::parse($date)->addMonth();

                    $total_day = $exp->diffInDays($new_expire);
                }

            } else {
                $date = date($newBillingDate . '-' . $exp->month . '-' . $exp->year);
                $new_expire = Carbon::parse($date)->addMonth();

                $total_day = $exp->diffInDays($new_expire);
            }
        }
    }

    // d2d extend after days for billing cycle change
    // $extra_day_for_day_day = (isset(siteinfo()->d2dactiveday) ? siteinfo()->d2dactiveday : 0);

    // if($extra_day_for_day_day > 0){
    //   if (Carbon::parse($user->expire_date)->addDay($extra_day_for_day_day) < today() ) {
    //     $currentBillingDate = today()->day;

    //     if ($currentBillingDate <= $newBillingDate) {
    //       $total_day = $newBillingDate - $currentBillingDate;
    //       $new_expire = today()->addDay($total_day);
    //       $total_day = $total_day + 1;
    //     } else {

    //       $date = date($newBillingDate . '-' . today()->month . '-' . today()->year);
    //       $new_expire = Carbon::parse($date)->addMonth();
    //       $total_day = today()->diffInDays($new_expire);
    //       $total_day = $total_day + 1;
    //     }
    //   }

    // }


    if (date('m') == '02' && checkSettings('february_add_2_days') == 'enable' && $new_expire > today()->lastOfMonth()) {
      $total_day = $total_day + 2;
    }




    $days_in_month = Carbon::parse($new_expire)->daysInMonth;

    $reseller_cost = PriceCalculate::calculate($days_in_month, $user->packages->package_rate, $total_day);

    $sub_reseller_cost = $user->pop->subreseller == 'yes' ? PriceCalculate::calculate($days_in_month, $user->subpack->rate, $total_day) : 0;





    if ($pop->bill_generate == "yes") {
        // dd($reseller_cost, "check");
      if ($user->customerAccount->dueAmount < 0 &&  abs($user->customerAccount->dueAmount) >= $reseller_cost) {

        $status = $this->customer_bill_cycle_change_for_advanced_balance($user, $reseller_cost, $sub_reseller_cost, $total_day, $new_expire, $newBillingDate,$uniqueString);

      } elseif ($user->customerAccount->dueAmount < 0 && abs($user->customerAccount->dueAmount) < $reseller_cost) {

        $status = $this->customer_bill_cycle_change_for_advanced_balance_and_extra_amount($user, $reseller_cost, $sub_reseller_cost, $total_day, $new_expire, $newBillingDate,$uniqueString);
      } else {

        $status = $this->reseller_billing_cycle_change_process($user, $total_day, $new_expire, $newBillingDate, $reseller_cost,$uniqueString);
      }
    } else {

        // dd($reseller_cost, "check df");
      $status = $this->reseller_billing_cycle_change_process($user, $total_day, $new_expire, $newBillingDate, $reseller_cost,$uniqueString);
    }


    $client = Client::with('pop')->find($user->id);
    if(globalPermission('RadiusExpiration')){

        (new ExpirationService())->handleExpiration($client->userid,$exp,$client->payment_dadeline,$client->pop->experity_check);
    }



    return $status;
  }

  public function customer_bill_cycle_change_for_advanced_balance($user, $reseller_cost, $sub_reseller_cost, $total_day, $new_expire, $newBillingDate,$uniqueString)
  {

    $action = "Billing Cycle Changed. For Package: " . $user->packages->package_name .
      " . Expire: " . $new_expire .
      " Total " . $total_day .
      " days cost BDT " . $reseller_cost .
      ". Cusomer has advanced balance so not deducted.";

    $bill_for_billing_cycle_change = (new CustomerAccountService)->customer_account_update($user, $reseller_cost, 'Customer Billing Cycle Change', 'billing_cycle_change');

    $this->update_reseller_balance_and_log_report($user, $new_expire, $action, 0, $newBillingDate,$uniqueString,$bill_for_billing_cycle_change->id);

    if ($user->pop->subreseller == 'yes') {
      $this->update_sub_reseller_balance_and_log_report($user, $action, 0);
    }

  }



  public function customer_bill_cycle_change_for_advanced_balance_and_extra_amount($user, $reseller_cost, $sub_reseller_cost, $total_day, $new_expire, $newBillingDate,$uniqueString)
  {

    $customer_advanced_balance = $user->customerAccount->dueAmount < 0 ? abs($user->customerAccount->dueAmount) : 0;

    $reseller_adjustable_amount = abs($reseller_cost == 0 ? 0 : $customer_advanced_balance - $reseller_cost);

    if ($reseller_adjustable_amount > floatval(Balance::getBalance('reseller', $user->pop->reseller_id))) { //reseller balance checking
      return 'reseller_balance_error';
    }

    $action = "Billing Cycle Changed. From Package: " . $user->packages->package_name .
      " . Expire: " . $new_expire .
      " Total  " . $total_day .
      " days cost BDT " . $reseller_cost .
      ". Cusomer advanced balance: " . abs($user->customerAccount->dueAmount) .
      ".Reseller Deductable Amount: " . $reseller_adjustable_amount;

    $bill_for_billing_cycle_change = (new CustomerAccountService)->customer_account_update($user, $reseller_cost, 'Customer Billing Cycle Change', 'billing_cycle_change', $reseller_adjustable_amount, $this->billCycleChangeIncomeHead);


    $this->update_reseller_balance_and_log_report($user, $new_expire, $action, $reseller_adjustable_amount, $newBillingDate, $uniqueString,$bill_for_billing_cycle_change->id);

    if ($user->pop->subreseller == 'yes') {

      $sub_reseller_adjustable_amount = abs($sub_reseller_cost == 0 ? 0 : $customer_advanced_balance - $sub_reseller_cost);

      $action = "Billing Cycle Changed. From Package: " . $user->subpack->package_name .
        " . Expire: " . $new_expire .
        " Total  " . $total_day .
        " days cost BDT " . $sub_reseller_cost .
        ". Cusomer advanced balance: " . abs($user->customerAccount->dueAmount) .
        ".Reseller Deductable Amount: " . $sub_reseller_adjustable_amount;

      $this->update_sub_reseller_balance_and_log_report($user, $action, $sub_reseller_adjustable_amount,$reseller_adjustable_amount);
    }

  }


  public function reseller_billing_cycle_change_process($user, $total_day, $new_expire, $newBillingDate, $reseller_cost,$uniqueString)
  {

    $action = "Billing Cycle Changed. For Package: " . $user->packages->package_name .
      " . Expire Date: " . $new_expire .
      " Total " . $total_day .
      " days cost BDT " . $reseller_cost;

    $resellerBalance =   Balance::getBalance('reseller', $user->pop->reseller_id);

    if ($resellerBalance >= $reseller_cost) {

      if ($user->pop->subreseller == 'no' && $user->pop->bill_generate == 'yes') {

        $bill = (new CustomerAccountService)->customer_account_update($user, $reseller_cost, 'Customer Billing Cycle Change', 'billing_cycle_change', $reseller_cost, $this->billCycleChangeIncomeHead);
      } elseif ($user->pop->subreseller == 'yes') {
        // dd("not", $reseller_cost);
        $status = $this->sub_reseller_billing_cycle_change_process($user, $total_day, $new_expire , $reseller_cost);
      }
      if(isset($bill)){

          $this->update_reseller_balance_and_log_report($user, $new_expire, $action, $reseller_cost, $newBillingDate,$uniqueString, $bill->id);
      }else{
          $this->update_reseller_balance_and_log_report($user, $new_expire, $action, $reseller_cost, $newBillingDate,$uniqueString);
      }

      return isset($status) ? $status : 'success';
    } else {
      return 'error';
    }
  }

  public function update_sub_reseller_balance_and_log_report($user, $action, $sub_reseller_cost, $reseller_cost = 0)
  {

    SubResellerBalanceLogReport::create(
      [
        'reseller_id'       => $user->pop->reseller_id,
        'sub_reseller_id'   => $user->pop->id,
        'client_id'         => $user->id,
        'action'            => $action,
        'amount'            => $sub_reseller_cost,
        'remarks'           => 'Created BY ' . Auth::user()->email,
        'reseller_cost' => $reseller_cost,
        'commission_amount' => getCommissionForSubResellerRecharge($user->id,$sub_reseller_cost),
      ]
    );

    if (isset($user->subpack) && $user->subpack->commission > 0) {
      (new CommissionService())->subreseller_commission($sub_reseller_cost, $action, $user->pop->id, $user->subpack->commission, $user->subpack->rate, $user->id);
    }

    if ($sub_reseller_cost > 0) {
      Balance::balanceDeductForUserRecharge('pop', $user->pop->id, $sub_reseller_cost);
    }
  }


  public function update_reseller_balance_and_log_report($user, $new_expire_date, $action, $reseller_cost, $newBillingDate, $uniqueString, $bill_id =null)
  {

    Client::where('id', $user->id)
      ->update([
        'expire_date'   => $new_expire_date,
        'billing_cycle' => $newBillingDate
      ]);

    if ($user->packages->commission > 0) {
      (new CommissionService())->reseller_commission($reseller_cost, $action, $user->pop->reseller_id, $user->packages->commission, $user->packages->package_rate, $user->id,'bill',$bill_id);
    }

    if ($reseller_cost > 0) {
      Balance::balanceDeductForUserRecharge('reseller', $user->pop->reseller_id, $reseller_cost);
    }
    $cur_balance = Balance::whereType('reseller')->whereType_id($user->pop->reseller_id)->first('amount');

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

    ReselleBalanceLogReport::create([
        'reseller_id' => $user->pop->reseller_id,
        'client_id'   => $user->id,
        'action'      => $action,
        'amount'      => $reseller_cost,
        'remarks'     => ' BY ' . Auth::user()->email,
        'reseller_balance'     => $cur_balance->amount,
        'uniqueId'      => $uniqueString.$user->id,
        'pop_id'        => $user->pop_id,
        'commission_amount' => getCommissionForResellerRecharge($user->id,$reseller_cost),
        'reseller_commission_percentage' => $pop->reseller->commission_percentage,
        'pop_commission_percentage' => $pop->commission_percentage,
    ]);
  }



  public function sub_reseller_billing_cycle_change_process($user, $total_day, $new_expire, $resellerCost)
  {

    $reseller_id = $user->pop->reseller_id;

    $SR_package = SubPackage::where('id', $user->sub_package_id)->first();
    $days_in_month = Carbon::parse($new_expire)->daysInMonth;

    $sub_reseller_cost = PriceCalculate::calculate($days_in_month, $SR_package->rate, $total_day);

    $SubResellerAction = "Billing Cycle Changed. For Package: " . $SR_package->name .
      " . Expire Date: " . $new_expire .
      " Total " . $total_day .
      " days cost BDT " . $sub_reseller_cost;

    $popBalance  = Balance::getBalance('pop', $user->pop->id);

    if ($sub_reseller_cost > $popBalance) {
      return 'balance_error';
    }

    $this->update_sub_reseller_balance_and_log_report($user, $SubResellerAction, $sub_reseller_cost,$resellerCost);

    if ($user->pop->bill_generate == 'yes') {
      (new CustomerAccountService)->customer_account_update($user, $sub_reseller_cost, 'Customer Billing Cycle Change', 'billing_cycle_change', $sub_reseller_cost, $this->billCycleChangeIncomeHead);
    }
  }
}
