<?php

namespace DAO;

/**
 * 用户数据层
 */
class DeliveryFormulaModel extends \DAO\AbstractModel {



    /**
     * 表名
     *
     * @var string
     */
    protected $_tableName = 'han_delivery_formula';

    /**
     * 主键
     *
     * @var string
     */
    protected $_primaryKey = 'id';
    public function init(){

    }
    public function getOne($field,$where){
        $this->setDb($this->dbName);
        return $this->db->select($field)->from($this->_tableName)->where($where)->fetchOne();
    }



    public function getDeliveryFormulaByDistince($storeId,$distince,$deliveryFormula){
        if(!$deliveryFormula){
            return false;
        }
        /*$deliveryFormula['state'] == 1 ? $formula = unserialize($deliveryFormula['formula']) : $formula = unserialize($deliveryFormula['simple_formula']);
        if($deliveryFormula['state'] == 1){
            ksort($formula);
            foreach($formula as $key=>$temp){
                if($key*1000>=$distince){
                    return $formula[$key];
                }
            }
        }else{
            foreach($formula as $key=>$temp){
                if($key*1000>=$distince){
                    return $formula[$key];
                }
            }
        }*/
        $formula = unserialize($deliveryFormula['simple_formula']);
        foreach($formula as $key=>$temp){
            if($key*1000>=$distince){
                return $formula[$key];
            }
        }
    }


    public function getDeliveryFormulaForCart($store,$distance,$deliveryFreeFlag=false){
        $deliveryFormula = \Our\RedisHelper::cachedFunction(\Redis\Db6\DeliveryFormulaRedisModel::getInstance(),array(&$this, 'getOne'),array('*',array('store_id'=>$store['store_id'])),\Our\ApiConst::sevenDaySecond,array($store['store_id']));
        if(!$deliveryFormula){
            return false;
        }
        //$deliveryFormula['state'] == \Our\ApiConst::one ? $formula = unserialize($deliveryFormula['formula']) : $formula = unserialize($deliveryFormula['simple_formula']);
        $formula = unserialize($deliveryFormula['simple_formula']);
        ksort($formula);
        foreach ($formula as $k=>$v){
            if($k*1000 >= $distance){
                $choosedData = $v;
                //$choosedData['deliver_distance'] = $k;
                break;
            }
        }
        if(!isset($choosedData)){
            return false;
        }
        $deliveryIntval = intval($store['delivery_interval'])>0?intval($store['delivery_interval']):\Our\ApiConst::defaultDeliveryInterval;
        $time = date('Y-m-d',time());
        $todayUnixTime = strtotime($time);
        if($store['store_dis_sta_time']&&$store['store_dis_end_time']){
            $todayStartTime = strtotime($time.' '.$store['store_dis_sta_time']);
            $todayEndTime = strtotime($time.' '.$store['store_dis_end_time']);
        }else{
            $todayStartTime = $time+\Our\ApiConst::deliveryStartTime;
            $todayEndTime = $time+\Our\ApiConst::deliveryEndTime;
        }
        $tommorowStartTime = $todayStartTime + \Our\ApiConst::oneDaySecond;
        $tommorowEndTime = $todayEndTime + \Our\ApiConst::oneDaySecond;
        /*if($deliveryFormula['state'] == \Our\ApiConst::one) {
            $returnData = $this->getCommonFormula($choosedData,$todayStartTime,$todayEndTime,$tommorowStartTime,$tommorowEndTime,$deliveryIntval);
        }else{
            $returnData = $this->getSimpleFormula($choosedData,$todayStartTime,$todayEndTime,$tommorowStartTime,$tommorowEndTime,$deliveryIntval);
        }*/
        $returnData = $this->getSimpleFormula($choosedData,$todayStartTime,$todayEndTime,$tommorowStartTime,$tommorowEndTime,$deliveryIntval);
        if($deliveryFreeFlag&&$returnData){
            $aRplaceMent=array_fill(0,count($returnData),array('price'=>0));
            $returnData=array_replace_recursive($returnData,$aRplaceMent);
        }
        return $returnData;
    }

    /**
     * 获取简易版配送公式
     * @param $choosedData
     * @param $todayStartTime
     * @param $todayEndTime
     * @param $tommorowStartTime
     * @param $tommorowEndTime
     * @param $deliveryIntval
     * @return array
     */
    public function getSimpleFormula($choosedData,$todayStartTime,$todayEndTime,$tommorowStartTime,$tommorowEndTime,$deliveryIntval){
        $currentTime = time();
        $minTime = $choosedData[0]['time']*\Our\ApiConst::oneMinute;
        $minFee =  $choosedData[count($choosedData)-1]['price']*\Our\ApiConst::hundred;
        ksort($choosedData);
        if($currentTime<$todayStartTime){
            $myCurrentStartTime = $todayStartTime;
            $myCurrentEndTime = $todayEndTime;
        }else if(($currentTime+$minTime)>$todayEndTime){//今天无法配送的情况下直接返回明天的配送时间
            $tommorowData = $this->getTomorrowFormulaList($tommorowStartTime,$tommorowEndTime,\Our\ApiConst::oneHour,$minFee,$currentTime);
            $returnData = $tommorowData;
            ksort($returnData);
            foreach($returnData as &$data){
                $data['isDefault'] = \Our\ApiConst::one;
                break;
            }
            return $returnData;
        }else{
            $myCurrentStartTime = $currentTime;
            $myCurrentEndTime = $todayEndTime;
        }
        $tommorowData = $this->getTomorrowFormulaList($tommorowStartTime,$tommorowEndTime,\Our\ApiConst::oneHour,$minFee,$myCurrentStartTime);
        $returnData = array();
        ksort($choosedData);
        $expriseStartTime = \Our\ApiConst::zero;
        //var_dump($choosedData);
        foreach($choosedData as $key=>$temp){
            $tempData = array();
            $expriseStartTime = $myCurrentStartTime+ $temp['time']*\Our\ApiConst::oneMinute;
            if($expriseStartTime<=$myCurrentEndTime){
                $tempData['interval'] = $temp['time']*\Our\ApiConst::oneMinute;
                $tempData['time'] = $myCurrentStartTime + $tempData['interval'];
                $tempData['price'] = $temp['price']*\Our\ApiConst::hundred;
                if($key==2){
                    $tempData['isDefault'] = \Our\ApiConst::one;
                }else{
                    $tempData['isDefault'] = \Our\ApiConst::zero;
                }
                $returnData[] = $tempData;
            }else{
                break;
            }
        }
        $expriseStartTime += $deliveryIntval*\Our\ApiConst::oneMinute;
        if($expriseStartTime<$todayEndTime){
            $expriseData = $this->getTomorrowFormulaList($expriseStartTime,$todayEndTime,$deliveryIntval*\Our\ApiConst::oneMinute,$minFee,$myCurrentStartTime);
            if($expriseData){
                $returnData = array_merge($expriseData,$returnData);
            }
        }
        if($returnData){
            $returnData = array_merge($returnData,$tommorowData);
        }else{
            $returnData = $tommorowData;
        }
        foreach($returnData as $key => $delivery){
            $time[$key] = $delivery['time'];
        }
        array_multisort($time, SORT_ASC, $returnData);
        return $returnData;
    }


    /**
     * 获取常规版配送公式
     * @param $formula
     * @param $todayStartTime
     * @param $todayEndTime
     * @param $tommorowStartTime
     * @param $tommorowEndTime
     * @param $deliveryIntval
     * @return array
     */
    public function getCommonFormula($formula,$todayStartTime,$todayEndTime,$tommorowStartTime,$tommorowEndTime,$deliveryIntval){
        $returnData = array();
        $currentTime = time();
        $minTime = $formula['min_time'] * \Our\ApiConst::oneMinute;
        $minFee = $formula['min_price'] * \Our\ApiConst::hundred;
        $defaultFee = $formula['default_price'] * \Our\ApiConst::hundred;
        if($currentTime<$todayStartTime){
            $myCurrentStartTime = $todayStartTime;
            $myCurrentEndTime = $todayEndTime;
        }else if(($currentTime+$minTime)>$todayEndTime){//今天无法配送的情况下直接返回明天的配送时间
            $tommorowData = $this->getTomorrowFormulaList($tommorowStartTime,$tommorowEndTime,\Our\ApiConst::oneHour,$minFee,$currentTime);
            $returnData = $tommorowData;
            ksort($returnData);
            foreach($returnData as &$data){
                $data['isDefault'] = \Our\ApiConst::one;
                break;
            }
            return $returnData;
        }else{
            $myCurrentStartTime = $currentTime;
            $myCurrentEndTime = $todayEndTime;
        }
        $tommorowData = $this->getTomorrowFormulaList($tommorowStartTime,$tommorowEndTime,\Our\ApiConst::oneHour,$minFee,$myCurrentStartTime);
        $defalutTime = $myCurrentStartTime + $formula['default_time']*\Our\ApiConst::oneMinute;
        $defalutData['time'] = $defalutTime;
        $defalutData['interval'] = $formula['default_time']*\Our\ApiConst::oneMinute;
        $defalutData['price'] = $formula['default_price']*\Our\ApiConst::hundred;
        $defalutData['isDefault'] = \Our\ApiConst::one;
        $returnData[] = $defalutData;
        $earlierTotalPrice = ($formula['max_price']-$formula['default_price'])*\Our\ApiConst::hundred;
        $earlierTimeIntervalNum  = ($formula['default_time'] - $formula['min_time'])/$formula['interval_time'];
        $earlierPrice = round($earlierTotalPrice/$earlierTimeIntervalNum);//更早送达的单个时间间隔单价
        $intervalTimeInSecond = $formula['interval_time']* \Our\ApiConst::oneMinute;
        for($i = \Our\ApiConst::one;$i<=$earlierTimeIntervalNum;$i++){
            if(($defalutTime - $intervalTimeInSecond*$i)>$myCurrentStartTime){
                $temp = array();
                $temp['time'] = $defalutTime - $intervalTimeInSecond*$i;
                $temp['interval']=$temp['time'] - $currentTime;
                $temp['price'] = $defaultFee + $earlierPrice*$i;
                $temp['isDefault'] = \Our\ApiConst::zero;
                $returnData[] =$temp;
            }
        }
        $laterTotalPrice = ($formula['default_price']-$formula['min_price'])*\Our\ApiConst::hundred;
        $laterTimeIntervalNum  = ($formula['max_time']-$formula['default_time'] )/$formula['interval_time'];
        $laterPrice = round($laterTotalPrice/$laterTimeIntervalNum);//更早送达的单个时间间隔单价
        $intervalTimeInSecond = $formula['interval_time']* \Our\ApiConst::oneMinute;
        $maxLastTime = \Our\ApiConst::zero;
        for($j = \Our\ApiConst::one;$j<=$laterTimeIntervalNum;$j++){
            if(($defalutTime + $intervalTimeInSecond*$j)<$myCurrentEndTime){
                $temp = array();
                $maxLastTime = $defalutTime + $intervalTimeInSecond*$j;
                $temp['interval']=$maxLastTime-$currentTime;
                $temp['time'] = $maxLastTime;
                $temp['price'] =  $defaultFee- $laterPrice*$j;
                $temp['isDefault'] = \Our\ApiConst::zero;
                $returnData[] =$temp;
            }
        }
        if($maxLastTime+$deliveryIntval*\Our\ApiConst::oneMinute<$myCurrentEndTime){//超过最大配送时间之后的配送
            $otherReturnData = $this->getTomorrowFormulaList($maxLastTime,$myCurrentEndTime,\Our\ApiConst::oneHour,$minFee,$currentTime);
            if($otherReturnData){
                $returnData = array_merge($returnData,$otherReturnData);
            }
        }
        $returnData = array_merge($returnData,$tommorowData);
        foreach($returnData as $key => $delivery){
            $time[$key] = $delivery['time'];
        }
        array_multisort($time, SORT_ASC, $returnData);
        return $returnData;
    }

    /**
     * 获取超出时间配送公式
     * @param $tommorowStartTime
     * @param $tommorowEndTime
     * @param $deliveryIntval
     * @param $defaultDeliveryMoney
     */
    public function getTomorrowFormulaList($tommorowStartTime,$tommorowEndTime,$deliveryIntval,$defaultDeliveryMoney,$currentTime){
        $return = array();
        for($i=$tommorowStartTime;$i<$tommorowEndTime;$i = $i+($deliveryIntval)){
            $temp = array();
            $temp['time'] = $i;
            $temp['interval'] = $i-$currentTime;
            $temp['price'] = $defaultDeliveryMoney;
            $temp['isDefault'] = \Our\ApiConst::zero;
            $return[] = $temp;
        }
        return $return;
    }


    /**
     * 类实例
     *
     * @var \DAO\UserModel
     */
    private static $_instance = null;

    /**
     * 获取类实例
     *
     * @return \DAO\UserModel
     */
    public static function getInstance($dbName = \Our\DbNameConst::salveDBConnectName) {
        if (!(self::$_instance instanceof self)) {
            self::$_instance = new self($dbName);
        }

        return self::$_instance;
    }

}
