<?php namespace App\Models;


use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Yajny\Member\FraudDetection\FraudDetection;
use Yajny\Member\FraudDetection\Utils\FraudDetectionPeriodsUtil;
use Yajny\Member\Models\FraudDetectionLog;


class FraudRule extends Central
{

    protected $table = 'fraud_rules';
    protected $primaryKey = 'id';
    public $module = 'fraudrules';

    protected $guarded = [];
    public $timestamps = false;


    public function __construct()
    {
        parent::__construct();

    }

    public static function querySelect()
    {

        return "  SELECT fraud_rules.* FROM fraud_rules  ";
    }

    public static function queryWhere()
    {

        return "  WHERE fraud_rules.id IS NOT NULL ";
    }

    public static function queryGroup()
    {
        return "  ";
    }

    protected $casts = [
        'store_ids' => 'array'
    ];

    public static function boot()
    {
        parent::boot();

        static::created(function ($fraudRule) {
            if (strtotime($fraudRule->effective_from) <= strtotime('today - 2 weeks'))
                (new FraudDetection($fraudRule))->run();
        });
    }

    public function fraud_logs()
    {
        return $this->hasMany(FraudDetectionLog::class, 'fraud_rule_id', 'id');
    }

    public function getFraudUsersThatExceedsOrderCount($from, $to): array
    {
        $transactionGroupBy = '';
        switch ($this->order_count_per) {
            case FraudDetectionPeriodsUtil::PER_DAY:
                $transactionGroupBy = 'DATE(us.transaction_time)';
                break;
            case FraudDetectionPeriodsUtil::PER_WEEK:
                $transactionGroupBy = "YEARWEEK(us.transaction_time)";
                break;
            case FraudDetectionPeriodsUtil::PER_MONTH:
                $transactionGroupBy = "YEAR(us.transaction_time), MONTH(us.transaction_time)";
                break;
        }
        $storeIDs = implode(',', $this->store_ids);
        $query = "
                SELECT us.user_id, count(*) as orderCount 
                FROM user_sales us
                JOIN users u on u.user_id = us.user_id and u.is_merchant = 0
                WHERE us.store_id in ({$storeIDs}) and DATE(us.transaction_time) BETWEEN '{$from}' and '{$to}'
                GROUP BY us.user_id, us.store_id, {$transactionGroupBy}
                HAVING orderCount >= {$this->order_count}";
        $fraudUsers = DB::select($query);
        return Arr::pluck($fraudUsers, 'user_id');
    }

    public function getFraudUsersThatExceedsTotalOrderAmount($from, $to): array
    {
        $transactionGroupBy = '';
        switch ($this->total_order_amount_per) {
            case FraudDetectionPeriodsUtil::PER_DAY:
                $transactionGroupBy = 'DATE(us.transaction_time)';
                break;
            case FraudDetectionPeriodsUtil::PER_WEEK:
                $transactionGroupBy = "YEARWEEK(us.transaction_time)";
                break;
            case FraudDetectionPeriodsUtil::PER_MONTH:
                $transactionGroupBy = "YEAR(us.transaction_time), MONTH(us.transaction_time)";
                break;
        }
        $storeIDs = implode(',', $this->store_ids);
        $query = "
                SELECT us.user_id, sum(us.order_amount) as totalOrderAmount 
                FROM user_sales us
                JOIN users u on u.user_id = us.user_id and u.is_merchant = 0
                WHERE us.store_id in ({$storeIDs}) and DATE(us.transaction_time) BETWEEN '{$from}' and '{$to}'
                GROUP BY us.user_id, us.store_id, {$transactionGroupBy}
                HAVING totalOrderAmount >= {$this->total_order_amount}";
        $fraudUsers = DB::select($query);
        return Arr::pluck($fraudUsers, 'user_id');
    }

}
