<?php
namespace Business\User;
use Our\ApiConst;

/**
 * 地址管理相关
 * User: liuyuzhen
 * Date: 2018/5/8
 * Time: 10:11
 * Description:
 */

class AddressServiceModel extends \Business\AbstractModel {

    public function init()
    {
    }

    public function writeToFile(){

        $addressDao = \DAO\AreaModel::getInstance();
        $addressDao->writeToFile();
        return true;
    }

    public function saveAddress($data,$memberId){
        $addressDao = \DAO\AddressModel::getInstance(\Our\DbNameConst::masterDBConnectName);
        $addressId = isset($data['addressId'])?$data['addressId']:\Our\ApiConst::zero;
        $address = $this->getVerifiedAddress($data,$memberId);
        if($addressId){
            $oldAddress = $addressDao->find($addressId);
            if(!$oldAddress){
                return false;
            }
            $where['address_id'] = $addressId;
            $result = $addressDao->update($address,$where);
            \Our\RedisHelper::delCachedFunction(\Redis\Db8\AddressRedisModel::getInstance(),array(&$addressDao, 'findByWhereWithColumns'),array(),array($addressId));
            if($result!==false){
                $result = true;
            }
        }else{
            $result = $addressDao->insert($address);
            $addressId = $result;
        }
        if($result){
            \Our\RedisHelper::delCachedFunction(\Redis\Db8\AddressRedisModel::getInstance(),array(&$addressDao, 'selectByWhere'),array(),array($memberId));
        }
        return $addressId;
    }

    /**
     * @param $data
     * @param $memberId
     * @return array
     */
    public function setAddress($data,$memberId){
        $sess=\Yaf\Session::getInstance();
        $currentAddress = $sess->get('currentAddress');
        //if($currentAddress)
        if(isset($data['choosedFlag'])&&$data['choosedFlag']){
            $chooseFlag = $data['choosedFlag'];
        }
        if(isset($data['addressId'])&&$data['addressId']){
            $returnAddress = $this->setAddressById($data['addressId'],$memberId);
        }else if(($data['lng']&&$data['lat']&&$data['cityCode'])){
            if(isset($chooseFlag)&&$chooseFlag){
                $returnAddress = $this->setCurrentAddress($data,$memberId,$chooseFlag);
            }else{
                $returnAddress = $this->setCurrentAddress($data,$memberId);
            }
        }else {
            if($currentAddress){
                if($currentAddress['addressId']&&$currentAddress['chooseFlag']){
                    $address['addressId'] = $currentAddress['addressId'];
                    $address['address'] = $currentAddress['address'];
                    $address['name'] = $currentAddress['name'];
                    $address['tagType'] = $currentAddress['tagType'];
                    $address['lat'] = $currentAddress['lat'];
                    $address['lng'] = $currentAddress['lng'];
                    $address['cityCode'] = $currentAddress['cityCode'];
                    $addresses[] = $address;
                    $returnAddress = array('returnAddressId'=>$currentAddress['addressId'],'choosedAddressFlag'=>$currentAddress['chooseFlag'],'addresses'=>$addresses);
                }else{

                    $returnAddress = array('returnAddressId'=>$currentAddress['addressId'],'choosedAddressFlag'=>isset($currentAddress['chooseFlag'])&&$currentAddress['chooseFlag']?$currentAddress['chooseFlag']:\Our\ApiConst::zero);
                    if($memberId){
                        $myAddresses =  $this->getMyCurrentAddressByMemberId($memberId);
                        if($myAddresses){
                            $returnAddress['addresses'] = $myAddresses;
                        }
                    }
                }
            }else{
                if(isset($data['choosedFlag'])&&$data['choosedFlag']) {//设置地址时执行到这里属于非法情况
                    \Error\ErrorModel::throwException(\Error\CodeConfigModel::illegalAccess);
                }
                $data = \Our\ArrayConst::defaultAddress; //如果没有传任何地址信息,系统提供默认地址
                $returnAddress = $this->setCurrentAddress($data,$memberId);
            }
        }
        if(isset($data['choosedFlag'])&&$data['choosedFlag']){ //如果调用设置地址接口时,前台不需要弹窗
            $returnAddress['choosedAddressFlag'] = \Our\ApiConst::one;
        }
        return $returnAddress;
    }


    /**
     * 设置指定地址为当前地址
     */
    public function setAddressById($addressId,$memberId){
        if(!$addressId){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::illegalAccess);
        }
        $address = $this->getMyAddress(array('addressId'=>$addressId),$memberId);
        if(!$address){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::addressNotExist);
        }
        $sess = \Yaf\Session::getInstance();
        $newAddress['addressId'] = $address['addressId'];
        $newAddress['address'] = $address['address'];
        $newAddress['name'] = $address['name'];
        $newAddress['tagType'] = $address['tagType'];
        $newAddress['lng']  = $address['lng'];
        $newAddress['lat']  = $address['lat'];
        $newAddress['cityCode']  = $address['cityCode'];
        $returnAddresses[] = $newAddress;
        $choosedAddressId = $address['addressId'];
        $newAddress = $address;
        $newAddress['chooseFlag'] = \Our\ApiConst::one;
        $sess['currentAddress'] = $newAddress;
        return array('returnAddressId'=>$choosedAddressId,'choosedAddressFlag'=>\Our\ApiConst::one,'addresses'=>$returnAddresses);
    }

    /**
     * 检测是否需要返回地址列表
     * @param $where 参入参数
     * @param $memberId 会员ID
     * @throws \Exception
     */
    public function setCurrentAddress($where,$memberId=null,$chooseFlag = null){
        $addressDao = \DAO\AddressModel::getInstance();
        $sess = \Yaf\Session::getInstance();
        $currentAddress = $sess->get('currentAddress');
        $validFlag = $addressDao->getValidAddress($where);
        if(!$validFlag){
            //\Error\ErrorModel::throwException($addressDao->errorCode);

            //当前用户没有任何收货地址,并且又没有命中任何收货地址时
            $data = \Our\ArrayConst::defaultAddress; //如果没有传任何地址信息,系统提供默认地址
            $defaultResultAddress = $this->setCurrentAddress($data,null,\Our\ApiConst::zero);
            return $defaultResultAddress;

        }
        $tempLatLng['lat']      = $where['lat'];
        $tempLatLng['lng']      = $where['lng'];
        $tempLatLng['cityCode'] = $where['cityCode'];
        //用户已经登录的情况下

        if(!$memberId){
            $address = $tempLatLng;
            $address['addressId'] = \Our\ApiConst::unChoosedAddressId;
            if($chooseFlag){
                $address['chooseFlag'] = $chooseFlag;
            }else{
                $address['chooseFlag'] = \Our\ApiConst::zero;
                if($currentAddress&&$tempLatLng&&!(isset($where['default'])&&$where['default'])){
                    $sameFlag = $addressDao->checkSessAddress($tempLatLng,$currentAddress);
                    if($sameFlag){
                        $address['chooseFlag'] = \Our\ApiConst::one;
                    }
                }
            }
            $sess['currentAddress'] = $address;
            return array('returnAddressId'=>$address['addressId'],'choosedAddressFlag'=>$address['chooseFlag']?\Our\ApiConst::one:\Our\ApiConst::zero);
        }

        $address = array();

        $columns = $this->getChoosedAddressColumns();
        $condition['member_id'] = $memberId;
        $condition['citycode'] = $where['cityCode'];
        $order = array('is_default'=> 'desc','address_id' => 'desc');
        $limit = \Our\ApiConst::defaultAddressCount;
        //1、判断当前用户的地址列表中是否存在和当前经纬度坐标小于200的地址（当前经纬度是否存在对应收货地址）
        $addressList = \Our\RedisHelper::cachedFunction(\Redis\Db8\AddressRedisModel::getInstance(),array(&$addressDao, 'selectByWhere'),array($condition,$columns),\Our\ApiConst::oneHour,array($memberId));
        if($addressList){
            $newAddressList = array();
            foreach($addressList as $addr){
                $newAddressList[$addr['address_id']] = $addr;
                $distince = \Our\CommonExtension::getDistance($tempLatLng['lat'],$tempLatLng['lng'],$addr['lat'],$addr['lng'],1);
                $distinceArray[$addr['address_id']]=$distince;
            }
            $pos = array_search(min($distinceArray), $distinceArray);
            $minDistince = $distinceArray[$pos];
            if($minDistince<\Our\ApiConst::minDistanceForCurrentPosition){
                $address = array();
                $address['addressId']= $newAddressList[$pos]['address_id'];
                $address['address']= $newAddressList[$pos]['address'];
                $address['name'] = $newAddressList[$pos]['name'];
                $address['tagType']= $newAddressList[$pos]['tag_type'];
                $address['lng']  = $newAddressList[$pos]['lng'];
                $address['lat']  = $newAddressList[$pos]['lat'];
                $address['cityCode']  = $newAddressList[$pos]['citycode'];
                $choosedAddressId = $address['addressId'];
                $newAddress = $address;
                $newAddress['chooseFlag'] = \Our\ApiConst::one;
                $sess['currentAddress'] = $newAddress;
                $returnAddresses[] = $address;
            }
        }
        //2、如果不存在，存入当前经纬度作为临时地址，并且取当前用户最近使用过的最多3条地址返回去
        $choosedAddressFlag = \Our\ApiConst::one;
        if(!$address){
            $address = $tempLatLng;
            $address['addressId'] = \Our\ApiConst::unChoosedAddressId;

            //$sameFlag = $addressDao->checkSessAddress($tempLatLng,$currentAddress);
            /*$address['chooseFlag'] = $chooseFlag;
            if($chooseFlag){
                $choosedAddressFlag = \Our\ApiConst::one;
            }else{
                $choosedAddressFlag = \Our\ApiConst::zero;
            }*/

            if($chooseFlag){
                $address['chooseFlag'] = $chooseFlag;
                $choosedAddressFlag = \Our\ApiConst::one;
            }else{
                $address['chooseFlag'] = \Our\ApiConst::zero;
                $choosedAddressFlag = \Our\ApiConst::zero;
                if($currentAddress&&$tempLatLng&&!(isset($where['default'])&&$where['default'])){
                    $sameFlag = $addressDao->checkSessAddress($tempLatLng,$currentAddress);
                    if($sameFlag){
                        $address['chooseFlag'] = \Our\ApiConst::one;
                        $choosedAddressFlag = \Our\ApiConst::one;
                    }
                }
            }

            $sess['currentAddress'] = $address;
            $choosedAddressId = $address['addressId'];
            $newCondition['member_id'] = $memberId;
            $returnAddresses = \Our\RedisHelper::cachedFunction(\Redis\Db8\AddressRedisModel::getInstance(),array(&$addressDao, 'selectByWhere'),array($newCondition,$columns,$order,$limit),3600,$newCondition);
            //print_r($returnAddresses);
            $defaultAddressRoute = \Our\ApiConst::defaultAddressRoute;
            if($returnAddresses){
                $returnAddresses = \Our\Common::convertUnderline($returnAddresses);
                if($defaultAddressRoute){
                    foreach($returnAddresses as &$tempAdd){
                        $tempAdd['cityCode'] =  $tempAdd['citycode'];
                        unset($tempAdd['citycode']);
                    }
                    $sessAddress = $returnAddresses[0];
                    $choosedAddressId = $sessAddress['addressId'];
                    $sessAddress['chooseFlag'] = $chooseFlag;
                    $sess['currentAddress'] = $sessAddress;
                }
                $returnAddressList = array();
                foreach($returnAddresses as $tempAddr){
                    $temp = array();
                    $temp['addressId'] = $tempAddr['addressId'];
                    $temp['address'] = $tempAddr['address'];
                    $temp['name'] = $tempAddr['name'];
                    $temp['tagType'] = $tempAddr['tagType'];
                    $temp['cityCode'] = $tempAddr['citycode'];
                    $temp['lat'] = $tempAddr['lat'];
                    $temp['lng'] = $tempAddr['lng'];
                    $returnAddressList[] = $temp;
                }
                return array('returnAddressId'=>$choosedAddressId,'choosedAddressFlag'=>$choosedAddressFlag,'addresses'=>$returnAddressList);
            }else{
                return array('returnAddressId'=>$choosedAddressId,'choosedAddressFlag'=>$choosedAddressFlag);
            }
        }else{
            if(isset($where['default'])&&$where['default']){
                $choosedAddressFlag = \Our\ApiConst::zero;
            }
        }
        return array('returnAddressId'=>$choosedAddressId,'choosedAddressFlag'=>$choosedAddressFlag,'addresses'=>$returnAddresses);

    }

    public function getMyCurrentAddressByMemberId($memberId){
        $addressDao = \DAO\AddressModel::getInstance();
        $columns = $this->getChoosedAddressColumns();
        $order = array('is_default'=> 'desc','address_id' => 'desc');
        $limit = \Our\ApiConst::defaultAddressCount;
        $newCondition['member_id'] = $memberId;
        $returnAddresses = \Our\RedisHelper::cachedFunction(\Redis\Db8\AddressRedisModel::getInstance(),array(&$addressDao, 'selectByWhere'),array($newCondition,$columns,$order,$limit),3600,$newCondition);
        //print_r($returnAddresses);
        $defaultAddressRoute = \Our\ApiConst::defaultAddressRoute;
        if($returnAddresses){
            $returnAddresses = \Our\Common::convertUnderline($returnAddresses);
            if($defaultAddressRoute){
                foreach($returnAddresses as &$tempAdd){
                    $tempAdd['cityCode'] =  $tempAdd['citycode'];
                    unset($tempAdd['citycode']);
                }

            }
            $returnAddressList = array();
            foreach($returnAddresses as $tempAddr){
                $temp = array();
                $temp['addressId'] = $tempAddr['addressId'];
                $temp['address'] = $tempAddr['address'];
                $temp['name'] = $tempAddr['name'];
                $temp['tagType'] = $tempAddr['tagType'];
                $temp['lat'] = $tempAddr['lat'];
                $temp['lng'] = $tempAddr['lng'];
                $temp['cityCode'] = $tempAddr['cityCode'];
                $returnAddressList[] = $temp;
            }
            return $returnAddressList;
        }
        return false;
    }

    /**
     * 获取单个收货地址
     * @param $where
     * @param $memberId
     * @return array|bool|mixed
     * @throws \Exception
     */
    public function getMyAddress($where,$memberId){
        $addressDao = \DAO\AddressModel::getInstance();
        $columns = $addressDao->getAddressColumns();
        if($where['addressId']){
            $addressId = $where['addressId'];
            $condition['address_id'] = $addressId;
            $address = \Our\RedisHelper::cachedFunction(\Redis\Db8\AddressRedisModel::getInstance(),array(&$addressDao, 'findByWhereWithColumns'),array($condition,$columns),3600,array($addressId));

            //$address = $this->findFromRedis($condition,'han_address','address_id',$columns);
            if(!$address||($address&&$address['member_id']!=$memberId)){
                \Error\ErrorModel::throwException(\Error\CodeConfigModel::addressNotExist);
            }
        };
        if($address){
            $address = \Our\Common::convertUnderline($address);
            $address['subAddress']  = $address['subaddress'];
            $address['gender']      = $address['sex'];
            $address['cityCode']    = $address['citycode'];
            $address['mobPhone']    = $address['mobPhone']?$address['mobPhone']:$address['telPhone'];
            unset($address['memberId']);
            unset($address['telPhone']);
            unset($address['subaddress']);
            unset($address['sex']);
            unset($address['citycode']);
            unset($address['city_id']);
            return $address;
        }
        return false;
    }

    public function getMyAddresses($memberId){
        $addressDao = \DAO\AddressModel::getInstance();
        $columns = $addressDao->getAddressColumns();
        $condition['member_id'] = $memberId;
        $addresses = \Our\RedisHelper::cachedFunction(\Redis\Db8\AddressRedisModel::getInstance(),array(&$addressDao, 'selectByWhere'),array($condition,$columns),3600,array($memberId));
        if($addresses){
            //$addresses = $addressDao->selectByMemberId($memberId,$columns);
            $addresses = \Our\Common::convertUnderline($addresses);
            foreach($addresses as &$address){
                $address['subAddress']  = $address['subaddress'];
                $address['gender']      = $address['sex'];
                $address['cityCode']    = $address['citycode'];
                $address['mobPhone']    = $address['mobPhone']?$address['mobPhone']:$address['telPhone'];
                unset($address['memberId']);
                unset($address['telPhone']);
                unset($address['subaddress']);
                unset($address['sex']);
                unset($address['citycode']);
            }
            return $addresses;
        }
        return false;
    }


    public function delAddress($data,$memberId){
        $addressDao = \DAO\AddressModel::getInstance();
        $where['address_id'] = $data['addressId'];
        if(!$data['addressId']){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyAddressId);
        }
        $where['member_id'] = $memberId;
        $result = $addressDao->del($where);
        \Our\RedisHelper::delcachedFunction(\Redis\Db8\AddressRedisModel::getInstance(),array(&$addressDao, 'findByWhereWithColumns'),array(),array($data['addressId']));
        \Our\RedisHelper::delCachedFunction(\Redis\Db8\AddressRedisModel::getInstance(),array(&$addressDao, 'selectByWhere'),array(),array($memberId));
        return $result;
    }

    /**
     * 获取城市列表
     * @return bool
     */
    public function getCityList(){
        $areaDao =\DAO\AreaModel::getInstance();
        $citList = $areaDao->getCityList();
        if($citList){
            return $citList;
        }
        return array();
    }

    private static $_instance = null;

    /**
     * 单例模式获取类实例
     *
     * @return \Business\User\LoginV2Model
     */
    public static function getInstance()
    {
        if (!(self::$_instance instanceof self)) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }


    private function getChoosedAddressColumns(){
        $columns = array(
            'address_id',
            'lng',
            'lat',
            'address',
            'name',
            'citycode',
            'tag_type'
        );
        return $columns;
    }

    private function getVerifiedAddress($data,$memberId){
        $address = array();
        $province = $data['province'];
        $city = $data['city'];
        $district = $data['district'];
        $address['true_name']   = $data['trueName'];
        $address['sex'] = intval($data['gender']);

        $address['mob_phone']   = $data['mobPhone'];
        $address['tag_type']     = intval($data['tagType']);
        $address['province']    = $province;
        $address['city']        = $city;
        $address['district']    = $district;
        $areaInfo = $province .'	'.$city.'	'.$district;
        $address['area_info']   = $areaInfo;
        $address['subaddress']  = $data['subAddress'];
        $address['citycode']    = $data['cityCode'];
        $address['address']     = $data['address'];
        $address['name']        = $data['name'];
        $address['member_id']   = $memberId;
        $address['lng']         = $data['lng'];
        $address['lat']         = $data['lat'];
        $prov_id =0;
        $city_id =0;
        $area_id = 0;
        $areaList= \Our\AreaConst::areaList;
        if(!($address['address']&&$address['name'])){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyAddressAndName);
        }
        if(!($address['tag_type']>=\Our\ApiConst::zero&&$address['tag_type']<=3)){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::wrongAddressTagType);
        }
        if($province){
            $province = mb_substr($province,0,2);
            $provinceList = $areaList[\Our\ApiConst::zero];
            foreach($provinceList as $temp){
                if(mb_strpos($temp['area_name'],$province)===0){
                    $prov_id = $temp['area_id'];
                }
            }
        }
        if($prov_id==0){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyProvinceId);
        }
        if($city){
            $cityList = $areaList[$prov_id];
            foreach($cityList as $temp){
                if($temp['area_name'] == $city){
                    $city_id = $temp['area_id'];
                }
            }
        }
        if($city_id==0){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyCityId);
        }
        if($district){
            $areaList = $areaList[$city_id];
            foreach($areaList as $temp){
                if($temp['area_name'] == $district){
                    $area_id = $temp['area_id'];
                }
            }
        }
        if($area_id==0){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyDistrictId);
        }
        $address['prov_id'] = $prov_id;
        $address['city_id'] = $city_id;
        $address['area_id'] = $area_id;
        if(!in_array($address['sex'],array(\Our\ApiConst::woman,\Our\ApiConst::man))){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::wrongAddressGender);
        }
        if(!$address['true_name']){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyAddressTrueName);
        }
        if(!$address['mob_phone']){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyAddressMobile);
        }
        $isMobile = \Our\Common::checkMobilePhone($address['mob_phone']);
        if($isMobile){
            $address['tel_phone'] = '';
        }else{
            $isTel = \Our\Validate::checkTelePhone($address['mob_phone']);
            if(!$isTel){
                \Error\ErrorModel::throwException(\Error\CodeConfigModel::wrongAddressMobile);
            }
            $address['tel_phone'] = $address['mob_phone'];
            $address['mob_phone'] = '';
        }

        if(!($address['citycode'])){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyCityCodeForSave);
        }
        if(!($address['lng']&&$address['lat'])){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::chooseAddressFormMap);
        }
        /*if(!$address['subaddress']){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptySubAddress);
        }*/
        return $address;

    }

}