<?php

namespace Base\Repository;

class SpendRepository
{

    public function __construct()
    {

    }

    private function assembleRecords($items, $keys, $valueColumn, $keyColumn = 'day')
    {
        $records = [];
        foreach ($keys as $key) {
            $value = 0;
            foreach ($items as $item) {
                if ($item[$keyColumn] == $key) {
                    $value = $item[$valueColumn];
                }
            }
            $records[$key] = $value;
        }
        return $records;
    }

    private function getGameGroupConditions($params)
    {
        $beginTime = $params['begin_time'] ?? 0;
        $endTime = $params['end_time'] ?? 0;
        $ids = $params['promote_ids'] ?? [];
        $isBan = $params['is_ban'] ?? false;
        $gameIds = $params['game_ids'] ?? [];

        $conditions = [];
        $conditions['pay_status'] = 1;
        $conditions['promote_id'] = ['in', $ids];
        $conditions['pay_time'] = ['between', [$beginTime, $endTime]];
        $conditions['game_id'] = ['in', $gameIds];
        $conditions['pay_way'] = $isBan ? ['neq', '-10'] : ['neq', '-1'];
        if (!empty($params['server_id'])) {
            $conditions['server_id'] = $params['server_id'];
        }

        return $conditions;
    }

    private function getGameGroupConditionsNew($params)
    {
        $beginTime = $params['begin_time'] ?? 0;
        $endTime = $params['end_time'] ?? 0;
        $ids = $params['promote_ids'] ?? [];
        $gameIds = $params['game_ids'] ?? [];

        $conditions = [];
        $conditions['pay_status'] = 1;
        $conditions['promote_id'] = ['in', $ids];
        $conditions['pay_time'] = ['between', [$beginTime, $endTime]];
        $conditions['game_id'] = ['in', $gameIds];
        if (!empty($params['server_id'])) {
            $conditions['server_id'] = $params['server_id'];
        }
        if (isset($params['pay_way'])) {
            $conditions['pay_way'] = $params['pay_way'];
        }

        return $conditions;
    }

    private function getDayGroupConditions($params)
    {
        $beginTime = $params['begin_time'] ?? 0;
        $endTime = $params['end_time'] ?? 0;
        $gameId = $params['game_id'] ?? 0;
        $serverId = $params['server_id'] ?? 0;
        $ids = $params['promote_id'] ?? [];
        $isBan = $params['is_ban'] ?? false;

        $conditions = [];
        $conditions['pay_status'] = 1;
        $conditions['promote_id'] = ['in', $ids];
        $conditions['pay_time'] = ['between', [$beginTime, $endTime]];
        $conditions['game_id'] = $gameId > 0 ? $gameId : ['gt', 0];
        if (isset($params['server_id'])) {
            $conditions['server_id'] = $serverId;
        }
        $conditions['pay_way'] = $isBan ? ['neq', '-10'] : ['neq', '-1'];
        return $conditions;
    }

    private function getDayGroupConditionsNew($params)
    {
        $beginTime = $params['begin_time'] ?? 0;
        $endTime = $params['end_time'] ?? 0;
        $gameId = $params['game_id'] ?? 0;
        $serverId = $params['server_id'] ?? 0;
        $ids = $params['promote_id'] ?? [];

        $conditions = [];
        $conditions['pay_status'] = 1;
        $conditions['promote_id'] = ['in', $ids];
        $conditions['pay_time'] = ['between', [$beginTime, $endTime]];
        $conditions['game_id'] = $gameId > 0 ? $gameId : ['gt', 0];
        if (isset($params['server_id'])) {
            $conditions['server_id'] = $serverId;
        }
        if (isset($params['pay_way'])) {
            $conditions['pay_way'] = $params['pay_way'];
        }
        return $conditions;
    }

    /**
     * 付费游戏数
     */
    public function getPayGameCountGroupByDay($params)
    {
        $dayList = $params['dayList'] ?? [];
        $conditions = $this->getDayGroupConditions($params);
        $field = 'FROM_UNIXTIME(pay_time,"%Y-%m-%d") as day, count(DISTINCT game_id) count';
        $items = M('spend', 'tab_')->field($field)->where($conditions)->group('day')->select();
        return $this->assembleRecords($items, $dayList, 'count');
    }

    /**
     * 按天统计付款总额
     */
    public function getPayAmountGroupByDay($params)
    {
        $dayList = $params['dayList'] ?? [];
        $conditions = $this->getDayGroupConditions($params);
        $field = 'FROM_UNIXTIME(pay_time,"%Y-%m-%d") as day, sum(pay_amount) as amount';
        $items = M('spend', 'tab_')->field($field)->where($conditions)->group('day')->select();
        return $this->assembleRecords($items, $dayList, 'amount');
    }

    /**
     * 按天统计类型付款总额
     */
    public function getPayAmountGroupByDayAndType($params)
    {
        $dayList = $params['dayList'] ?? [];
        $conditions = $this->getDayGroupConditionsNew($params);
        $field = 'FROM_UNIXTIME(pay_time,"%Y-%m-%d") as day, sum(pay_amount) as amount';
        $items = M('spend', 'tab_')->field($field)->where($conditions)->group('day')->select();
        return $this->assembleRecords($items, $dayList, 'amount');
    }

    /**
     * 按游戏统计付款总额
     */
    public function getPayAmountGroupByGame($params)
    {
        $gameIds = $params['game_ids'] ?? [];
        $conditions = $this->getGameGroupConditions($params);
        $field = 'game_id, sum(pay_amount) as amount';
        $items = M('spend', 'tab_')->field($field)->where($conditions)->group('game_id')->select();
        return $this->assembleRecords($items, $gameIds, 'amount', 'game_id');
    }

    /**
     * 按游戏统计付款总额--cxj
     */
    public function getPayAmountGroupByGameAndType($params)
    {
        $gameIds = $params['game_ids'] ?? [];
        $conditions = $this->getGameGroupConditionsNew($params);
        $field = 'game_id, sum(pay_amount) as amount';
        $items = M('spend', 'tab_')->field($field)->where($conditions)->group('game_id')->select();
        return $this->assembleRecords($items, $gameIds, 'amount', 'game_id');
    }

    /**
     * 按游戏统计付款总额--cxj
     */
    public function getPayAmountByGameAndType($params)
    {
        $conditions = $this->getGameGroupConditionsNew($params);
        return M('spend', 'tab_')->where($conditions)->sum('pay_amount');
    }

    /**
     * 按天统计付款用户数
     */
    public function getPayUserCountGroupByDay($params)
    {
        $dayList = $params['dayList'] ?? [];
        $conditions = $this->getDayGroupConditions($params);
        $field = 'FROM_UNIXTIME(pay_time,"%Y-%m-%d") as day, count(distinct user_id) count';
        $items = M('spend', 'tab_')->field($field)->where($conditions)->group('day')->select();
        return $this->assembleRecords($items, $dayList, 'count');
    }

    /**
     * 按天统计付款用户数--cxj
     */
    public function getPayUserCountGroupByDayNew($params)
    {
        $dayList = $params['dayList'] ?? [];
        $conditions = $this->getDayGroupConditions($params);
        $field = 'FROM_UNIXTIME(pay_time,"%Y-%m-%d") as day, count(distinct user_id, game_id) count';
        $items = M('spend', 'tab_')->field($field)->where($conditions)->group('day')->select();
        return $this->assembleRecords($items, $dayList, 'count');
    }

    /**
     * 按天统计付款次数
     */
    public function getPayCountGroupByDay($params)
    {
        $dayList = $params['dayList'] ?? [];
        $conditions = $this->getDayGroupConditions($params);
        $field = 'FROM_UNIXTIME(pay_time,"%Y-%m-%d") as day, count(*) count';
        $items = M('spend', 'tab_')->field($field)->where($conditions)->group('day')->select();
        return $this->assembleRecords($items, $dayList, 'count');
    }

    /**
     * 按游戏统计付款次数
     */
    public function getPayCountGroupByGame($params)
    {
        $gameIds = $params['game_ids'] ?? [];
        $conditions = $this->getGameGroupConditions($params);
        $field = 'game_id, count(*) count';
        $items = M('spend', 'tab_')->field($field)->where($conditions)->group('game_id')->select();
        return $this->assembleRecords($items, $gameIds, 'count', 'game_id');
    }

    /**
     * 按游戏统计付款次数--cxj
     */
    public function getPayCountByGame($params)
    {
        $conditions = $this->getGameGroupConditions($params);
        return M('spend', 'tab_')->where($conditions)->count();
    }

    /**
     * 游戏统计付款用户数
     */
    public function getPayUserCountGroupByGame($params)
    {
        $gameIds = $params['game_ids'] ?? [];
        $conditions = $this->getGameGroupConditions($params);
        $field = 'game_id, count(distinct user_id) count';
        $items = M('spend', 'tab_')->field($field)->where($conditions)->group('game_id')->select();
        return $this->assembleRecords($items, $gameIds, 'count', 'game_id');
    }

    /**
     * 游戏统计付款用户数--cxj
     */
    public function getPayUserCountByGame($params)
    {
        $conditions = $this->getGameGroupConditions($params);
        $sql = M('spend', 'tab_')->field('distinct game_id, user_id')
            ->where($conditions)
            ->fetchSql(true)
            ->select();
        $model = new \Think\Model();
        return $model->query("select count(*) as num from ($sql) as t")[0]['num'];
    }

    /**
     * 按照时间分组统计新增付费用户数
     */
    public function getNewPayUserCountGroupByDay($params)
    {
        $dayList = $params['dayList'] ?? [];
        $conditions = $this->getDayGroupConditions($params);
        $oldConditions = $conditions;

        $records = [];
        foreach ($dayList as $day) {
            $time = strtotime($day);
            $oldConditions['pay_time'] = ['lt', $time];
            $conditions['pay_time'] = ['between', [$time, ($time + 24 * 3600 - 1)]];
            $oldQuery = M('spend', 'tab_')->field('user_id')->where($oldConditions)->group('user_id')->buildSql();
            $conditions['user_id'] = ['exp', ' not in (' . $oldQuery . ')'];
            $result = M('spend', 'tab_')->field('count(distinct user_id) count')->where($conditions)->find();
            $records[$day] = $result['count'];
        }
        return $records;
    }

    /**
     * 按照时间分组统计新增付费用户数
     */
    public function getNewPayUserCountGroupByGame($params)
    {
        $beginTime = $params['begin_time'] ?? 0;
        $gameIds = $params['game_ids'] ?? [];
        $conditions = $this->getGameGroupConditions($params);
        $oldConditions = $conditions;
        $oldConditions['pay_time'] = ['lt', $beginTime];
        $oldQuery = M('spend', 'tab_')->field('user_id')->where($oldConditions)->group('user_id')->buildSql();
        $conditions['user_id'] = ['exp', ' not in (' . $oldQuery . ')'];
        $items = M('spend', 'tab_')->field('count(distinct user_id) count, game_id')->where($conditions)->group('game_id')->find();
        return $this->assembleRecords($items, $gameIds, 'amount', 'game_id');
    }

    /**
     * 按照时间分组统计新增付费用户付费金额
     */
    public function getNewPayAmountGroupByDay($params)
    {
        $dayList = $params['dayList'] ?? [];
        $conditions = $this->getDayGroupConditions($params);
        $oldConditions = $conditions;

        $records = [];
        foreach ($dayList as $day) {
            $time = strtotime($day);
            $oldConditions['pay_time'] = ['lt', $time];
            $conditions['pay_time'] = ['between', [$time, ($time + 24 * 3600 - 1)]];

            $oldQuery = M('spend', 'tab_')->field('user_id')->where($oldConditions)->group('user_id')->buildSql();
            $conditions['user_id'] = ['exp', ' not in (' . $oldQuery . ')'];
            $result = M('spend', 'tab_')->field('sum(pay_amount) amount')->where($conditions)->find();
            $records[$day] = floatval($result['amount']);
        }
        return $records;
    }

    /**
     * 按照游戏统计新增付费用户付费金额
     */
    public function getNewPayAmountGroupByGame($params)
    {
        $beginTime = $params['begin_time'] ?? 0;
        $gameIds = $params['game_ids'] ?? [];
        $conditions = $this->getGameGroupConditions($params);
        $oldConditions = $conditions;
        $oldConditions['pay_time'] = ['lt', $beginTime];
        $oldQuery = M('spend', 'tab_')->field('user_id')->where($oldConditions)->group('user_id')->buildSql();
        $conditions['user_id'] = ['exp', ' not in (' . $oldQuery . ')'];
        $items = M('spend', 'tab_')->field('sum(pay_amount) amount, game_id')->where($conditions)->group('game_id')->find();
        return $this->assembleRecords($items, $gameIds, 'amount', 'game_id');
    }

    /**
     * 统计给定时间前的付费玩家总数
     */
    public function getHistoryPayCountGroupByDay($params)
    {
        $dayList = $params['dayList'] ?? [];
        $conditions = $this->getDayGroupConditions($params);

        $records = [];
        foreach ($dayList as $day) {
            $time = strtotime($day) + 24 * 3600;
            $conditions['pay_time'] = ['elt', $time];
            $result = M('spend', 'tab_')->field('count(DISTINCT user_id) as count')->where($conditions)->find();
            $records[$day] = $result['count'];
        }
        return $records;
    }

    /**
     * 统计给定时间前的付费玩家总数
     */
    public function getHistoryPayCountGroupByGame($params)
    {
        $beginTime = $params['begin_time'] ?? 0;
        $conditions = $this->getGameGroupConditions($params);
        $conditions['pay_time'] = ['elt', $beginTime];
        $items = M('spend', 'tab_')->field('count(DISTINCT user_id) as count, game_id')->where($conditions)->group('game_id')->find();
        return $this->assembleRecords($items, $gameIds, 'count', 'game_id');
    }

    public function getCommonQuery($params, $columns = '*')
    {
        // return M('spend', 'tab_')->field($columns)->where($map);
    }
}