<?php
/**
 * Created by PhpStorm.
 * User: stanley-king
 * Date: 16/4/11
 * Time: 上午10:04
 */

namespace bonus;

use \Exception;
use \errcode;
use \text_filter;
use \member_info;

class type
{
    const def_usable_days = 30;

    const MakeSendType = 0;
    const MakeBonusRefundType = 1;
    const MakeShakeGainType = 2;
    const MakeShakeLostType = 3;
    const MakePayRefundType = 4;
    const MakePayType = 5;
    const MakeOrderCancelType = 6;
    const MakeRegisterType = 7;
    const MakeInviteType = 8;
    const MakeEvaluateType = 9;
    const MakeInviteRewardType = 10;
    const MakeVoteType = 11;
    const MakePayRewardInviterType = 12;
    const MakePayRewardInviteeType = 13;
    const MakeAllowanceType = 14;

    const create_type = 0;
    const load_type = 1;

    const direct_type = 1;
    const general_type =2;

    const SendType_Random = 1;
    const SendType_Fixed = 2;

    const def_period_day = 1;

    const max_total_cent = 100000000;
    const max_person_total_num  = 1000;
    const max_admin_total_num   = 5000;

    const GrabType_All = 0;         //所有人都可以抢的红包
    const GrabType_EXSENDER = 1;    //自己不可以抢
    const GrabType_EXEXIST  = 2;    //注册用户不可以抢

    private $mParam;
    private function __construct($param,$crete_type)
    {
        if($crete_type == self::load_type) {
            $this->mParam = $param;
            return;
        }

        if(intval($param['sender_id'] <= 0)) {
            throw new Exception("发送者身份ID不能为空.",errcode::ErrParamter);
        }
        $this->mParam['sender_id'] = intval($param['sender_id']);

        if(!empty($param['sender_name'])) {
            $this->mParam['sender_name'] = $param['sender_name'];
        }
        if(!empty($param['sender_mobile'])) {
            $this->mParam['sender_mobile'] = $param['sender_mobile'];
        }
        if(intval($param['relayer_id']) > 0) {
            $this->mParam['relayer_id'] = $param['relayer_id'];
        } else {
            $this->mParam['relayer_id'] = 0;
        }

        if(intval($param['usable_days']) > 0) {
            $this->mParam['usable_days'] = intval($param['usable_days']);
        } else {
            $this->mParam['usable_days'] = self::def_usable_days;
        }

        if(intval($param['send_start_date']) >= time()) {
            $this->mParam['send_start_date'] = intval($param['send_start_date']);
        } else {
            $this->mParam['send_start_date'] = time();
        }

        if(intval($param['send_end_date']) > $this->mParam['send_start_date']) {
            $this->mParam['send_end_date'] = intval($param['send_end_date']);
        } else {
            $this->mParam['send_end_date'] = $this->mParam['send_start_date'] + self::def_period_day * 60 * 60 * 24;
        }

        $send_type = intval($param['send_type']);
        if($send_type < 1 || $send_type > 2) {
            $send_type = 2;
        }
        $this->mParam['send_type'] = $send_type;
        $this->fill_total($send_type,$param);

        $this->mParam['remain_amount'] = $this->mParam['total_amount'];
        if(!isset($param['user_type'])) {
            $this->mParam['user_type'] = 2;
        } else {
            $this->mParam['user_type'] = intval($param['user_type']);
        }

        if(intval($param['share_id']) <= 0) {
            $share = open_sharer::instance()->get();
            $param['share_id'] = $share['share_id'];
        }
        $share_id = intval($param['share_id']);
        $this->mParam['share_id'] = $share_id;

        $type_bless = $param['type_bless'];
        if(!empty($type_bless)) {
            $type_bless = urldecode($type_bless);
            $type_bless = text_filter::filter_input($type_bless);
            $this->mParam['type_bless'] = $type_bless;
        } else {
            $share = open_sharer::instance()->get($share_id);
            $this->mParam['type_bless'] = $share['title'];
        }

        if(!empty($param['type_name'])) {
            $this->mParam['type_name'] = $param['type_name'];
        }
        else
        {
            $nickname = $this->nickname($this->mParam['sender_id'],$this->mParam['relayer_id'],$this->mParam['sender_name']);
            $this->mParam['type_name'] = "{$nickname} 的红包";
        }
        $this->mParam['make_type'] = intval($param['make_type']);

        if(!isset($param['grab_type'])) {
            $this->mParam['grab_type'] = 0;
        } else {
            $this->mParam['grab_type'] = intval($param['grab_type']);
        }
    }

    private function fill_total($send_type,$param)
    {
        $rate_money = $param['rate_money'];
        if(empty($rate_money)) //个人发送的红包
        {
            $param['total_num'] = intval($param['total_num']);
            if($param['total_num'] <= 0) {
                throw new Exception("红包个数不能小于1.",errcode::ErrParamter);
            }
            if($param['total_num'] > self::max_person_total_num) {
                $max_num = self::max_person_total_num;
                throw new Exception("红包个数不能大于{$max_num}.",errcode::ErrParamter);
            }

            $this->mParam['total_num'] = $param['total_num'];

            if($send_type == self::SendType_Fixed)
            {
                $this->mParam['min_amount'] = 0;
                $this->mParam['max_amount'] = 0;

                $fixed_mondey = doubleval($param['fixed_money']);
                if (intval($fixed_mondey * 100 + 0.5) < 1) {
                    throw new Exception("红包额度不能小于一分钱.",errcode::ErrParamter);
                }
                $this->mParam['total_amount'] = $fixed_mondey * $param['total_num'];
                $this->mParam['fixed_money']  = $fixed_mondey;
            }
            else
            {
                $this->mParam['fixed_money'] = 0;

                $min_cent = intval($param['min_amount'] * 100 + 0.5);
                $total_cent = intval($param['total_amount'] * 100 + 0.5);
                if($min_cent <= 0) {
                    $min_cent = 1;
                    $this->mParam['min_amount'] = 0.01;
                } else {
                    $this->mParam['min_amount'] = $min_cent / 100;
                }

                if($total_cent <= 0 || $total_cent < $param['total_num'] * $min_cent) {
                    $min_cent = $min_cent / 100;
                    throw new Exception("每个红包至少{$min_cent}元，总金额不够分配.",errcode::ErrParamter);
                }

                $total_amount = doubleval($param['total_amount']);
                if(intval($total_amount * 100 + 0.5) <= 0) {
                    throw new Exception("红包总金额不能小于1分钱.",errcode::ErrParamter);
                }
                $this->mParam['total_amount'] = $total_amount;
            }

            $bonus_rate = intval($param['bonus_rate']);
            if($bonus_rate > 0 || $bonus_rate <= 100) {
                $this->mParam['bonus_rate'] = $bonus_rate;
            }

            if(intval($this->mParam['total_amount'] * 100 + 0.5) > self::max_total_cent) {
                $max_yuan = self::max_total_cent / 100;
                throw new Exception("红包总金额不能超过{$max_yuan}元.",errcode::ErrParamter);
            }
        }
        else
        {
            $total_num = 0;
            $total_amount = 0;
            $max_rate = 0;

            foreach ($rate_money as $item)
            {
                if($send_type == \bonus\type::SendType_Random) {
                    $total_amount += $item['amount'];
                } else {
                    $total_amount += $item['amount'] * $item['num'];
                }
                $total_num += $item['num'];

                if($item['rate'] > $max_rate) {
                    $max_rate = $item['rate'];
                }
            }

            $this->mParam['total_amount'] = $total_amount;
            $this->mParam['total_num'] = $total_num;

            if($total_num <= 0) {
                throw new Exception("红包个数不能小于1.",errcode::ErrParamter);
            }
            if($total_num > self::max_admin_total_num) {
                $max_num = self::max_admin_total_num;
                throw new Exception("系统发送的红包个数不能大于{$max_num}.",errcode::ErrParamter);
            }

            if($send_type == \bonus\type::SendType_Random) {
                $this->mParam['fixed_money'] = 0;
                $this->mParam['min_amount'] = 0.01;
            } else {
                $this->mParam['min_amount'] = 0;
                $this->mParam['max_amount'] = 0;
                $this->mParam['fixed_money'] = $total_amount / $total_num;
            }

            if($max_rate > 0 || $max_rate <= 100) {
                $this->mParam['bonus_rate'] = $max_rate;
            } else {
                throw new Exception("错误的红包折扣率{$max_rate}.",errcode::ErrParamter);
            }
        }
    }

    private function nickname($sender_id,$relayer_id,$sender_name)
    {
        if($relayer_id > 0) {
            $member_id = $relayer_id;
        }
        else
        {
            $member_id = $sender_id;
            if(!empty($sender_name)) {
                return $sender_name;
            }
        }

        $mem_info = new member_info($member_id);
        return $mem_info->nickname();
    }

    public function user_type() {
        return intval($this->mParam['user_type']);
    }
    public function isDirectType() {
        return (intval($this->mParam['user_type']) == self::direct_type);
    }
    public function isGeneralType() {
        return (intval($this->mParam['user_type']) == self::general_type);
    }
    public function isFixedAmount() {
        return (intval($this->mParam['send_type']) == self::SendType_Fixed);
    }
    public function isRandomAmount() {
        return (intval($this->mParam['send_type']) == self::SendType_Random);
    }
    public function send_type() {
        return intval($this->mParam['send_type']);
    }
    public function getType_id() {
        return intval($this->mParam['type_id']);
    }
    public function setType_id($type_id) {
        $this->mParam['type_id'] = $type_id;
    }
    public function setType_sn($type_sn) {
        $this->mParam['type_sn'] = $type_sn;
    }
    public function getType_sn() {
        return $this->mParam['type_sn'];
    }
    public function getTotal_num() {
        return $this->mParam['total_num'];
    }
    public function fixed_money() {
        return $this->mParam['fixed_money'];
    }
    public function getTotal_amount() {
        return $this->mParam['total_amount'];
    }
    public function get_param() {
        return $this->mParam;
    }
    public function bless() {
        return $this->mParam['type_bless'];
    }
    public function name() {
        return $this->mParam['type_name'];
    }
    public function sender_name() {
        return $this->mParam['sender_name'];
    }
    public function sender_id() {
        return $this->mParam['sender_id'];
    }
    public function sender_mobile() {
        return $this->mParam['sender_mobile'];
    }
    public function relayer_id() {
        return $this->mParam['relayer_id'];
    }
    public function isStart() {
        $start_time = intval($this->mParam['send_start_date']);
        if($start_time === 0) {
            return true;
        }
        else {
            return time() >= $start_time;
        }
    }
    public function get_start_time() {
        return intval($this->mParam['send_start_date']);
    }
    public function get_end_time() {
        return intval($this->mParam['send_end_date']);
    }
    public function isEnd() {
        $end_time = intval($this->mParam['send_end_date']);
        if($end_time === 0) {
            return false;
        }
        else {
            return time() >= $end_time;
        }
    }
    public function grab_type() {
        return $this->mParam['grab_type'];
    }
    public function binded_num() {
        return $this->mParam['binded_num'];
    }
    public function binded_over() {
        return intval($this->mParam['total_num']) == intval($this->mParam['binded_num']);
    }
    public function grabed_over() {
        return intval($this->mParam['total_num']) == intval($this->mParam['grabed_num']);
    }
    public function grab_lastime()
    {
        if(isset($this->mParam['grab_lastime'])) {
            return intval($this->mParam['grab_lastime']);
        } else {
            return false;
        }
    }
    public function min_amount() {
        return $this->mParam['min_amount'];
    }
    public function max_amount() {
        return $this->mParam['max_amount'];
    }
    public function isMaxAmount($value)
    {
        $max_val = intval(doubleval($this->mParam['max_amount']) * 100);
        return ($max_val == intval($value * 100));
    }
    public function make_type()
    {
        $make_type = intval($this->mParam['make_type']);
        return $make_type;
    }
    public function remain_amount()
    {
        $amount = intval($this->mParam['remain_amount'] * 100 + 0.5);
        return $amount / 100;
    }
    public function remain_over() {
        $amount = intval($this->mParam['remain_amount'] * 100 + 0.5);
        return ($amount <= 0);
    }
    public function bonus_rate() {
        return intval($this->mParam['bonus_rate']);
    }
    // 为了兼容老版本，提供设置红包折扣率接口
    public function set_rate($rate)
    {
        if(!empty($rate) && intval($rate) > 0) {
            $this->mParam['bonus_rate'] = intval($rate);
        }
    }
    public function share_id() {
        return intval($this->mParam['share_id']);
    }
    public function usable_days() {
        return intval($this->mParam['usable_days']);
    }
    
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static public function crate_by_input($paramer)
    {
        return new type($paramer,self::create_type);
    }

    static public function create_by_paramer($paramer)
    {
        return new type($paramer,self::load_type);
    }

    static public function create_by_sn($type_sn,$master = false)
    {
        $bonus_type = Model('bonus_type');
        $type_info = $bonus_type->get_one(array('type_sn' => $type_sn),'*',$master);
        if(empty($type_info)) {
            throw new Exception("错误的红包序列号.",errcode::ErrBonusType);
        }
        return new type($type_info,self::load_type);
    }
    static public function create_by_id($type_id)
    {
        $bonus_type = Model('bonus_type');
        $type_info = $bonus_type->get_one(array('type_id' => $type_id));
        if(empty($type_info)) {
            throw new Exception("错误的红包ID号.",errcode::ErrBonusType);
        }
        return new type($type_info,self::load_type);
    }

    static public function create_by_ids($type_ids)
    {
        $bonus_type = Model('bonus_type');
        $type_infos = $bonus_type->get(array('type_id' => array('in',$type_ids)));
        if(empty($type_infos)) {
            throw new Exception("错误的红包ID号.",errcode::ErrBonusType);
        }

        $ret = array();
        foreach($type_infos as $val) {
            $ret[$val['type_id']] = new type($val,self::load_type);
        }
        return $ret;
    }
}