<?php

namespace App\Models;

use App\Classes\Accounting\Accounting;
use Carbon\Carbon;
use App\Models\Packages;
use App\Models\BillGenerate;
use App\Models\CustomerAccount;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Serializable;

class Client extends Model
{
    use HasFactory, SoftDeletes;

    protected $guarded = ['id'];

    protected $attributes = [
        'client_approval' => 'pending',
    ];





    public function reseller()
    {
        return $this->belongsTo(Reseller::class, 'reseller_id');
    }

    public function resellerList()
    {
        return $this->hasMany(Pop::class, 'pop_id');
    }

    public function customerAccount()
    {
        return $this->hasOne(CustomerAccount::class, 'client_id', 'id');
    }
    public function pops()
    {
        return $this->belongsTo(Pop::class, 'pop_id', 'id');
    }

    public function nas()
    {
        return $this->belongsTo(Nas::class, 'nas_id');
    }

    public function pop()
    {
        return $this->belongsTo(Pop::class, 'pop_id');
    }

    public function popbillable()
    {
        return $this->belongsTo(Pop::class, 'pop_id')->where('bill_generate', 'yes');
    }


    public function packages()
    {
        return $this->hasOne(Packages::class, 'id', 'package_id');
    }
    public function user()
    {
        return $this->belongsTo(User::class, 'created_by')->withTrashed();
    }

    public function clientsinfo()
    {
        return $this->hasOne(Clientsinfo::class, 'client_id', 'id');
    }

    public function subpack()
    {
        return $this->hasOne(SubPackage::class, 'id', 'sub_package_id');
    }

    public function paymentBill()
    {
        return $this->hasMany(Billpayment::class, 'client_id', 'id');
    }


    public function generatedBill()
    {
        return $this->hasMany(BillGenerate::class, 'client_id', 'id');
    }

    public function balanceAdjustment()
    {
        return $this->hasMany(BalanceAdjustment::class, 'client_id', 'id');
    }
    public function customerToken()
    {
        return $this->hasOne(Token::class, 'clientId', 'id');
    }

    public function totalGeneratedBill()
    {
        return $this->generatedBill()->sum('bill_amount');
    }
    public function generatedBillNow()
    {
        return $this->hasMany(BillGenerate::class, 'client_id', 'id')
            ->whereBetween('created_at', [now()->firstOfMonth(), now()->lastOfMonth()->addDay()])
            ->where(function ($q) {
                $q->where('billing_type', 'monthly')
                    ->oRwhere('billing_type', 'reactive');
            });
    }



    public function generatedBillOther()
    {
        return $this->hasMany(BillGenerate::class, 'client_id', 'id')
            ->whereBetween('created_at', [now()->firstOfMonth(), now()->lastOfMonth()->addDay()])
            ->where(function ($q) {
                $q->where('billing_type', '!=', 'monthly')
                    ->where('billing_type', '!=', 'reactive');
            });
    }

    static function online($lists)
    {

        $accounting = new Accounting();

        return $accounting->totalOnlineUser();


    }

    static function list($type = 'approved', $popType = null)
    {
        $list = Client::with('clientsinfo', 'packages:id,package_name,package_rate,client_payment_amount', 'subpack:id,name,rate,client_payment_amount', 'pop:id,popname,nas_id,bill_generate,subreseller', 'customerAccount', 'pop.reseller', "pop.nas")
            ->selectRaw('id,pop_id,billing_cycle,package_id,userid,password,ip_address,expire_date,payment_dadeline,created_by,client_approval,created_at,clients_status,sub_package_id,customer_id,marketed_by,deleted_at,parmanent_discount,required_cable,ignoreMKCheck,closed_at,bandwidth_limit,up_bandwidth,down_bandwidth,isStatic,auto_deactive,customer_code,
            mac,distribution_point,connection_type,customer_type,crm_status,crm_check_date,is_free,slug,un_recharge_amount,client_payment_amount,billing_start_date,experity_check,customer_account_balance_reseller,free_day_to_create_customer,client_id')
            ->where('client_approval', $type)
            ->whereIn('pop_id', userPops()->pluck('id'));

        return $list;
    }

    static function listWithPendingAndClose()
    {
        $list = Client::withTrashed()->with('clientsinfo', 'packages:id,package_name,package_rate,client_payment_amount', 'subpack:id,name,rate,client_payment_amount', 'pop:id,popname,nas_id,bill_generate,subreseller', 'customerAccount', 'pop.reseller', "pop.nas")
            ->selectRaw('id,pop_id,billing_cycle,package_id,userid,password,ip_address,expire_date,payment_dadeline,created_by,client_approval,created_at,clients_status,sub_package_id,customer_id,marketed_by,deleted_at,parmanent_discount,required_cable,ignoreMKCheck,closed_at,bandwidth_limit,up_bandwidth,down_bandwidth,isStatic,auto_deactive,customer_code,
            mac,distribution_point,connection_type,customer_type,crm_status,crm_check_date,is_free,slug,un_recharge_amount,client_payment_amount,billing_start_date,experity_check,customer_account_balance_reseller,free_day_to_create_customer,client_id')
            ->whereIn('pop_id', userPops()->pluck('id'));

        return $list;
    }

    static function withTrashedList($type = 'approved', $popType = null)
    {
        $list = Client::withTrashed()->with('clientsinfo', 'packages:id,package_name,package_rate', 'subpack:id,name,rate', 'pop:id,popname,nas_id,bill_generate,subreseller', 'customerAccount', 'pop.reseller', "pop.nas")
            ->selectRaw('id,pop_id,billing_cycle,package_id,userid,password,ip_address,expire_date,payment_dadeline,created_by,client_approval,created_at,clients_status,sub_package_id,customer_id,marketed_by,deleted_at,parmanent_discount,required_cable,ignoreMKCheck,closed_at,bandwidth_limit,up_bandwidth,down_bandwidth,isStatic,auto_deactive,customer_code,billing_start_date')
            ->where('client_approval', $type)
            ->whereIn('pop_id', userPops()->pluck('id'));

        return $list;
    }

    static function clist($type = 'approved', $popType = null)
    {
        $list = Client::with('clientsinfo', 'packages:id,package_name,package_rate', 'subpack:id,name,rate', 'pop:id,popname,bill_generate,subreseller', 'pop.reseller')
            ->selectRaw('id,pop_id,billing_cycle,package_id,userid,password,ip_address,expire_date,payment_dadeline,created_by,client_approval,created_at,clients_status,sub_package_id,customer_id,marketed_by')
            ->where('client_approval', $type)
            ->whereIn('pop_id', userPops()->pluck('id'));
        return $list;
    }


    static function pop_ids()
    {
        $uid = auth()->user()->id;
        $pop_ids = null;

        if (auth()->user()->hasRole(['Reseller Admin', 'Reseller', 'Reseller Technician'])) {

            $reseller_ids = DB::table('reseller_user')->where('user_id', $uid)->pluck('reseller_id')->toArray();

            $pop_ids = Pop::with('reseller', 'nas')->whereIn('reseller_id', $reseller_ids)->pluck('id')->toArray();
        } elseif (auth()->user()->hasRole(['Sub Reseller', 'Sub Reseller Technician'])) {

            $pop_ids = DB::table('pop_user')->where('user_id', $uid)->pluck('pop_id')->toArray();
        }

        return $pop_ids;
    }

    static function conditionlist()
    {

        $uid = auth()->id();



        if (auth()->user()->hasRole(['Admin', 'Accounts Manager', 'Support Manager', 'Accounts Executive', 'PendingCustomerChecker'])) {

            $list = Client::where('client_approval', 'pending');
        } elseif (auth()->user()->hasRole(['Reseller Admin', 'Reseller', 'Reseller Technician'])) {

            $reseller_ids = DB::table('reseller_user')->where('user_id', $uid)->pluck('reseller_id')->toArray();

            $pop_ids = Pop::with('reseller', 'nas')->whereIn('reseller_id', $reseller_ids)->pluck('id')->toArray();

            $list = Client::whereIn('pop_id', $pop_ids)->where('client_approval', 'pending');;
        } elseif (auth()->user()->hasRole(['Sub Reseller', 'Sub Reseller Technician'])) {

            $pop_ids = DB::table('pop_user')->where('user_id', $uid)->pluck('pop_id')->toArray();
            $list = Client::whereIn('pop_id', $pop_ids)
                ->where('client_approval', 'pending');
        } elseif (!auth()->user()->hasRole(['Admin', 'Support Manager', 'Accounts Manager', 'Accounts Executive'])) {

            $list = Client::whereIn('pop_id', []);
        }

        return $list ?? '';
    }

    // all customer
    static function allCustomerlist()
    {

        $uid = auth()->id();



        if (auth()->user()->hasRole(['Admin', 'Accounts Manager', 'Support Manager', 'Accounts Executive', 'PendingCustomerChecker', 'Billing Man'])) {

            $list = array();
            $clientsaccount = DB::table('clients')
                ->get();
            $list['allCustomer']  =  $clientsaccount->count();
        } elseif (auth()->user()->hasRole(['Reseller Admin', 'Reseller', 'Reseller Technician'])) {

            $list = array();

            $reseller_ids = DB::table('reseller_user')->where('user_id', $uid)->pluck('reseller_id')->toArray();

            $pop_ids = Pop::with('reseller', 'nas')->whereIn('reseller_id', $reseller_ids)->pluck('id')->toArray();

            $data = Client::whereIn('pop_id', $pop_ids);

            $list['totalResellerUser'] = $data->count();
        } elseif (auth()->user()->hasRole(['Sub Reseller', 'Sub Reseller Technician'])) {

            $list = array();
            $pop_ids = DB::table('pop_user')->where('user_id', $uid)->pluck('pop_id')->toArray();
            $data = Client::whereIn('pop_id', $pop_ids);
            $list['allSubresellerUser'] = $data->count();
        } elseif (!auth()->user()->hasRole(['Admin', 'Support Manager', 'Accounts Manager', 'Accounts Executive'])) {

            $list = Client::whereIn('pop_id', []);
        }

        return $list;
    }


    public function clientEditLog()
    {
        return $this->hasMany(ClientEditLog::class, 'client_id', 'id')->orderBy('id', 'desc');
    }

    public function resellerBlanceLogCurrentMonth()
    {
        return $this->hasMany(ReselleBalanceLogReport::class, 'client_id', 'id')->whereBetween('created_at', [Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth()]);
    }

    public function resellerBlanceLogPreviousMonth()
    {
        return $this->hasMany(ReselleBalanceLogReport::class, 'client_id', 'id')->whereBetween('created_at', [Carbon::now()->startOfMonth()->subMonth(), Carbon::now()->endOfMonth()->subMonth()]);
    }

    public function customerAccountAdjustment()
    {
        return $this->hasMany(CustomerBalanceAdjustment::class, 'client_id', 'id');
    }

    public function adminUser()
    {
        return $this->belongsTo(User::class, 'created_by', 'id');
    }

    public function thisMonthBill()
    {
        $from = Carbon::parse(now()->startOfMonth())->format('Y-m-d 00:00:00');
        $end = Carbon::parse(now()->lastOfMonth())->format('Y-m-d 23:59:59');
        return $this->hasMany(BillGenerate::class, 'client_id', 'id')->whereBetween('created_at',[$from,$end]);
    }

    public function resellerClientBillGenerates()
    {
        return $this->hasMany(ResellerBillGenerate::class, 'client_id', 'id');
    }

    public function resellerClientBillPayments()
    {
        return $this->hasMany(ResellerBillPayment::class, 'client_id', 'id');
    }

    public function radusergroup()
    {
        return $this->hasOne(RadUserGroup::class, 'username', 'userid');
    }

    public function marketingEmployeeUser()
    {
        return $this->belongsTo(Employee::class, 'marketing_employee_id');
    }



}
