<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/4/25
 * Time: 14:10
 */

namespace App\Lib\Settlement;
set_time_limit(600);
ini_set('memory_limit', '256M');


use Illuminate\Support\Facades\DB;

class SettlementBase
{
     const  USER_WIN  = 1 ;   //用户赢钱
     const  USER_LOSE = -1;   //用户输钱
     const  USER_FLAT = 2 ;   //持平,用户钱原路返回
     const  USER_HAFWIN = 3 ;  //半平半赢
     const  USER_HALFLOSE = 4 ;  //半平半输

     private  $RefClass = [] ;   //适配器缓存

    //输赢判断
    public function  winOrfalseInfo($gameType,$buyMatchModel,$resultModel,$resultRecordsArray){
        if (!isset($this->RefClass[$gameType])){
            $gameType = ucfirst($gameType);
            $pathBase = dirname(__FILE__).DIRECTORY_SEPARATOR.'Adapter'.DIRECTORY_SEPARATOR ;
            $file = $pathBase.$gameType.'Rule.php';
            if (!file_exists($file)){  throw new \Exception('无胜负判断规则文件');}
            include_once($file);
            $tmpapater =  gameType.'Rule' ;
            $this->RefClass[$gameType] = new $tmpapater();
        }

        $fun = $buyMatchModel->odds_code ;
        $fun2 = $buyMatchModel->p_code ;
        if ( $this->RefClass[$gameType]->hasMethod($fun) ){
            $winorfalse = $this->RefClass[$gameType]->$fun($buyMatchModel,$resultModel,$resultRecordsArray);
        }elseif ( $this->RefClass[$gameType]->hasMethod($fun2) ){
            $winorfalse = $this->RefClass[$gameType]->$fun2($buyMatchModel,$resultModel,$resultRecordsArray);
        }else{
            throw new \Exception('没有找到玩法输赢判断规则',40010);
        }

        if (!in_array($winorfalse,[-1,1,2,3,4])){
            throw new \Exception('胜负判断结果异常',40011);
        }
        return $winorfalse ;
    }

    /**
     * 注单返现计算
     * @param mixed $dataArray 结果表数据 [['odds'=>xx,'winOrLose'=>1],[...]];
     * @return array 注单返现额
     */
    public function   winOddsCalculation($dataArray){
        $returnMoney = 1;
        // 循环计算每注返现赔率
        foreach ($dataArray as $value) {
            $odds = floatval($value['odds']);
            // 因结果不同更改赔率
            switch (intval($value['winOrLose'])) {
                case 1:
                    $oddsDiscount = $odds;
                    break;
                case 2:
                    $oddsDiscount = 1;
                    break;
                case 3:
                    $oddsDiscount = $odds * 0.5;
                    break;
                default:
                    $oddsDiscount = 0.5;
            }
            // 计算每注返现
            $returnMoney = $returnMoney * $oddsDiscount;
        }
        // 计算赚钱
        $earnMoney = $returnMoney - 1;

        return ['earnMoney' => $earnMoney, 'returnMoney' => $returnMoney];
    }

    /**
     * 注单返现计算
     * @param mixed $dataArray 结果表数据 [['odds'=>xx,'winOrLose'=>1],[...]];
     * @return array 注单返现额
     */
    public function   stringOdds($dataArray){
        $returnMoney = 1;
        // 循环计算每注返现赔率
        foreach ($dataArray as $value) {
            $odds = floatval($value['odds']);
            // 因结果不同更改赔率
            switch (intval($value['winOrLose'])) {
                case 1:
                    $oddsDiscount = 1 + $odds;
                    break;
                case 2:
                    $oddsDiscount = 1;
                    break;
                case 3:
                    $oddsDiscount = 1 + $odds * 0.5;
                    break;
                default:
                    $oddsDiscount = 0.5;
            }
            // 计算每注返现
            $returnMoney = $returnMoney * $oddsDiscount;
        }
        // 计算赚钱
        $earnMoney = $returnMoney - 1;

        return ['earnMoney' => $earnMoney, 'returnMoney' => $returnMoney];
    }

    /**
     * 注单返现计算
     * @param mixed $dataArray 结果表数据
     * @return array 注单返现额
     */
    public function stringComputing($dataArray){
        /*$dataArray = [
            [
                ['odds'=>3.02,'winOrLose'=>1],
                ['odds'=>2.84,'winOrLose'=>1],
                ['odds'=>3.01,'winOrLose'=>1],
                ['odds'=>2.94,'winOrLose'=>1]
            ], 2
        ];*/
        $data = $this -> combination($dataArray[0],$dataArray[1]);
        $dataCount = count($data);
        $returnMoney = 0;
        foreach ($data as $key => $value) {
            $getReturnMoney = $this -> stringOdds($value);
            $returnMoney += $getReturnMoney['returnMoney'];
        }
        $returnMoney = $returnMoney / $dataCount;

        return $returnMoney;
    }

    // 组合
    function combination($a, $m) {
        $r = array();

        $n = count($a);
        if ($m <= 0 || $m > $n) {
            return $r;
        }

        for ($i=0; $i<$n; $i++) {
            $t = array($a[$i]);
            if ($m == 1) {
                $r[] = $t;
            } else {
                $b = array_slice($a, $i+1);
                $c = $this->combination($b, $m-1);
                foreach ($c as $v) {
                    $r[] = array_merge($t, $v);
                }
            }
        }

        return $r;
    }

    /**
     * UUID 生成
     */
    public  static  function UUID() {
        $prefix = '';
        $uuid = '';
        $str = md5(uniqid(mt_rand(), true));
        $uuid = substr($str, 0, 8) . '-';
        $uuid .= substr($str, 8, 4) . '-';
        $uuid .= substr($str, 12, 4) . '-';
        $uuid .= substr($str, 16, 4) . '-';
        $uuid .= substr($str, 20, 12);
        return $prefix . $uuid;
    }


    //获取到某个用户的account模型和detail模型，用于用户的余额计算等使用
    public function  getUserInfo($account_name){

        $accountModel = DB::table('account')->where('account',$account_name)->first();
        if (!$accountModel){
            throw  new   \Exception('查无此用户数据account='.$account_name,41002);
        }

        $detailModel = DB::table('account_detailed')->where('account_identity',$accountModel->identity)->first();

        if (!$detailModel){
            throw  new   \Exception('查无此用户数据account_detail='.$accountModel->identity,41002);
        }
        $ret = [
            'account'=>$detailModel,
            'detail' => $detailModel ,
        ];


        return $ret;
    }



}