<?php
/**
 * Created by PhpStorm.
 * User: stanley-king
 * Date: 16/6/23
 * Time: 下午10:28
 */

namespace relation;

use \Exception;
use \session_helper;
use \algorithm;
use \errcode;
use \member_info;
use \Log;

//member_mobile VARCHAR(11) PRIMARY KEY NOT NULL COMMENT '用户手机号',
//member_id INT(11) DEFAULT '0' COMMENT '已经注册用户id',
//contact_name VARCHAR(50) DEFAULT '',
//subscriber TEXT COMMENT '订阅我为好友的人。',
//follower TEXT COMMENT '我订阅别人成为好友通过的人。',
//build_mobiles TEXT COMMENT '已经与我建立好友关系的手机号',
//unbuild_mobiles TEXT COMMENT '还未与我建立好友关系的手机号'

class mem_relation
{
    //对应数据库表中字段
    private $member_id;
    private $member_mobile;
    private $contact_name;
    private $subscriber; //关注我的
    private $new_subscriber;
    private $follower;   //我关注的
    private $build_mobiles;
    private $unbuild_mobiles;
    private $invited_user;

    private $mod_relation;
    private $dirty;

    public function __construct($member_id,$mobile = null)
    {
        $this->dirty = false;

        if(is_array($member_id)) {
            $info = $member_id;
            $this->init($info);
            return;
        }

        $this->mod_relation = Model('member_relation');
        $member_id = intval($member_id);

        if($member_id > 0)
        {
            $member_info = new member_info($member_id);
            if(!empty($member_info))
            {
                $mobile = $member_info->mobile();
                $info = $this->mod_relation->findByMobile($mobile);
                if(!empty($info))
                {
                    $this->init($info);
                    if($this->member_id != $member_id) {
                        $this->member_id = $member_info->member_id();
                        $this->dirty = true;
                    }
                    if($this->contact_name != $member_info->nickname()) {
                        $this->contact_name = $member_info->nickname();
                        $this->dirty = true;
                    }
                    return;
                }
                else
                {
                    if(!empty($member_info)) {
                        $this->member_id = $member_info->member_id();
                        $this->member_mobile = $member_info->mobile();
                        $this->contact_name = $member_info->nickname();
                        $this->subscriber = array();
                        $this->new_subscriber = array();
                        $this->follower = array();
                        $this->build_mobiles = array();
                        $this->unbuild_mobiles = array();
                        $this->invited_user = array();

                        $this->dirty = true;
                        return;
                    }
                }
            }
        }

        if(isset($mobile) && !empty($mobile))
        {
            $mobile = session_helper::mobile_valid($mobile);
            if($mobile == false) {
                throw new Exception("member_relation __construct error",errcode::ErrParamter);
            }
            $mobile = intval($mobile);
            $info = $this->mod_relation->findByMobile($mobile);
            if(!empty($info)) {
                $this->init($info);
                return;
            }
            else
            {
                $this->member_mobile = $mobile;
                $this->member_id = $member_id;
                $this->contact_name = '';
                $this->subscriber = array();
                $this->new_subscriber = array();
                $this->follower = array();
                $this->build_mobiles = array();
                $this->unbuild_mobiles = array();
                $this->invited_user = array();

                $this->dirty = true;
            }
        }
        else
        {
            throw new Exception("member_relation __construct error",errcode::ErrParamter);
        }
    }

    public function __destruct()
    {
        if($this->dirty) {
            $this->save();
        }
    }

    public function invite($user_id)
    {
        if(algorithm::binary_search($this->invited_user,$user_id)) {
            return true;
        }

        if(algorithm::binary_search($this->invited_user,$user_id) == false) {
            $pos = algorithm::lower_bonud($this->invited_user,$user_id);
            algorithm::array_insert($this->invited_user,$pos,$user_id);
            $this->dirty = true;
        }
        return true;
    }

    //用户($member_id) 关注 我($this)
    private function subscribe_me($member_id)
    {
        if(algorithm::binary_search($this->subscriber,$member_id)) {
            return;
        }

        if(algorithm::binary_search($this->new_subscriber,$member_id) == false) {
            $pos = algorithm::lower_bonud($this->new_subscriber,$member_id);
            algorithm::array_insert($this->new_subscriber,$pos,$member_id);
            $this->dirty = true;
        }
    }

    //用户($member_id) 取消关注 我($this)
    private function unsubscribe_me($member_id)
    {
        if(algorithm::binary_search($this->subscriber,$member_id)) {
            $pos = algorithm::lower_bonud($this->subscriber,$member_id);
            algorithm::array_erase($this->subscriber,$pos);
            $this->dirty = true;
            return;
        }

        if(algorithm::binary_search($this->new_subscriber,$member_id)) {
            $pos = algorithm::lower_bonud($this->new_subscriber,$member_id);
            algorithm::array_erase($this->new_subscriber,$pos);
            $this->dirty = true;
        }
    }

    private function doUnSubscribe($member_id)
    {
        $someone = new mem_relation($member_id, null);
        $someone->unsubscribe_me($this->member_id);
        $someone->save();
        return $someone->member_id;
    }

    private function doSubscribe($member_id,&$mobile)
    {
        $someone = new mem_relation($member_id, $mobile);
        $someone->subscribe_me($this->member_id);
        $someone->save();
        $mobile = intval($someone->member_mobile);

        return $someone->member_id;
    }
    public function member_id()
    {
        return $this->member_id;
    }

    //关注我的
    public function subscriber() {
        return $this->subscriber;
    }

    public function subscriber_count() {
        return count($this->subscriber);
    }

    //我关注的
    public function follower() {
        return $this->follower;
    }
    public function follower_count() {
        return count($this->follower);
    }

    //"我"关注某人
    public function subscribe($user)
    {
        if(!isset($user) || intval($user) == 0 || $this->member_id == $user) {
            return false;
        }

        try
        {
            $user = intval($user);
            $someone_id = $this->doSubscribe($user,$some_mobile);
            if($someone_id > 0) {
                $this->add_fllower($someone_id);
                $this->remove_unbuild($some_mobile);
                $this->add_build($some_mobile);
            } else {
                $this->add_unbuild($some_mobile);
            }
            $this->save();
            return true;
        }
        catch (Exception $ex) {
            Log::record($ex->getMessage(),Log::ERR);
            return false;
        }

    }

    //"我"取消关注某人
    public function unsubscribe($member_id)
    {
        if(!isset($member_id) || intval($member_id) == 0 || $this->member_id == $member_id) {
            return false;
        }

        try
        {
            $member_id = intval($member_id);
            $this->doUnSubscribe($member_id);
            $this->remove_fllower($member_id);
            $this->save();
            return true;
        } catch (Exception $ex) {
            Log::record($ex->getMessage(),Log::ERR);
            return false;
        }
    }

    //我通过所有关注
    public function pass_subscribe()
    {
        if(count($this->new_subscriber) > 0) {
            $this->dirty = true;
        }
        else {
            return true;
        }
        
        foreach ($this->new_subscriber as $someone_id)
        {
            try
            {
                $someone = new mem_relation($someone_id);
                $someone->add_fllower($this->member_id);
                if(!empty($this->member_mobile)) {
                    $mobile = intval($this->member_mobile);
                    $someone->remove_unbuild($mobile);
                    $someone->add_build($mobile);
                }
                $someone->save();

                if(algorithm::binary_search($this->subscriber,$someone_id) == false) {
                    $pos = algorithm::lower_bonud($this->subscriber,$someone_id);
                    algorithm::array_insert($this->subscriber,$pos,$someone_id);
                    $this->dirty = true;
                }
            }
            catch (Exception $ex) {
                Log::record($ex->getMessage(),Log::ERR);
            }
        }

        $this->new_subscriber = array();
        $this->save();

        return true;
    }

    //是否是我的粉丝
    public function is_follower($other_id)
    {
        if($this->member_id == $other_id) {
            return false;
        } else {
            return algorithm::binary_search($this->follower,$other_id);
        }
    }

    private function subscribed($mobile)
    {
        if(algorithm::binary_search($this->build_mobiles,$mobile)) {
            return true;
        }
        if(algorithm::binary_search($this->unbuild_mobiles,$mobile)) {
            return true;
        }
        return false;
    }

    private function add_fllower($someone_id)
    {
        if(algorithm::binary_search($this->follower,$someone_id) == false) {
            $pos = algorithm::lower_bonud($this->follower,$someone_id);
            algorithm::array_insert($this->follower,$pos,$someone_id);
            $this->dirty = true;
        }
    }
    private function remove_fllower($someone_id)
    {
        if(algorithm::binary_search($this->follower,$someone_id)) {
            $pos = algorithm::lower_bonud($this->follower,$someone_id);
            algorithm::array_erase($this->follower,$pos);
            $this->dirty = true;
        }
    }

    private function add_unbuild($mobile)
    {
        if(algorithm::binary_search($this->unbuild_mobiles,$mobile) == false) {
            $pos = algorithm::lower_bonud($this->unbuild_mobiles,$mobile);
            algorithm::array_insert($this->unbuild_mobiles,$pos,$mobile);
            $this->dirty = true;
        }
    }

    private function remove_unbuild($mobile)
    {
        if(algorithm::binary_search($this->unbuild_mobiles,$mobile)) {
            $pos = algorithm::lower_bonud($this->unbuild_mobiles,$mobile);
            algorithm::array_erase($this->unbuild_mobiles,$pos);
            $this->dirty = true;
        }
    }

    private function add_build($mobile)
    {
        if(algorithm::binary_search($this->build_mobiles,$mobile) == false) {
            $pos = algorithm::lower_bonud($this->build_mobiles,$mobile);
            algorithm::array_insert($this->build_mobiles,$pos,$mobile);
            $this->dirty = true;
        }
    }

    //我关注我通讯录中所有人
    public function subscribe_contacts($contacts)
    {
        foreach ($contacts as $mobile)
        {
            $mobile = intval($mobile);
            if($this->member_mobile == $mobile || $mobile < 10000000000) { //自己不能订阅自己
                continue;
            }

            if($this->subscribed($mobile)) {
                continue;
            }

            $someone_id = $this->doSubscribe(0,$mobile);
            if($someone_id > 0) {
                $this->add_fllower($someone_id);
                $this->remove_unbuild($mobile);
                $this->add_build($mobile);
            } else {
                $this->add_unbuild($mobile);
            }
        }
        $this->save();
    }

    private function init($info)
    {
        $this->member_id = intval($info['member_id']);
        $this->member_mobile = $info['member_mobile'];
        $this->contact_name = $info['contact_name'];
        $this->subscriber = unserialize($info['subscriber']);
        $this->new_subscriber = unserialize($info['new_subscriber']);
        $this->follower = unserialize($info['follower']);
        $this->build_mobiles = unserialize($info['build_mobiles']);
        $this->unbuild_mobiles = unserialize($info['unbuild_mobiles']);

        if(empty($info['invited_user'])) {
            $this->invited_user = [];
        } else {
            $this->invited_user = unserialize($info['invited_user']);
        }
    }

    private function mobile_int($mobiles)
    {
        foreach ($mobiles as $mobile)
        {
            $val = intval($mobile);
            if($val > 10000000000) {
                $ret[] = $val;
            }
        }
        if(isset($ret)) {
            return $ret;
        } else {
            return array();
        }
    }

    public function sort_mobile()
    {
        $this->mobile_int($this->build_mobiles);
        sort($this->build_mobiles);

        $this->mobile_int($this->unbuild_mobiles);
        sort($this->unbuild_mobiles);

        $this->dirty = true;
    }

    private function save()
    {
        if($this->dirty) {
            $data = array();
            $data['member_mobile'] = $this->member_mobile;
            $data['member_id'] = $this->member_id;
            $data['contact_name'] = $this->contact_name;
            $data['subscriber'] = serialize($this->subscriber);
            $data['new_subscriber '] = serialize($this->new_subscriber);
            $data['follower'] = serialize($this->follower);
            $data['build_mobiles'] = serialize($this->build_mobiles);
            $data['unbuild_mobiles'] = serialize($this->unbuild_mobiles);
            $data['invited_user'] = serialize($this->invited_user);

            $ret = $this->mod_relation->replace($data);
            $this->dirty = false;
        }
    }
}