<?php

namespace App\Models;

use App\Models\Traits\BelongsToUser;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Facades\DB;

class Activity extends Model
{

    use BelongsToUser;

    protected $dates = [
        'start_at',
        'end_at',
    ];

    const TYPE_EXTEND = 1;
    const TYPE_SCOPE  = 2;
    const TYPE_MONTH  = 3;
    const TYPES       = [
        self::TYPE_EXTEND => '延期',
        self::TYPE_SCOPE  => '固定',
        self::TYPE_MONTH  => '当月',
    ];

    const STATUS_OPEN  = 1;
    const STATUS_CLOSE = 0;
    const STATUS       = [
        self::STATUS_OPEN  => '正常',
        self::STATUS_CLOSE => '关闭',
    ];

    const CHANNEL_YSD   = 1;
    const CHANNEL_UNION = 2;
    const CHANNELS      = [
        self::CHANNEL_YSD   => '亿时代',
        self::CHANNEL_UNION => '银联',
    ];

    const VERIFY_SHOP_YES = 1;
    const VERIFY_SHOP_NO  = 0;
    const VERIFY_SHOPS    = [
        self::VERIFY_SHOP_YES => '是',
        self::VERIFY_SHOP_NO  => '否',
    ];

    /**
     * 默认加载的关联
     *
     * @var array
     */
    protected $with = ['rule'];

    protected static function boot(): void
    {
        parent::boot();

        self::creating(function ($model) {
            $model->code = 'ysd'.date('Ym').mt_rand(100, 999);
        });
    }

    //活动类型  固定期限 延期
    public function getTypeTextAttribute(): string
    {
        return self::TYPES[$this->type] ?? '未知';
    }

    //活动状态
    public function getStatusTextAttribute(): string
    {
        return self::STATUS[$this->status] ?? '未知';
    }

    //关联卡券规则 ysd-full100-10
    public function rule(): BelongsTo
    {
        return $this->belongsTo(ActivityRule::class, 'activity_rule_id');
    }

    //关联券表
    public function coupons(): HasMany
    {
        return $this->hasMany(ActivityCoupon::class);
    }

    /**
     * Notes: 关联可发券渠道中间表
     *
     * @Author: 玄尘
     * @Date  : 2020/8/21 11:09
     */
    public function grants(): HasMany
    {
        return $this->hasMany(ActivityGrant::class);
    }

    /**
     * Notes: 可发券的渠道
     *
     * @Author: 玄尘
     * @Date  : 2021/4/25 11:36
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function grant_users(): BelongsToMany
    {
        return $this->belongsToMany(User::class, 'activity_grants')->using(ActivityGrant::class);
    }

    /**
     * Notes: 关联可核券网点中间表
     *
     * @Author: 玄尘
     * @Date  : 2020/8/21 11:09
     */
    public function shops(): HasMany
    {
        return $this->hasMany(ActivityShop::class);
    }

    /**
     * Notes: 关联可核销渠道
     *
     * @Author: 玄尘
     * @Date  : 2020/8/21 11:09
     */
    public function verifications(): HasMany
    {
        return $this->hasMany(ActivityVerification::class);
    }

    /**
     * Notes: 可核销的渠道
     *
     * @Author: 玄尘
     * @Date  : 2021/4/25 11:37
     */
    public function verify_users(): BelongsToMany
    {
        return $this->belongsToMany(User::class, 'activity_verifications')->using(ActivityVerification::class);
    }

    /**
     * Notes: 是否可以发券
     *
     * @Author: 玄尘
     * @Date  : 2021/4/25 10:41
     * @return mixed
     */
    public function canGrant()
    {
        return $this->status;
    }

    /**
     * Notes: 生成优惠券码
     *
     * @Author: 玄尘
     * @Date  : 2021/4/25 10:41
     * @return mixed|string
     */
    public function getCode()
    {
        //判断生成何种码
        if ($this->channel == self::CHANNEL_UNION) {
            $code = '66406'.date('ymdHi').mt_rand(10000, 99999);
        } else {
            $code_length = config('pingan.code_length');

            switch ($code_length) {
                case 17://17位长度
                    $code = 'YSD'.substr(date('ymdHi'), 1).mt_rand(10000, 99999);
                    break;
                case 15://15位长度
                    $code = 'YSD'.substr(date('ymdH'), 1).mt_rand(10000, 99999);
                    break;
                default://默认15位长度
                    $code = 'YSD'.substr(date('ymdH'), 1).mt_rand(10000, 99999);
                    break;
            }

        }

        //查询是否存在，存在重新生成
        $exists = ActivityCoupon::where('code', $code)->exists();
        if ($exists) {
            return $this->getCode();
        }

        return $code;
    }

    //发券
    public function grant($mobile, $outletId = null)
    {
        try {
            $code = $this->getCode();

            if ($this->type == SELF::TYPE_EXTEND) {
                $start_at = now();
                $end_at   = now()->addDays($this->days);
            } elseif ($this->type == self::TYPE_MONTH) {
                $start_at = now();
                $end_at   = now()->endOfMonth();
            } else {
                $start_at = $this->start_at->startOfDay();
                $end_at   = $this->end_at->endOfDay();
            }

            DB::beginTransaction();
            $coupon = ActivityCoupon::create([
                'activity_id' => $this->id,
                'code'        => $code,
                'mobile'      => $mobile,
                'outletId'    => $outletId,
                'full'        => $this->rule->full,
                'price'       => $this->rule->take,
                'start_at'    => $start_at,
                'end_at'      => $end_at,
                'status'      => ActivityCoupon::STATUS_INIT,
            ]);

            DB::commit();

            return $coupon;
        } catch (\Exception $e) {
            DB::rollback();
            return $e->getMessage();
        }
    }
}
