<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;

class SalesMaster extends BaseModel
{
    use HasFactory;

    protected $guarded = [];
    protected $appends = ['previous_due', 'current_payment'];

    protected $casts = [
        'pos_table_parcel_json' => 'array',
    ];


    protected static function boot()
    {
        parent::boot(); // always call the parent boot

        static::addGlobalScope('typeScope', function ($builder) {

            if (auth()->check() && auth()->user()->shop_id != null) {
                $shopId = auth()->user()->shop_id;

                $builder->Where(function ($query) use ($shopId) {
                    $query->where('sales_masters.transition_location_id', $shopId)
                        ->orWhere('sales_masters.location_id', $shopId);
                });
            }
        });

        static::creating(function ($model) {
            if (auth()->check()) {
                $user = auth()->user();
                $model->transition_location_id = $user->shop_id;
                $model->transition_create_by = $user->id;
            }
        });

        static::updating(function ($model) {
            if (auth()->check()) {
                $model->transition_update_by = auth()->id(); // use user ID here
            }
        });
    }

    public function details()
    {
        return $this->hasMany(SalesDetails::class, 'sales_masters_id', 'id')->with('product', 'arribute', 'WareHouse');
    }

    public function User()
    {
        return $this->hasOne(User::class, 'id', 'user_id');
    }

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

    public function customer()
    {
        return $this->hasOne(Client::class, 'id', 'client_id');
    }
    public function salesPerson()
    {
        return $this->hasOne(SalesPerson::class, 'id', 'sales_person_id');
    }

    public function bank()
    {
        return $this->hasOne(Bank::class, 'id', 'bank_id');
    }

    public function mobile()
    {
        return $this->hasOne(MobileBanking::class, 'id', 'mobilebank_id');
    }

    public function salesList()
    {
        return $this->hasMany(SalesDetails::class, 'sales_masters_id', 'id')->select('sales_masters_id', 'attribute_id', 'product_id')->selectRaw('sum(qty) as qty , sum(price) as price , SUM(after_discount) discount,sum(total) as total,sum(buy_price) as buy_price')->groupby('attribute_id', 'sales_masters_id', 'product_id','buy_price')->with('product', 'WareHouse', 'arribute')->with('salesMaster');
    }

    public function supplier()
    {
        return $this->hasOne(Supplier::class, 'id', 'supplier_id');
    }

    public function salesReturn()
    {
        return $this->hasMany(SalesReturnMaster::class, 'sales_invoice_no', 'id')
            ->leftJoin('sales_return_details', 'sales_return_masters.id', '=', 'sales_return_details.sales_return_master_id')
            ->selectRaw('sales_return_masters.sales_invoice_no, SUM(sales_return_details.return_qty) as total_qty,sales_return_details.product_id,sales_return_details.attribute_id')
            ->groupBy('sales_return_masters.sales_invoice_no', 'sales_return_details.product_id', 'sales_return_details.attribute_id');
    }

    /** Exchange return linked to this sale (when this invoice was created from an exchange) */
    public function exchangeReturn()
    {
        return $this->hasOne(SalesReturnMaster::class, 'exchange_id', 'id')
            ->withoutGlobalScope('typeScope')
            ->with(['details' => fn ($q) => $q->with('product', 'attribute')]);
    }


    public function getPreviousDueAttribute()
    {
        $customerId = $this->client_id;

        $opening = DB::table('customer_opening_details as cod')
            ->join('customer_openings as co', 'cod.customer_opening_id', '=', 'co.id')
            ->where('co.client_id', $customerId)
            ->sum('cod.opening_balance');

        $sales = DB::table('sales_masters')
            ->where('client_id', $customerId)
            ->sum('grand_total');

        $returns = DB::table('sales_return_masters as srm')
            ->join('sales_return_details as srd', 'srd.sales_return_master_id', '=', 'srm.id')
            ->where('srm.customer_id', $customerId)
            ->sum('srd.total');

        $payments = DB::table('customer_payment_collections')
            ->where('customer_id', $customerId)
            ->sum('payment');

        return $opening + $sales - $returns - $payments;
    }

    public function getCurrentPaymentAttribute()
    {

        return DB::table('customer_payment_collections')
            ->where('invoice_id', $this->id)
            ->sum('payment');
    }


    public function customerPayment()
    {
        return $this->hasMany(CustomerPaymentCollection::class, 'invoice_id', 'id');
    }



    public function transitionLocation()
    {
        return $this->belongsTo(SalesPerson::class, 'sales_person_id', 'id');
    }
}
