<?php

namespace DAO\Order;


use Error\CodeConfigModel;
use Error\ErrorModel;
use OSS\Common;
use Our\ApiConst;
use Our\DbNameConst;
use Our\DescribeConst;
use Our\ImageConst;
use Our\ImageUtil;
use Our\OrderConst;
use Payment\Alipay;

class RefundReturnModel extends \DAO\AbstractModel {

    public $errorCode;
    /**
     * 表名
     *
     * @var string
     */
    protected $_tableName = 'han_refund_return';
    public $refundDetailField='is_platform_in as isPlatformIn,seller_state as sellerState,platform_state as platformState,refund_id as refundId,order_id as orderId,store_id as storeId,order_goods_id as orderGoodsId';
    public $refundReturnField="seller_state,refund_state,is_platform_in,platform_state";
    private $sumField="order_id as orderId,buyer_id as buyerId,store_id as storeId,goods_num as goodsNum,refund_amount as refundAmount,is_suc_refund as isSucRefund,gmt_update as gmtUpdate";
    private $sumRefundAmount=" sum(refund_amount) as sumRefundAmont";
    /**
     * 主键
     *
     * @var string
     */
    protected $_primaryKey = 'refund_id';
    public $errorMessage='';
    public function init(){

    }
    public function getCount($where){
        $this->setDb();
        return $this->db->from($this->_tableName)->where($where)->fetchNum();
    }

    public function getAll($where,$field,$db=DbNameConst::salveDBConnectName){
        $this->setDb($db);
        $list = $this->db->select($field)->from($this->_tableName)->where($where)->fetchAll();
        return $list;
    }


    public function getRefundSuccessMoneyByStoreId($storeId,$beginTime=false,$endTime=false){
        $this->setDb($this->dbName);
        if($beginTime){
            $where=\Our\Common::format(" store_id={0} and is_suc_refund={1}  and gmt_update between {2} and {3}",$storeId,ApiConst::refundSuccess,$beginTime,$endTime);
        }else{
            $where=\Our\Common::format(" store_id={0}  and is_suc_refund={1}",$storeId,ApiConst::refundSuccess);
        }
        $res=$this->db->from($this->_tableName)->select($this->sumRefundAmount)->where($where)->fetchValue();
        return !empty($res)?$res:ApiConst::zero;

    }
    public function getRefundSuccessMoneyByStoreIdAndMemberId($storeId,$buyerId){
        $this->setDb($this->dbName);
        if(is_array($storeId)){
            $storeId=implode(',',$storeId);
        }
        if(is_array($buyerId)){
            $buyerId=implode(',',$buyerId);
        }
        $where=\Our\Common::format(" store_id in({0}) and buyer_id in({1}) and is_suc_refund={2}",$storeId,$buyerId,ApiConst::refundSuccess);
        $res=$this->db->from($this->_tableName)->where($where)->select(" buyer_id as buyerId,store_id as storeId,(SUM(refund_amount)) AS refundTotal")->group('buyer_id')->group('store_id')->fetchAll();
        return !empty($res)?$res:[];

    }
    /**
     * 更新数据
     * @param $data
     * @param $where
     * @return mixed
     */
    public function update($where, $data)
    {
        $this->setDb(\Our\DbNameConst::masterDBConnectName);
        return $this->db->update($this->_tableName)->where($where)->rows($data)->execute();
    }
   //更新退货物流信息
    public function updateReturnShippingByRefundId($refundId,$data){
        $where[$this->_primaryKey]=$refundId;
        $updateData['express_id']=$data['expressId'];
        $updateData['invoice_no']=$data['invoiceNo'];
        $updateData['address_id']=$data['addressId'];
        $updateData['goods_state']=ApiConst::goodsStateWaitRecieve;
        $updateData['ship_time']=TIMESTAMP;
        return $this->update($where,$updateData);
    }
    //检查是否可以添加退货物流信息
    public function checkIsAddReturnShipping($refundReturn){
        $isReturn=TRUE;
        if($refundReturn['sellerState']!=ApiConst::refundSellerAgree){
            $this->errorCode=CodeConfigModel::notReturnAgree;
            $isReturn=FALSE;
        }
        if($refundReturn['refundType']!=ApiConst::refundTypeGoods){
            $this->errorCode=CodeConfigModel::isNotReturn;
            $isReturn=FALSE;
        }
        if($refundReturn['refundShippingType']!=ApiConst::express){
            $this->errorCode=CodeConfigModel::isNotExpressType;
            $isReturn=FALSE;
        }
        if($refundReturn['expressId']>ApiConst::zero){
            $this->errorCode=CodeConfigModel::isNotExpressType;
            $isReturn=FALSE;
        }
        return $isReturn;
    }
    /**
     * 申请平台介入
     * @param $data
     * @param $where
     * @return mixed
     */
    public function updateStatusByBuyerIdAndRefundId($buyerId,$refundId,$applyMessage)
    {
        $where['refund_id'] = $refundId;
        $where['buyer_id'] = $buyerId;
        $data['is_platform_in']=ApiConst::platIn;
        $data['refund_state']=ApiConst::platProccess;
        $data['platform_in_reason']=$applyMessage;
        return $this->update($where, $data);
    }
    /**
     * 获取单条数据
     * @param $where
     * @return array
     */
    public function find($where,$field='*')
    {
        $this->setDb($this->dbName);
        $data = $this->db->from($this->_tableName)->select($field)->where($where)->fetchOne();
        return $data;
    }

    public function findByRefundId($refundId,$field='*')
    {
        $where['refund_id'] = $refundId;
        return $this->find($where,$field);
    }

    public function findByMemberIdAndRefundId($memberId,$refundId,$field='*'){
        $where['buyer_id']=$memberId;
        $where['refund_id']=$refundId;
        return $this->find($where,$field);
    }

    public function getAllByOrderIds($orderIds,$field='*'){
        if(is_array($orderIds)){
            $where=Common::format(" order_id in {0}",implode(',',$orderIds));
        }else{
            $where['order_id']=$orderIds;
        }
        return $this->getAll($where,$field);
    }

    public function getStatusExtent($returnRefund){
      //  if($returnRefund['refundState']!=ApiConst::refundCompleted){
            if($returnRefund['sellerState']==ApiConst::refundSellerAgree){
                if($returnRefund['isSucRefund']==ApiConst::refundSuccess){
                    return OrderConst::refoundSuccess;
                }
                if($returnRefund['refundType']==ApiConst::refundTypeMoney){
                    return OrderConst::sellerAgree;
                }
                if($returnRefund['refundType']==ApiConst::refundTypeGoods){
                    if($returnRefund['isSucRefund']==ApiConst::refundSuccess){
                        return OrderConst::sellerAgreeGoods;
                    }else{
                        return OrderConst::waitSellerRecieve;
                    }
                }
            }
            if($returnRefund['sellerState']==ApiConst::refundSellerRefuse){
                if($returnRefund['isSucRefund']==ApiConst::refundSuccess){
                    return OrderConst::refoundSuccess;
                }
                if($returnRefund['platformState']==ApiConst::platAgree){
                    return OrderConst::platFormAgree;
                }
                if($returnRefund['platformState']==ApiConst::platRefuse){
                    return OrderConst::platFormRefuse;
                }
                if($returnRefund['isPlatformIn']==ApiConst::platIn){
                    return OrderConst::platFromProccess;
                }
                if($returnRefund['refundType']==ApiConst::refundTypeMoney){
                    return OrderConst::sellerRefuse;
                }
                if($returnRefund['refundType']==ApiConst::refundTypeGoods){
                    return OrderConst::sellerRefuseGoods;
                }

            }
//        }else{
//                return OrderConst::refoundSuccess;
//        }


    }
    public function getRefundTextStatus($refundReturn){
        $refundText='';
        switch($refundReturn['sellerState']){
            case ApiConst::refundSellerVerify:$refundText=OrderConst::waitVerify;break;
            case ApiConst::refundSellerAgree:$refundText=$this->getStatusExtent($refundReturn);break;
            case ApiConst::refundSellerRefuse:$refundText=$this->getStatusExtent($refundReturn);break;
        }

        return $refundText;
    }
    public function getStatusText($orderId){
        $where['order_id']=$orderId;
        $refundReturn= $this->db->from($this->_tableName)->select($this->refundReturnField)->where($where)->fetchOne();
        return $this->getRefundTextStatus($refundReturn);
    }
    /**
     * 根据退货退款订单详情获取是否可申请平台介入
     *
     * @param
     * @return array
     */
    public function isPlatformIn($refundInfo){

           if(($refundInfo['isPlatformIn']==ApiConst::platNotIn && ($refundInfo['sellerState']==ApiConst::refundSellerRefuse) || $refundInfo['buyerRefundAmount']>$refundInfo['refundAmount'])){
                return TRUE;
           }else{
               return FALSE;
           }
    }
    /**
     * 根据订单状态判断是否可以退款退货
     *
     * @param
     * @return array
     */
    public function isReturn($order) {
        $refund = FALSE;//默认不允许退款退货
        $orderState = $order['orderState'];//订单状态
        ApiConst::orderStateWaitRecieve;//30:已发货
        ApiConst::orderStateComplete;//40:已收货
        switch ($orderState) {
            //已发货
            case ApiConst::orderStateWaitRecieve:
                $payment_code = $order['paymentCode'];//支付方式
                if ($payment_code != 'offline') {//货到付款订单在没确认收货前不能退款退货
                    $refund = TRUE;
                }else{
                    ErrorModel::throwException(CodeConfigModel::returnErrorAfterPay);
                }
                break;
            //已收货
            case  ApiConst::orderStateComplete:

                if($order['shippingType']==ApiConst::express){
                    $order_refund=ApiConst::canRefundDay;
                }else{
                    $order_refund=ApiConst::byselfRfundDay;
                }
                if($order['delayTime']>ApiConst::zero){
                    $delay_time = $order['delayTime']+60*60*24*$order_refund;
                }else{
                    $delay_time = $order['gmtUpdate']+60*60*24*$order_refund;
                }
                if ($delay_time > TIMESTAMP) {
                    $refund = TRUE;
                }else{
                    ErrorModel::throwException(CodeConfigModel::returnBeyondTimeError);
                }

                break;
            default:
                $refund = FALSE;
                break;
        }

        return $refund;
    }
    /**
     * 退款退货申请编号
     *
     * @param
     * @return array
     */
    public function getRefundsn($store_id) {
        $result = mt_rand(100,999).substr(100+$store_id,-3).date('ymdHis');
        return $result;
    }
    /**
     * 退款退货申请编号
     *
     * @param
     * @return array
     */
    public function getRefundPics($pics){
        $picsRes=array();
        if($pics){
            foreach($pics as $pic){
                $readFile=\Our\Common::getStaticFile($pic,ImageConst::refund);
                array_push($picsRes,$readFile);
            }
        }
        return $picsRes;

    }

    /**
     * 店铺退款
     * @param $orderInfo 订单信息
     */
    public function storeRefund($orderInfo){
        $param['refundOrderNo'] = !empty($orderInfo['refund_order_no']) ? $orderInfo['refund_order_no'] : $this->getRefundsn($orderInfo['store_id']);
        //这个有可能多次退款的时候要变
        $param['outTradeNo'] = $orderInfo['pay_sn'];
        $param['totalFee'] = $orderInfo['order_amount'];
        $param['refundFee'] = $orderInfo['refund_amount'];//退款金额
        $param['storeId'] = $orderInfo['store_id'];
        $param['buyerId'] = $orderInfo['buyer_id'];
        if (intval($orderInfo['payment_type']) == ApiConst::wxAppPayType) {
            $wxpay = \Payment\WxPay::getInstance();
            $refund_return = $wxpay->refund($param);
            $this->errorMessage= "微信返回:".json_encode($refund_return);
            if (!($refund_return['return_code'] == 'SUCCESS' && $refund_return['result_code'] == 'SUCCESS')) {
                $this->errorMessage=date('Y-m-d').'微信退款操作执行失败！'.$orderInfo['order_id']."\r\n";
                return false;
            }
        } else if (intval($orderInfo['payment_type']) == ApiConst::alipay) {
            $aliPay = \Payment\Alipay::getInstance();
            $return = $aliPay->refund($param);
            $this->errorMessage = "支付宝返回:" . json_encode($return);
            $resultCode = $return->code;
            if (!empty($resultCode) && $resultCode == ApiConst::alipayRefundSuccess) {
                return true;
            } else {
                $this->errorMessage = date('Y-m-d') . '支付宝退款操作执行失败:' . $orderInfo['order_id'] . "\r\n";
                return false;
            }
        }else if(intval($orderInfo['payment_type']) == ApiConst::wxProgram){
            $wxpay = \Payment\WxPay::getInstance();
            $refund_return = $wxpay->refund($param);
            $this->errorMessage= "微信小程序返回:".json_encode($refund_return);
            if (!($refund_return['return_code'] == 'SUCCESS' && $refund_return['result_code'] == 'SUCCESS')) {
                $this->errorMessage=date('Y-m-d').'微信退款操作执行失败！'.$orderInfo['order_id']."\r\n";
                return false;
            }
        }
        return true;
    }

    /**
     * 退款
     * @param $orderInfo
     * @return bool
     */
    public function refundMoney($orderInfo){

        $param['refundOrderNo'] = !empty($orderInfo['refundOrderNo'])?$orderInfo['refundOrderNo']:$this->getRefundsn($orderInfo['storeId']);
        //这个有可能多次退款的时候要变
        $param['outTradeNo'] = $orderInfo['paySn'];
        $param['totalFee'] = $orderInfo['orderAmount'];
        $param['refundFee'] = $orderInfo['orderAmount'];//全额退款
        $param['storeId']=$orderInfo['storeId'];
        $param['buyerId']=$orderInfo['buyerId'];
        if (intval($orderInfo['paymentType']) == ApiConst::wxAppPayType) {
            $wxpay = \Payment\WxPay::getInstance();
            $refund_return = $wxpay->refund($param);
            $this->errorMessage= "微信返回:".json_encode($refund_return);
            if (!($refund_return['return_code'] == 'SUCCESS' && $refund_return['result_code'] == 'SUCCESS')) {
                $this->errorMessage=date('Y-m-d').'微信退款操作执行失败！'.$orderInfo['orderId']."\r\n";
                return false;
            }
        } else if (intval($orderInfo['paymentType']) == ApiConst::alipay) {
            $aliPay = \Payment\Alipay::getInstance();
            $return = $aliPay->refund($param);
            $this->errorMessage = "支付宝返回:" . json_encode($return);
            $resultCode = $return->code;
            if (!empty($resultCode) && $resultCode == ApiConst::alipayRefundSuccess) {
                return true;
            } else {
                $this->errorMessage = date('Y-m-d') . '支付宝退款操作执行失败:' . $orderInfo['orderId'] . "\r\n";
                return false;
            }
        }else if(intval($orderInfo['paymentType']) == ApiConst::wxProgram){
            $wxpay = \Payment\WxPay::getInstance();
            $refund_return = $wxpay->refundWxProgram($param);
            $this->errorMessage= "微信小程序返回:".json_encode($refund_return);
            if (!($refund_return['return_code'] == 'SUCCESS' && $refund_return['result_code'] == 'SUCCESS')) {
                $this->errorMessage=date('Y-m-d').'微信退款操作执行失败！'.$orderInfo['orderId']."\r\n";
                return false;
            }
        }
        return true;
    }

    /**
     * 修改记录
     *
     * @param $condition
     * @param $data
     * @return bool
     */
    public function editRefundReturn($condition, $data) {
        if (empty($condition)) {
            return false;
        }
        $this->setDb($this->dbName);
        if (is_array($data)) {
            $result = $this->db->update($this->_tableName)->rows($data)->where($condition)->execute();
            return $result;
        } else {
            return false;
        }
    }
    /**
     * 增加退款退货
     *
     * @param
     * @return int
     */
    public function addRefundReturn($refund_array, $order = array(), $goods = array()) {
        $this->setDb($this->dbName);
        if (!empty($order) && is_array($order)) {
            $refund_array['order_id'] = $order['orderId'];
            $refund_array['order_sn'] = $order['orderSn'];
            $refund_array['store_id'] = $order['storeId'];
            $refund_array['store_name'] = $order['storeName'];
            $refund_array['buyer_id'] = $order['buyerId'];
            $refund_array['buyer_name'] = $order['buyerName'];
        }
        if (!empty($goods) && is_array($goods)) {
            $refund_array['goods_id'] = $goods['goodsId'];
            $refund_array['order_goods_id'] = $goods['recId'];
            $refund_array['order_goods_type'] = $goods['goodsType'];
            $refund_array['goods_name'] = $goods['goodsName'];
            $refund_array['commis_rate'] = $goods['commisRate'];
            $refund_array['goods_image'] = $goods['goodsImage'];
        }
        if(!isset($refund_array['refund_sn'])|| !$refund_array['refund_sn']){
            $refund_array['refund_sn'] = $this->getRefundsn($order['storeId']);
        }
        $refund_id = $this->db->insert($this->_tableName)->rows($refund_array)->execute();
        // 发送商家提醒
        $param = array();

        if (intval($refund_array['refund_type']) == ApiConst::refundTypeMoney) {    // 退款
            $param['code'] = 'refund';
        } else {    // 退货
            $param['code'] = 'return';
        }
        $param['store_id'] = $order['storeId'];
        $type = $refund_array['order_lock'] == ApiConst::refundTypeGoods ? DescribeConst::beforeSale : DescribeConst::afterSale;
        $param['param'] = array(
            'type' => $type,
            'refund_sn' => $refund_array['refund_sn']
        );
       // QueueClient::push('sendStoreMsg', $param);

        return $refund_id;
    }
    //删除订单详情缓存
    public function deleteFindByOrderIdCache($refundId)
    {
        return \Our\RedisHelper::delCachedFunction(\Redis\Db5\OrderRedisModel::getInstance(), array(&$this, 'findByRefundId'), array(),array($refundId));
    }

    //删除订单列表缓存
    public function deleteGetListByMemberId($memberId)
    {
        return \Our\RedisHelper::delCachedFunction(\Redis\Db5\OrderRedisModel::getInstance(), array(&$this, 'getList'), array(), array($memberId));
    }

    //删除订单缓存
    public function deleteRefundCache($memberId, $refundId=false)
    {
        if(!empty($memberId)){
            $this->deleteGetListByMemberId($memberId);
        }
        if(!empty($refundId)){
            $this->deleteFindByOrderIdCache($refundId);
        }
    }
    /**
     *获得退货退款列表
     *
     * @var \DAO\getList
     */
    public function getList($where, $field, $pageIndex, $pageSize, $order = array('add_time' => 'desc'))
    {
        $this->setDb($this->dbName);
        $refunds = $this->lists($where, $order, $field, $pageIndex, $pageSize);
        return $refunds ? $refunds : array();
    }
    //根据传过来的退款类型获取退款类型
    public function getRefundTypeByType($refundType){
        $returnType=ApiConst::refundTypeGoods;
        if ($refundType!= ApiConst::refundTypeGoods) {
            $returnType = ApiConst::refundTypeMoney;
        }
        return $returnType;
    }

    public function getMemberStoreStaticsByGmtUpdate($gmtUpdate,$pageIndex,$pageSize){
        $this->setDb($this->dbName);
        $where =\Our\Common::format(' gmt_update>={0} and gmt_update<{1} and refund_state={2}',$gmtUpdate,TIMESTAMP,ApiConst::refundStateComplete);
        $res=$this->lists($where,array('gmt_update'=>'asc'),$this->sumField,$pageIndex,$pageSize);
        return $res['list']?$res:false;
    }
    /**
     *获得退货退款列表
     *
     * @var \DAO\getList
     */
    public function updateRefundShipping(){

    }

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


    /**
     * 单例模式获取类实例
     *
     */
    public static function getInstance($dbName=DbNameConst::salveDBConnectName)
    {
        if (!(self::$_instance instanceof self)) {
            self::$_instance = new self($dbName);
        }

        return self::$_instance;
    }

    /**
     * @param $storeId
     * @param $orderState
     * @return mixed 待处理
     */
    public function getCountByRefundState($storeId,$refundState){
        $where['store_id']=$storeId;
        $where['refund_state']=$refundState;
        $count=$this->getCountByWhere($where);
        return $count;
    }
    /**
     * @param $storeId
     * @param $orderState
     * @return mixed 待收货
     */
    public function getCountByRefundType($storeId,$refundType){
        $where['store_id']=$storeId;
        $where['refund_type']=$refundType;
        $where['goods_state']=array('neq',ApiConst::four);
        $count=$this->getCountByWhere($where);
        return $count;
    }

}
