<?php


namespace app\wechat\service;


use app\model\Consultant;
use app\model\MarketCustomer;
use app\model\MarketCustomerFollow;
use app\model\SysDept;
use Carbon\Carbon;
use support\Db;
use support\exception\BusinessException;
use Tinywan\Jwt\JwtToken;

class UserService
{
    /**
     * Notes: 获取所有顾问
     * User: yb
     * Date: 2024/8/15
     * Time: 11:51
     * @param $params
     */
    public static function getAll($params)
    {
        $ids = self::getIds(1);
        $where = [
            [function($query) use ($ids) {
                $query->whereIn('id', $ids);
            }]
        ];
        if (!empty($params['not_id'])) {
            $where[] = ['id', '<>', $params['not_id']];
        }
        //获取所有团队
        $teamKeys = TeamService::getTeams()->pluck('dept_name', 'dept_id');
        $list = Consultant::where($where)->select(['id','name','mobile','gender','status','dept_id','created_at'])->orderBy('created_at', 'desc')->get();
        if (!empty($list)) {
            foreach ($list as $item) {
                $item->dept_name = $teamKeys[$item->dept_id] ?? '';
            }
        }
        return json_success('请求成功', $list);
    }

    /**
     * Notes: 团队成员
     * User: yb
     * Date: 2024/8/14
     * Time: 15:34
     * @param $params
     */
    public static function index($params)
    {
        $page = $params['page'] ?? 1;
        $size = $params['size'] ?? 10;
        $ids = self::getIds(1);
        $where = [
            [function($query) use ($ids) {
            $query->whereIn('id', $ids);
            }]
        ];
        if (!empty($params['status'])) {
            $where[] = ['status', '=', $params['status']];
        }
        if (!empty($params['consultant'])) {
            $keywords = $params['consultant'];
            $where[] = [function($query) use ($keywords) {
                $query->orWhere('name', 'like', "%{$keywords}%")->orWhere('mobile', 'like', "%{$keywords}%");
            }];
        }
        if (!empty($params['dept_id'])) {
            $deptIds = $params['dept_id'];
            $deptId = end($deptIds);
            $where[] = ['dept_id', '=', $deptId];
        }
        if (!empty($params['created_at'])) {
            $datetime = $params['created_at'];
            $startTime = strtotime($datetime['start'].' 00:00:00');
            $endTime = strtotime($datetime['end'].' 23:59:59');
            $where[] = [function($query) use ($startTime, $endTime) {
                $query->whereBetween('created_at', [$startTime, $endTime]);
            }];
        }
        $paginator = Consultant::where($where)->orderBy('created_at', 'desc')->paginate($size, ['id','name','mobile','gender','status','dept_id','created_at'], 'page', $page);
        $total = $paginator->total();
        $items = $paginator->items();
        $data = [
            'total' => $total,
            'rows' => $items
        ];
        return json_success('success', $data);
    }

    /**
     * Notes: 删除成员
     * User: yb
     * Date: 2024/8/15
     * Time: 11:39
     * @param $id
     */
    public static function del($id)
    {
        if(MarketCustomer::where('consultant_id', $id)->exists()) {
            return json_fail('成员下存在客户,请移交客户后删除成员');
        }
        $result = Consultant::where('id', $id)->delete();
        if ($result) {
            return json_success('删除成功');
        } else {
            return json_fail('删除失败');
        }
    }

    /**
     * Notes: 成员详情
     * User: yb
     * Date: 2024/8/15
     * Time: 10:19
     * @param $id
     */
    public static function getInfoById($id)
    {
        $info = Consultant::firstWhere(['id' => $id]);
        if (empty($info)) {
            return json_fail('成员信息不存在');
        }
        return json_success('请求成功', $info);
    }

    /**
     * Notes: 编辑成员
     * User: yb
     * Date: 2024/8/15
     * Time: 10:28
     * @param $params
     */
    public static function updateById($params)
    {
        if (empty($params['id'])) {
            return json_fail('成员id不能为空');
        }
        //查找员工信息
        $info = Consultant::find($params['id']);
        $oldDeptId = $info->dept_id;
        if (empty($info)) {
            return json_fail('成员不存在');
        }
        if (!self::checkMobile($params['mobile'])) {
            return json_fail('请输入正确的手机号');
        }
        //查询员工是否已被注册
        if (Consultant::where('mobile', $params['mobile'])->where('id', '<>', $params['id'])->exists()) {
            return json_fail('手机号已存在,成员已被注册');
        }
        //校验密码规则
        if (!empty($params['password'])) {
            $passwordLen = strlen($params['password']);
            if ($passwordLen > 20 || $passwordLen < 6) {
                return json_fail('请输入6-20位密码');
            }
            $password = self::handlePassword($params['password']);
        }
        //查询上级团队
        $topDeptId = SysDept::where('dept_id', $params['dept_id'])->where('dept_category', TeamService::DEPT_CATEGORY)->value('dept_super_id');
        if (!is_numeric($topDeptId)) {
            return json_fail('团队不存在');
        }
        $updateData = [
            'name' => $params['name'],
            'mobile' => $params['mobile'],
            'dept_id' => $params['dept_id'],
            'top_dept_id' => $topDeptId,
            'gender' => $params['gender'] ?? 1,
            'status' => $params['status'] ?? 1,
            'updated_at' => time()
        ];
        if (!empty($params['password'])) {
            $updateData['password'] = $password;
        }
        $result = false;
        Db::beginTransaction();
        try {
            $result =  Consultant::where('id', $params['id'])->update($updateData);
            if ($updateData['dept_id'] != $oldDeptId) {
                //修改成员所属部门
                MarketCustomer::where('consultant_id', '=', $params['id'])->update(['updated_at' => time(), 'dept_id' => $updateData['dept_id']]);
            }
            Db::commit();
        }catch (BusinessException|\Exception $e) {
            Db::rollBack();
            return json_fail($e->getMessage());
        }
        if ($result) {
            return json_success('编辑成功');
        } else {
            return json_fail('编辑失败');
        }
    }

    /**
     * Notes: 添加员工
     * User: yb
     * Date: 2024/8/15
     * Time: 9:55
     * @param $params
     */
    public static function add($params)
    {
        if (!self::checkMobile($params['mobile'])) {
            return json_fail('请输入正确的手机号');
        }
        //查询员工是否已被注册
        if (Consultant::where('mobile', $params['mobile'])->exists()) {
            return json_fail('手机号已存在,成员已被注册');
        }
        //校验密码规则
        if (!empty($params['password'])) {
            $passwordLen = strlen($params['password']);
            if ($passwordLen > 20 || $passwordLen < 6) {
                return json_fail('请输入6-20位密码');
            }
        }
        //查询上级团队
        $topDeptId = SysDept::where('dept_id', $params['dept_id'])->where('dept_category', TeamService::DEPT_CATEGORY)->value('dept_super_id');
        if (!is_numeric($topDeptId)) {
            return json_fail('团队不存在');
        }
        if (empty($params['password'])) {
            $showPassword = substr($params['mobile'], 5);
            $password = self::handlePassword($showPassword);
        } else {
            $password = self::handlePassword($params['password']);
        }
        $insertData = [
            'name' => $params['name'],
            'mobile' => $params['mobile'],
            'dept_id' => $params['dept_id'],
            'top_dept_id' => $topDeptId,
            'gender' => $params['gender'] ?? 1,
            'password' => $password,
            'status' => $params['status'] ?? 1,
            'relation_user_id' => $params['relation_user_id'] ?? null,
            'type' => 2,
            'created_at' => time()
        ];
        $result = Consultant::insert($insertData);
        if ($result) {
            return json_success('新增成功');
        } else {
            return json_fail('新增失败');
        }
    }

    /**
     * Notes: 登录
     * User: yb
     * Date: 2024/8/8
     * Time: 9:20
     * @param $data
     */
    public static function login($data)
    {
        $password = $data['password'];
        $mobile = $data['mobile'];
        $userInfo = Consultant::firstWhere(['mobile' => $mobile]);
        if (empty($userInfo)) {
            return json_fail('用户不存在');
        }
        //校验密码
        $confoundPassword = $userInfo->password;
        if ($confoundPassword != md5(md5($password))) {
            return json_fail('密码错误');
        }
        $status = $userInfo->status;
        if ($status != 1) {
            return json_fail('用户已离职');
        }
        $extend = [
            'id' => $userInfo->id,
            'client' => 'wechat',
            'name'=> $userInfo->name,
            'user_type' => $userInfo->type
        ];
        $token = JwtToken::generateToken($extend);
        $token['user_type'] = $extend['user_type'];
        return json_success('', $token);
    }

    /**
     * Notes: 获取身份信息
     * User: yb
     * Date: 2024/8/8
     * Time: 10:09
     */
    public static function auth()
    {
        $userId = JwtToken::getCurrentId();
        $userInfo = Consultant::firstWhere(['id' => $userId]);
        if (empty($userInfo)) {
            return json_fail('用户不存在');
        }
        $status = $userInfo->status;
        if ($status != 1) {
            return json_fail('用户已离职');
        }
        $type = $userInfo->type;
        $relationUserId = $userInfo->relation_user_id;
        return json_success('请求成功', ['type' => $type, 'relation_user_id' => $relationUserId]);
    }

    /**
     * Notes: 获取需要查询的ids
     * User: yb
     * Date: 2024/8/13
     * Time: 15:58
     * @return array
     */
    public static function getIds($clearSelf = 0)
    {
        $userId = JwtToken::getCurrentId();
        $userInfo = Consultant::firstWhere(['id' => $userId]);
        if (empty($userInfo)) {
            return [];
        }
        $ids = [];
        if ($userInfo->type == 1) {
            //管理账号
            $deptId = $userInfo->dept_id;
            $deptIds = TeamService::getIds($deptId);
            //团队下的所有员工
            $where = [
                [function($query) use ($deptIds) {
                $query->whereIn('dept_id', $deptIds);
                }]
            ];
            if ($clearSelf == 1) {
                $where[] = ['id', '<>', $userId];
            }
            $ids = Consultant::where($where)->pluck('id')->toArray();
        } else if ($userInfo->type == 2){
            //普通账号
            $ids[] = $userId;
        } else if ($userInfo->type == 3) {
            //判客账户
            $ids = Consultant::pluck('id')->toArray();
        } else if ($userInfo->type == 4) {
            //外渠账号
            $ids[] = $userId;
        }
        return $ids;
    }

    /**
     * Notes: 获取用户类型
     * User: yb
     * Date: 2024/9/13
     * Time: 13:57
     * @return mixed
     */
    public static function getUserType()
    {
        $userId = JwtToken::getCurrentId();
        return Consultant::where('id', $userId)->value('type');
    }

    /**
     * Notes: 首页统计分析
     * User: yb
     * Date: 2024/8/14
     * Time: 10:23
     */
    public static function statistics($params)
    {
        //统计客户总数
        $userIds = self::getIds();
        $currentTime = time();
        $diffNums = CustomService::DIFF_TIME;
        $userType = self::getUserType();

        $whereFollow = [
            [function($query) use ($userIds) {
                $query->whereIn('consultant_id', $userIds);
            }]
        ];
        $where = [];
        $where[] = [function($query) use ($userIds) {
            $query->orWhereIn('consultant_id', $userIds)->orWhereIn('report_consultant_id', $userIds);
        }];
        if ($userType != 4) {
            $where[] = [function($query) use ($diffNums, $currentTime){
                $query->orWhereRaw("check_status IN (-1, 1)")
                    ->orWhereRaw("check_status = 2 AND current_status IN (-1,3,4)")
                    ->orWhereRaw("((visit_time + {$diffNums}) - {$currentTime} > 0 AND current_status = 2 AND check_status = 2)")
                    ->orWhereRaw("((visit_time + {$diffNums}) - {$currentTime} <= 0 AND (visit_time + ({$diffNums} * 4)) - {$currentTime} > 0 AND current_status = 2 AND check_status = 2 AND belong_status = 1)")->whereOr('belong_status','<>', 1);
            }];
        }
        //客户总量
        $customNums = MarketCustomer::where($where)->count();
        if (!empty($params['time'])) {
            $time = $params['time'];
            $start = strtotime($time[0]);
            $end = strtotime($time[1]);
        } else {
            $startDate = date('Y-m-01', strtotime(date('Y-m-d')));
            $endDate = date('Y-m-t', strtotime(date('Y-m-d')));
            $start = strtotime($startDate.' 00:00:00');
            $end  = strtotime($endDate.' 23:59:59');
        }
        $where[] = [function($query) use ($start, $end) {
            $query->whereBetween('created_at', [$start, $end]);
        }];
        $whereFollow[] = [function($query) use ($start, $end) {
            $query->whereBetween('created_at', [$start, $end]);
        }];
        //待转到访客户数量
        $checkCustomNums = MarketCustomer::where($where)->where('check_status', 1)->where('current_status', 1)->count();
        //新增客户
        $newCustomNums = MarketCustomer::where($where)->count();
        //已报备客户数
        $reportCustomNums = MarketCustomer::where($where)->where('current_status', 1)->count();
        //已到访客户数量
        $visitCustomNums = MarketCustomer::where($where)->where('current_status', 2)->where('check_status', 2)->count();
        //已缴费客户数量
        $payCustomNums = MarketCustomer::where($where)->where('current_status', 3)->where('check_status', 2)->count();
        //已成交客户数量
        $dealCustomNums = MarketCustomer::where($where)->where('current_status', 4)->where('check_status', 2)->count();
        //新增跟进记录数量
        $newFollowNums = MarketCustomerFollow::where($whereFollow)->count();
        /* 男女数量 */
        $genderDataNums = [
            ['label' => '男', 'value' => 1, 'nums' => 0],
            ['label' => '女', 'value' => 2, 'nums' => 0],
        ];
        $genderData = MarketCustomer::where($where)->select(Db::raw('gender, count(*) as nums'))->groupBy('gender')->get();
        if (!$genderData->isEmpty()) {
            $genderData = $genderData->toArray();
            foreach ($genderDataNums as $genderKey => $genderVal) {
                foreach ($genderData as $genderItem) {
                    if ($genderItem['gender'] == $genderVal['value']) {
                        $genderDataNums[$genderKey]['nums'] = $genderItem['nums'];
                    }
                }
            }
        }
        /* 客户级别 */
        $levelDataNums = [
            ['label' => 'A类', 'value' => 1, 'nums' => 0],
            ['label' => 'B类', 'value' => 2, 'nums' => 0],
            ['label' => 'C类', 'value' => 3, 'nums' => 0],
            ['label' => 'D类', 'value' => 4, 'nums' => 0],
            ['label' => '其他', 'value' => "", 'nums' => 0],
        ];
        $levelData = MarketCustomer::where($where)->select(Db::raw('level, count(*) as nums'))->groupBy('level')->get();
        if (!$levelData->isEmpty()) {
            $levelData = $levelData->toArray();
            $levelData = array_column($levelData, 'nums', 'level');
            foreach ($levelDataNums as $levelKey => $levelVal) {
                if (isset($levelData[$levelVal['value']])) {
                    $levelDataNums[$levelKey]['nums'] = $levelData[$levelVal['value']];
                }
            }
        }
        $data = [
            'custom_nums' => $customNums,
            'check_custom_nums' => $checkCustomNums,
            'new_custom_nums' => $newCustomNums,
            'report_custom_nums' => $reportCustomNums,
            'visit_custom_nums' => $visitCustomNums,
            'pay_custom_nums' => $payCustomNums,
            'deal_custom_nums' => $dealCustomNums,
            'new_follow_nums' => $newFollowNums,
            'gender_data_nums' => $genderDataNums,
            'level_data_nums' => $levelDataNums
        ];
        return json_success('请求成功', $data);
    }

    /**
     * Notes: 近7日客户走势
     * User: yb
     * Date: 2024/8/17
     * Time: 17:44
     */
    public static function customTrend($params)
    {
        $currentTime = time();
        $diffNums = CustomService::DIFF_TIME;
        //统计客户总数
        $userIds = self::getIds();
        $userType = self::getUserType();
        $where = [
            [function($query) use ($userIds) {
                $query->whereIn('consultant_id', $userIds);
            }]
        ];
        if ($userType != 4) {
            $where[] = [function($query) use ($diffNums, $currentTime){
                $query->orWhereRaw("check_status IN (-1, 1)")
                    ->orWhereRaw("check_status = 2 AND current_status IN (-1,3,4)")
                    ->orWhereRaw("((visit_time + {$diffNums}) - {$currentTime} > 0 AND current_status = 2 AND check_status = 2)");
            }];
        }
        $whereTrend = [];
        if (!empty($params['type'])) {
            $whereTrend[] = ['current_status', '=', $params['type']];
        }
        // 获取当前日期
        $today = Carbon::now();
        // 初始化日期数组和数量数组
        $dates = [date('Y-m-d')];
        // 循环7次,获取从今天开始往前推7天的日期
        for ($i = 0; $i < 6; $i++) {
            // 将日期推回到7天前
            $date = $today->subDay()->toDateString();
            // 将日期字符串存入数组
            $dates[] = $date;
        }
        // 逆序日期数组,因为我们是从今天往前计算的
        $dates = array_reverse($dates);
        $dateList = [];
        foreach ($dates as $item) {
            $dateList[] = ['label' => $item, 'nums' => 0, 'label_sim' => date('m/d', strtotime($item))];
        }
        $datesStr = implode('","', $dates);
        $datesStr = '"'.$datesStr.'"';
        $dateRaw = Db::raw("DATE_FORMAT(FROM_UNIXTIME(created_at), '%Y-%m-%d') IN ({$datesStr})");

        // 构建查询,使用whereBetween或whereIn根据需要筛选日期
        $results = MarketCustomer::select(Db::raw("DATE_FORMAT(FROM_UNIXTIME(created_at), '%Y-%m-%d') AS date,count(*) AS nums"))
            ->where($where)
            ->where($whereTrend)
            ->whereRaw($dateRaw)
            ->groupBy('date')->get();
        if (!$results->isEmpty()) {
            $results = $results->toArray();
            $results = array_column($results, 'nums', 'date');
            foreach ($dateList as $key => $val) {
                $dateList[$key]['nums'] = $results[$val['label']] ?? 0;
            }
        }

        //总数
        $customNums = MarketCustomer::where($where)->whereRaw($dateRaw)->count();
        //到访数
        $visitCustomNums = MarketCustomer::where($where)->whereRaw($dateRaw)->where('current_status', 2)->count();
        //已缴费数
        $payCustomNums = MarketCustomer::where($where)->whereRaw($dateRaw)->where('current_status', 3)->count();
        //已成交数
        $dealCustomNums = MarketCustomer::where($where)->whereRaw($dateRaw)->where('current_status', 4)->count();
        $data = [
            'dateList' => $dateList,
            'visit_nums' => $visitCustomNums,
            'pay_nums' => $payCustomNums,
            'deal_nums' => $dealCustomNums,
            'total_nums' => $customNums
        ];
        return json_success('请求成功', $data);
    }
    /**
     * Notes: 用户详情
     * User: yb
     * Date: 2024/8/14
     * Time: 13:35
     */
    public static function info()
    {
        $userId = JwtToken::getCurrentId();
        $info = Consultant::firstWhere(['id' => $userId]);
        if (!empty($info)) {
            $info->dept_name = SysDept::where('dept_id', $info->dept_id)->value('dept_name');
        }
        return json_success('请求成功', $info);
    }

    /**
     * Notes: 修改个人信息
     * User: yb
     * Date: 2024/8/14
     * Time: 14:19
     * @param $params
     */
    public static function update($params)
    {
        $userId = JwtToken::getCurrentId();
        if (!self::checkMobile($params['mobile'])) {
            return json_fail('请输入正确的手机号');
        }
        //查询员工是否已被注册
        if (Consultant::where('mobile', $params['mobile'])->where('id', '<>', $userId)->exists()) {
            return json_fail('手机号已存在');
        }
        $info = Consultant::firstWhere(['id' => $userId]);
        if (empty($info)) {
            return json_fail('用户不存在');
        }
        $info->name = $params['name'];
        $info->gender = $params['gender'];
        $info->mobile = $params['mobile'];
        $result = $info->save();
        if ($result) {
            return json_success('修改成功');
        } else {
            return json_fail('修改失败');
        }

    }

    /**
     * Notes: 修改密码
     * User: yb
     * Date: 2024/8/14
     * Time: 14:20
     * @param $params
     */
    public static function editPassword($params)
    {
        $oldPassword = $params['old_password'];
        $password = $params['new_password'];
        $rePassword = $params['check_password'] ?? '';
        $len = mb_strlen($password);
        if ($len < 6) {
            return json_fail('密码长度最少为6位');
        }
        if ($len > 20) {
            return json_fail('密码长度最大为20位');
        }
        if ($password != $rePassword) {
            return json_fail('密码与确认密码不一致');
        }
        $userId = JwtToken::getCurrentId();
        $info = Consultant::firstWhere(['id' => $userId]);
        if (empty($info)) {
            return json_fail('用户不存在');
        }
        //校验密码
        $confoundPassword = $info->password;
        if ($confoundPassword != md5(md5($oldPassword))) {
            return json_fail('旧密码错误');
        }
        $info->password = md5(md5($password));
        $result = $info->save();
        if ($result) {
            return json_success('修改成功');
        } else {
            return json_fail('修改失败');
        }
    }

    /**
     * Notes: 团队列表
     * User: yb
     * Date: 2024/8/14
     * Time: 16:32
     */
    public static function getTeamList()
    {
        $userId = JwtToken::getCurrentId();
        $info = Consultant::firstWhere(['id' => $userId]);
        if (empty($info)) {
            return json_success('请求成功');
        }
        $deptId = $info->dept_id;
        $list = TeamService::getTeamList($deptId);
        return $list;
    }

    /**
     * Notes:校验手机号
     * User: yb
     * Date: 2024/8/2
     * Time: 11:12
     * @param $mobile
     * @return bool
     */
    protected static function checkMobile($mobile)
    {
        if (preg_match('/^1[0-9]\d{9}$/', $mobile)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Notes: 处理密码
     * User: yb
     * Date: 2024/8/2
     * Time: 11:19
     * @param $password
     * @return mixed
     */
    protected static function handlePassword($password)
    {
        return md5(md5($password));
    }
}