<?php

namespace DAO;
use Our\ArrayConst;
use Our\DbNameConst;
use Our\NameConst;


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

    private $addressRedisService;

    private $myAddressPrefix = 'myAddresses';

    public $errorCode ;
    /**
     * 表名
     *
     * @var string
     */
    protected $_tableName = 'han_address';

    /**
     * 主键
     *
     * @var string
     */
    protected $_primaryKey = 'address_id';

    public function init(){
        $this->addressRedisService = \Redis\Db8\AddressRedisModel::getInstance();
    }

    /**
     * 根据按照地址ID进行查找单个地址
     *
     * @param int $userId
     * @return array
     */
    public function find($addressId) {
        $address  = $this->addressRedisService->find($addressId);
        if (!$address) {
            $this->setDb($this->dbName);
            $address  = $this->db->from($this->_tableName)->where(array('address_id'=>$addressId))->fetchOne();
            if ($address) {
                $this->addressRedisService->update($addressId, $address);
            }
        }
        return $address;
    }
    /**
     * 获取单条数据
     * @param $where
     * @return array
     */
    public function getOneByWhereWithField($where,$field='*'){
        $this->setDb($this->dbName);
        $address = $this->db->from($this->_tableName)->select($field)->where($where)->fetchOne();
        return $address;
    }

    public function getAddressByAddressId($addressId,$field='*'){
        $where['address_id']=$addressId;
        $address=$this->getOneByWhereWithField($where,$field);
        return $address;
    }

    public function findByWhereWithColumns($where,$columns){
        if($where['address_id']){
            $address = $this->find($where['address_id']);
            if(isset($where['member_id'])&&$address){
                if($where['member_id']==$address['member_id']){
                    $newAddress = array();
                    foreach($address as $key=>$value){
                        if(in_array($key,$columns)){
                            $newAddress[$key] = $value;
                        }
                    }
                    return $newAddress;
                }
                return false;
            }
        }
        $address  = $this->getOneByWhereWithField($where,$columns);
        return $address;
    }

    public function findByWhere($where){
        $this->setDb(\Our\DbNameConst::salveDBConnectName);
        $address  = $this->db->from($this->_tableName)->where($where)->fetchOne();
        return $address;
    }

    public function selectByMemberId($member_id,$column=array('*'),$order = array('is_default'=>'desc','address_id'=>'desc')){
        $where['member_id']=$member_id;
        $addressKey = $this->myAddressPrefix.$member_id;
        $addresses = $this->addressRedisService->get($addressKey);
        if(!$addresses){
            $this->db->select($column)->from($this->_tableName)->where($where);
            if($order){
                foreach($order as $key=>$value){
                    $this->db->order($key,$value);
                }
            }
            $addresses = $this->db->fetchAll();
            //$addresses = $this->addressMysql->fetchAll($column,$where,$order);
            $this->addressRedisService->set($addressKey,$addresses);
        }
        return $addresses;
    }

    public function selectByWhere($where,$columns = '*',$order = array('is_default'=> 'desc','address_id' => 'desc'),$limit=0){
        $this->setDb($this->dbName);
        $this->db->select($columns)->from($this->_tableName)->where($where);
        if($order){
            foreach($order as $key=>$value){
                $this->db->order($key,$value);
            }
        }
        if($limit>0){
            $this->db->limit($limit);
        }
        $addresses = $this->db->fetchAll();
        return $addresses;
    }

    //对主库进行操作
    public function updateBySql($sql){
        $this->setDb(\Our\DbNameConst::masterDBConnectName);
        $res=$this->db->update($this->_tableName)->query($sql);
        return $res;
    }

    public function insert($data){
        $this->setDb(\Our\DbNameConst::masterDBConnectName);
        $result = $this->db->insert($this->_tableName)->rows($data)->execute();

        if($result){
            $memberId = $data['member_id'];
            $addressKey = $this->myAddressPrefix.$memberId;
            $this->addressRedisService->del($addressKey);
        }
        return $result ;
    }

    public function update($data,$where){

        $this->setDb(\Our\DbNameConst::masterDBConnectName);
        $result=$this->db->update($this->_tableName)->rows($data)->where($where)->execute();
        if($result){
            $memberId = isset($data['member_id'])?$data['member_id']:(isset($where['member_id'])?$where['member_id']:\Our\ApiConst::zero);
            if($memberId){
                $addressKey = $this->myAddressPrefix.$memberId;
                $this->addressRedisService->del($addressKey);
            }
        }
        return $result;
    }

    public function del($where){
        $this->setDb(\Our\DbNameConst::masterDBConnectName);
        $result  = $this->db->delete($this->_tableName)->where($where)->execute();
        return $result;
    }

    /**
     * 更新此次下单使用地址为最新地址
     * @param $addressId
     * @param $memberId
     */
    public function updateOrderAddress($addressId,$memberId){
        $con= array('member_id'=>$memberId,'is_default'=>\Our\ApiConst::one);
        $addresses = $this->selectByWhere($con);
        if($addresses){
            foreach($addresses as $temp){
                \Our\RedisHelper::delCachedFunction(\Redis\Db8\AddressRedisModel::getInstance(),array(&$this, 'findByWhereWithColumns'),array(),array($temp['address_id']));
            }
        }
        $updateDefault = $this->update(array('is_default'=>\Our\ApiConst::zero),$con);
        $result = $this->update(array('is_default'=>\Our\ApiConst::one),array('member_id'=>$memberId,'address_id'=>$addressId));
        if($result===false){
            return false ;
        }
        \Our\RedisHelper::delCachedFunction(\Redis\Db8\AddressRedisModel::getInstance(),array(&$this, 'findByWhereWithColumns'),array(),array($addressId));
        \Our\RedisHelper::delCachedFunction(\Redis\Db8\AddressRedisModel::getInstance(),array(&$this, 'selectByWhere'),array(),array($memberId));
        return true;
    }

    public function  checkSessAddress($tempAddress,$sessAddress){
        $distance = \Our\CommonExtension::getDistance($tempAddress['lat'],$tempAddress['lng'],$sessAddress['lat'],$sessAddress['lng']);
        if($distance<=\Our\ApiConst::minDistanceForCurrentPosition&&(isset($sessAddress['chooseFlag'])&&$sessAddress['chooseFlag'])){
            return true;
        }
        return false;
    }
    /**
     * 类实例
     *
     * @var \DAO\UserModel
     */
    private static $_instance = null;


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

        return self::$_instance;
    }


    /**
     * 验证地址参数
     */
    public function getValidAddress($where){
        if(!$where['cityCode']){
            $this->errorCode = \Error\CodeConfigModel::emptyCityCode;
            return false;
        }
        if(!($where['lng']&&$where['lat'])){
            $this->errorCode = \Error\CodeConfigModel::emptyLatLng;
            return false;
        }
        return true;
    }

    public function getDefaultAddress(){
        return ArrayConst::defaultAddress;
    }



    public function getAddressColumns(){
        $columns = array(
            'address_id',
            'member_id',
            'area_info',
            'address',
            'name',
            'mob_phone',
            'tel_phone',
            'is_default',
            'tag_type',
            'sex',
            'subaddress',
            'lng',
            'lat',
            'citycode',
            'province',
            'city',
            'district',
            'true_name',
            'city_id'
        );
        return $columns;
    }

}
