<?php

namespace App\Models;

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

class Shop extends BaseModel
{
    use HasFactory;

    public $fillable = ["title", 'icon', 'pay_type', 'price', 'vip_price', 'is_vip', 'sku', 'banners', 'describe', 'is_show', 'share_qrcode', 'nature','is_open_policy','policy_title','policy'];

    public const AGENTSTOCKTYPE = "AGENT";

    public const ZongZiId = 5;

    public const AGENTNATURE = "AGENT"; //批发商
    public const NURTURENATURE = "NURTURE"; //营养品
    public const DMANATURE = "DMA";

    protected $casts = [
        'sku' => 'array',
        'banners'=>'array',
        'nature'=>'array',
    ];

    protected function price(): Attribute
    {
        return Attribute::make(
            get: fn ($value) => number_format($value, 2,'.',''),
        );
    }

    public function scopeNature($query)
    {
        $nature = request()->nature;
        if ($nature) {
            return $query->where('nature', "like", "%{$nature}%");
        }
        return $query;
    }

    //减扣库存
    public function decrementShopStock($sku_id, $num=1, $type = null)
    {
        $num = abs($num);
        $skus = $this->sku;
        if ($type == self::AGENTSTOCKTYPE) {
            if ($skus) {
                foreach ($skus as &$sku)
                {
                    if ($sku['sku_id'] == 1 && isset($sku['stock'])) {
                        $sku['stock'] = $sku['stock'] - $num;
                        if ($sku['stock'] < 0) throw new \Exception("商品id: $this->id, sku_id：$sku_id 库存不足");
                    }
                }
                $this->update(['sku'=>$skus]);
            }
        }else {
            Log::info("库存出库 {$sku_id} {$num}");
            if ($skus) {
                foreach ($skus as &$sku)
                {
                    if ($sku['sku_id'] == $sku_id && isset($sku['stock'])) {
                        $sku['stock'] = $sku['stock'] - $num;
                        if ($sku['stock'] < 0) throw new \Exception("商品id: $this->id, sku_id：$sku_id 库存不足");
                    }
                }
                $this->update(['sku'=>$skus]);
            }
        }
    }


    //出库
    public function stockOut($admin, $order_id, $sku_id=null, $num=1, $goods_type=0, $remark=null)
    {
        DB::beginTransaction();
        //减库存
        $skus = $this->sku;
        if ($skus) {
            foreach ($skus as &$sku)
            {
                if ($sku['sku_id'] == $sku_id && isset($sku['stock'])) {
                    $before_num = $sku['stock'];
                    $sku['stock'] = $sku['stock'] - $num;
                    $after_num = $sku['stock'];
                    if ($sku['stock'] < 0)  {
                        DB::commit();
                        return ['status'=>1, 'msg'=>'商品库存不足'];
                    }

                    //出库记录
                    $map = [];
                    $map['name'] = $this->title;
                    $map['food_id'] = $this->id;
                    $map['operate_name'] = $admin->name;
                    $map['operate_mobile'] = $admin->mobile;
                    $map['user_id'] = $admin->id;
                    $map['status'] = OperateStockLog::OPERATE_STATUS_PASS;
                    $map['sku_id'] = $sku_id;
                    $map['goods_type'] = $goods_type;
                    $map['type'] = OperateStockLog::TYPE_ADMIN;
                    $map['operate_type'] = OperateStockLog::OPERATE_TYPE_OUT;
                    $map['before_num'] = $before_num;
                    $map['num'] = $num;
                    $map['after_num'] = $after_num;
                    $map['order_id'] = $order_id;
                    $map['remark'] = $remark;
                    OperateStockLog::create($map);
                }
            }
            $this->update(['sku'=>$skus]);
        }
        DB::commit();
        return ['status'=>0, 'msg'=>''];
    }

    public function incrementShopStock($sku_id, $num=1)
    {
        $skus = $this->sku;
        foreach ($skus as &$sku)
        {
            if ($sku['sku_id'] == $sku_id) {
                $stock = $sku['stock']??0;
                $sku['stock'] = $stock + $num;
            }
        }
        $this->update(['sku'=>$skus]);
    }

    public function scopeKeyword($query)
    {
        $keyword = request()->keyword;
        if ($keyword) {
            return $query->where(function($sql) use($keyword) {
                $sql->where("title", 'like', "%$keyword%");
            });
        }
        return $query;
    }

    public function scopeStatus($query)
    {
        $is_show = request()->is_show;
        if (is_numeric($is_show) ) {
            return $query->where("is_show", $is_show);
        }
        return $query;
    }

    public function scopeShow($query)
    {
        return $query->where("is_show", 1);
    }

    public function scopeNopage($query)
    {
        $nopage = request()->nopage;
        if (is_numeric($nopage) && $nopage) return $query->get();
        return $query->paginate();
    }

    public function agentOrders()
    {
        return $this->hasMany(AgentOrder::class, 'shop_id', 'id')->where('pay_status', 'PAID');
    }

    public function scopeAgent($query)
    {
        return $query->whereHas("ShopAgent");
    }

    public function scopeDma($query)
    {
        return $query->whereHas("dmaShop");
    }

    public function scopeNurture($query)
    {
        return $query->whereHas("shopNurture");
    }

    public function shopAgent()
    {
        return $this->hasOne(AgentShop::class, 'shop_id', 'id');
    }

    public function dmaShop()
    {
        return $this->hasOne(DmaShop::class, 'shop_id', 'id');
    }

    public function shopNurture()
    {
        return $this->hasOne(NurtureShop::class, 'shop_id', 'id');
    }

    public function shopFood()
    {
        return $this->hasOne(Food::class, 'shop_id', 'id');
    }

    public function scopeFoodType($query)
    {
        $type = request()->type;
        if ($type) {
            return $query->whereHas("shopFood", function ($sql) use($type) {
                $sql->where('type', $type);
            });
        }
        return $query->whereHas("shopFood");
    }



//    public function payOrders()
//    {
//        return $this->hasMany(ShopOrder::class, 'shop_id', 'id')->where("pay_status", '<>', 0);
//    }
}
