<?php

/**
 * Created by PhpStorm.
 * User: stanley-king
 * Date: 16/8/14
 * Time: 下午5:27
 */

require_once (BASE_ROOT_PATH . '/helper/activity/groupbuy.php');
require_once (BASE_ROOT_PATH . '/helper/activity/limitime.php');
require_once (BASE_ROOT_PATH . '/helper/activity/bundling.php');
require_once (BASE_ROOT_PATH . '/helper/activity/recommend_combo.php');
require_once (BASE_ROOT_PATH . '/helper/activity/full_sent.php');
require_once (BASE_ROOT_PATH . '/helper/activity/recommend_goods.php');
require_once (BASE_ROOT_PATH . '/helper/activity/goods_gift.php');
require_once (BASE_ROOT_PATH . '/helper/activity/optional_goods.php');
require_once (BASE_ROOT_PATH . '/helper/activity/goods_sampler.php');

require_once (BASE_ROOT_PATH . '/helper/algorithm.php');
require_once (BASE_ROOT_PATH . '/helper/message/msgutil.php');
require_once (BASE_ROOT_PATH . '/helper/activity_helper.php');

function less_endtime($left,$right)
{
    $l_end = intval($left['end_time']);
    $r_end = intval($right['end_time']);
    $l_type = intval($left['time_type']);
    $r_type = intval($right['time_type']);
    $l_actype = $left['act_type'];
    $r_actype = $left['act_type'];

    if($l_end > $r_end) {
        return 1;
    }
    elseif($l_end == $r_end)
    {
        if($l_type > $r_type) return 1;
        elseif($l_type < $r_type) return -1;
        else
        {
            if($l_actype > $r_actype) return 1;
            elseif($l_actype < $r_actype) return -1;
            else return 0;
        }
    }
    else {
        return -1;
    }
}

function less_startime($left,$right)
{
    $l_start = intval($left['start_time']);
    $r_start = intval($right['start_time']);
    $l_type = intval($left['time_type']);
    $r_type = intval($right['time_type']);
    $l_actype = $left['act_type'];
    $r_actype = $left['act_type'];

    if($l_start > $r_start) {
        return 1;
    }
    elseif($l_start == $r_start) {
        if($l_type > $r_type) return 1;
        elseif($l_type < $r_type) return -1;
        else
        {
            if($l_actype > $r_actype) return 1;
            elseif($l_actype < $r_actype) return -1;
            else return 0;
        }
    }
    else {
        return -1;
    }
}


//抢,限,推,套装,三个信息会出现在商品的summary 中,其余的出现在商品的详细信息中
class activity_helper
{
    const ACTIVITY_NONE      = 0;
    const ACTIVITY_GROUPBUY  = 1; //抢
    const ACTIVITY_LIMITTIME = 2; //限
    const ACTIVITY_BUNDLING  = 3; //套装

    public static function take_parted($goods_id,&$act_type)
    {
        if(activity\groupbuy::instance()->isTakepart($goods_id,$act_id)) { //抢购
            $act_type = self::ACTIVITY_GROUPBUY;
            return $act_id;
        }
        elseif(activity\limitime::instance()->isTakepart($goods_id,$act_id)) { //
            $act_type = self::ACTIVITY_LIMITTIME;
            return $act_id;
        }
        else {
            $act_type = self::ACTIVITY_NONE;
            return false;
        }
    }
    public static function have_recommend($goods_id)
    {
        if (activity\recommend_goods::instance()->isTakepart($goods_id)) {
            return true;
        } else {
            return false;
        }
    }
    public static function have_bundling($goods_id) {
        return activity\bundling::instance()->have_bundling($goods_id);
    }
    public static function bundling_goods($bl_id) {
        return activity\bundling::instance()->bundling_goods($bl_id);
    }
    //赠品信息
    public static function have_gift($goods_id) {
        return activity\goods_gift::instance()->have_gift($goods_id);
    }
    public static function goods_gifts($goods_id) {
        return activity\goods_gift::instance()->gifts($goods_id);
    }
    public static function goods_giftids($goods_id) {
        return activity\goods_gift::instance()->goods_giftids($goods_id);
    }

    //商品组合
    public static function have_combo($goods_id) {
        return activity\recommend_combo::instance()->have_combo($goods_id);
    }
    public static function combo_goods($goods_id) {
        return activity\recommend_combo::instance()->combo_goods($goods_id);
    }
    //满赠活动
    public static function fullsent_rules() {
        return activity\full_sent::instance()->rules();
    }

    //包邮信息
    public static function free_ship() {
        return activity\full_sent::instance()->free_price();
    }
    //推荐商品列表
    public static function recomoned_goodsids()
    {
        return activity\recommend_goods::instance()->goods_ids();
    }

    public static function limit_goods($limit_id)
    {
        return activity\limitime::instance()->goods($limit_id);
    }
    public static function groupbuy_goods($group_id)
    {
        return activity\groupbuy::instance()->goods($group_id);
    }
    public static function acting()
    {
        $limits = activity\limitime::instance()->acting();
        $groupbuys = activity\groupbuy::instance()->acting();

        $values = [];
        foreach ($limits as $val) {
            $val['time_type'] = $val['xianshi_type'];
            $val['act_type'] = 1;
            $values[] = $val;
        }

        foreach ($groupbuys as $val) {
            $val['time_type'] = $val['groupbuy_type'];
            $val['act_type'] = 2;
            $values[] = $val;
        }

        $result = [];
        if(!empty($values))
        {
            uasort($values,'less_endtime');
            foreach ($values as $value) {
                $result[] = $value;
            }
        }

        return $result;
    }

    public static function groupbuy_price($limit_id,&$price)
    {
        return activity\groupbuy::instance()->promotion_price($limit_id,$price);
    }
    public static function limit_price($limit_id,$goods_id,&$price)
    {
        return activity\limitime::instance()->promotion_price($limit_id,$goods_id,$price);
    }

    public static function unstart()
    {
        $limits = activity\limitime::instance()->unstart();
        $groupbuys = activity\groupbuy::instance()->unstart();

        $values = [];
        foreach ($limits as $val) {
            $values[] = $val;
        }
        foreach ($groupbuys as $val) {
            $values[] = $val;
        }

        $result = [];
        if(!empty($values))
        {
            uasort($values,'less_startime');
            foreach ($values as $value) {
                $result[] = $value;
            }
        }

        return $result;
    }
    public static function take_part_opgoods($goods_id)
    {
        return activity\optional_goods::instance()->info($goods_id);
    }

    public static function optional_goods_check($goods_id,&$err)
    {
        if(self::take_parted($goods_id,$type)) {
            $err['msg'] = '该商品已经参加其它活动';
            return false;
        }
        elseif(self::have_bundling($goods_id)) {
            $err['msg'] = '该商品已经参加套装活动';
            return false;
        }
        return true;
    }

    public static function optional_goods_match($gids)
    {
        $result = activity\optional_goods::instance()->match($gids);
        return $result;
    }
}

class price_matcher
{
    private $mGoodsNums;
    private $mOptions;
    private $mPrice;
    private $mRepeat;
    private $mGoodsList;

    private $mResult;

    public function __construct($content,$goods_list)
    {
        $goods_nums = $content['goods_nums'];
        $this->mOptions   = $content['options'];
        $this->mPrice     = $content['price'];
        $this->mRepeat    = $content['repeat'];

        $this->mGoodsList = [];
        $goodses = [];
        foreach ($goods_nums as $gid => $num) {
            $this->mGoodsList[$gid] = $goods_list[$gid];
            $goodses[] = $goods_list[$gid];
        }

        usort($goodses,['optional_match','price_desc']);

        $this->mGoodsNums = [];
        foreach($goodses as $val) {
            $goods_id = intval($val['goods_id']);
            $this->mGoodsNums[$goods_id] = $goods_nums[$goods_id];
        }
        $this->mResult = false;
    }

    public function match(&$total_price_cent)
    {
        if($this->mRepeat) {
            $match_goods = $this->repeat();
        }
        else {
            $match_goods = $this->nonrepeat();
        }
        if(empty($match_goods)) {
            $total_price_cent = 0;
            return false;
        }
        else {
            $total_count = $this->goods_count($match_goods);
            $total_price_cent = $this->mPrice * ($total_count / $this->mOptions);
            return $match_goods;
        }
    }

    private function repeat()
    {
        $match_goods = [];

        $goods_num = $this->mGoodsNums;
        while ($this->goods_count($goods_num) >= $this->mOptions)
        {
            $left = $this->mOptions;

            foreach($goods_num as $gid => &$num)
            {
                if($left > $num) {
                    $sel = $num;
                } else {
                    $sel = $left;
                }

                if(array_key_exists($gid,$match_goods)) {
                    $match_goods[$gid] += $sel;
                } else {
                    $match_goods[$gid] = $sel;
                }

                $left -= $sel;
                $num -= $sel;
                if($num == 0) {
                    unset($goods_num[$gid]);
                }

                if($left == 0) {
                    break;
                }
            }
        }

        return $match_goods;
    }
    private function goods_count($goods_nums)
    {
        $count = 0;
        foreach ($goods_nums as $gid => $num) {
            $count += $num;
        }
        return $count;
    }

    private function nonrepeat()
    {
        $match_goods = [];

        $goods_num = $this->mGoodsNums;
        while (count($goods_num) >= $this->mOptions)
        {
            $i = 0;
            foreach($goods_num as $gid => &$num)
            {
                if($i < $this->mOptions)
                {
                    if(array_key_exists($gid,$match_goods)) {
                        $match_goods[$gid] += 1;
                    } else {
                        $match_goods[$gid] = 1;
                    }
                    ++$i;
                    --$num;
                    if($num == 0) {
                        unset($goods_num[$gid]);
                    }
                }
                else {
                    break;
                }
            }
        }

        return $match_goods;
    }
}

class optional_match
{
    private $mPregids;
    private $mAllGoods;

    public function __construct($cart_list)
    {
        $this->mPregids = [];
        $this->mAllGoods = [];

        foreach ($cart_list as $cart)
        {
            $bl_id = intval($cart['bl_id']);
            $goods_id = intval($cart['goods_id']);
            $goods_num = intval($cart['goods_num']);
            if($bl_id == 0 && $goods_id > 0)
            {
                $this->mPregids[$goods_id] = $goods_num;
                $this->mAllGoods[$goods_id] = $cart;
            }
        }
    }

    public function match()
    {
        if(!empty($this->mPregids))  {
            $matchs = activity\optional_goods::instance()->match($this->mPregids);
            if($matchs == false) return false;
        }
        else {
            return false;
        }

        $discount_cent = 0;
        $goods_nums = [];
        $total_cent = 0;

        foreach ($matchs as $item)
        {
            $matcher = new price_matcher($item,$this->mAllGoods);
            $match_goods = $matcher->match($total_oprice_cent);
            if(!empty($match_goods))
            {
                $total_price = $this->total_price_cent($match_goods);
                $total_cent += $total_price;
                $discount_cent += $total_price - $total_oprice_cent;
                foreach ($match_goods as $gid => $num) {
                    $goods_nums[$gid] = $num;
                }
            }
        }

        return ['total_amount' => $total_cent / 100,'discount' => $discount_cent / 100, 'goods_nums' => $goods_nums];
    }

    private function total_price_cent($match_goods)
    {
        $total_price = 0;
        foreach ($match_goods as $gid => $num) {
            $total_price += intval($this->mAllGoods[$gid]['goods_price'] * 100 * $num + 0.5);
        }
        return $total_price;
    }

    public static function price_desc($left,$right)
    {
        $l_price = intval($left['goods_price'] * 100  + 0.5);
        $r_price = intval($right['goods_price'] * 100 + 0.5);

        if($l_price > $r_price) return -1;
        elseif($l_price < $r_price) return 1;
        else return 0;
    }
}