<?php

namespace App\Services;

use App\Exceptions\UserFriendException;
use App\Models\FriendGroup;
use App\Models\User;
use App\Models\UserFriend;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use phpDocumentor\Reflection\Types\Self_;

class UserFriendService
{

    /*
     * 通过类型获取对应列表
     */
    const FRIEND_USER_LIST_FUNCTION = [
        UserFriend::FRIEND_TYPE_100 => 'getFriendsByAll',
        UserFriend::FRIEND_TYPE_101 => 'getFriendsByAddrBook',
        UserFriend::FRIEND_TYPE_102 => 'getFriendsByAll',
    ];


    public function bind(User $user, $toUserId)
    {
        //记录 A TO B

        try {

            $friendUser = User::query()->where('tencent_im_user_id', $toUserId)->first();

            if (!$friendUser) {
                throw new UserFriendException('好友不存在');
            }

            if ($user->id == $friendUser->id) {
                throw new UserFriendException('不能添加自己为好友!');
            }
            if (!$friendUser) {
                throw new UserFriendException('好友不存在');
            }
            DB::beginTransaction();
            $fromUser = UserFriend::firstOrCreate(
                ['user_id' => $user->id, 'friend_user_id' => $friendUser->id, 'wh_group_id' => FriendGroup::SOCIETY_GROUP]
            );

            //记录 B TO A

            $toUser = UserFriend::firstOrCreate(
                ['user_id' => $friendUser->id, 'friend_user_id' => $user->id, 'wh_group_id' => FriendGroup::SOCIETY_GROUP]
            );

            if (!$fromUser || !$toUser) {
                throw new UserFriendException('记录好友关系失败!');
            }
            DB::commit();
            return true;
        } catch (UserFriendException $e) {
            DB::rollBack();
            return ['error' => $e->getMessage()];
        } catch (\Exception $e) {
            DB::rollBack();
            return ['error' => $e->getMessage()];
        }

    }

    public function lists(User $user, int $listType, array $queryOptions)
    {
        try {
            self::verifyListType($listType);
            $action = self::FRIEND_USER_LIST_FUNCTION[$listType];
            $lists = $this->{$action}($user, $queryOptions);
            return $lists;
        } catch (UserFriendException $e) {
            return ['error' => $e->getMessage()];
        } catch (\Exception $e) {
            return ['error' => $e->getMessage()];
        }
    }

    /**
     * 获取所有好友列表 可通过分圈筛选
     * @param User $user
     * @param array $queryOptions
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    static public function getFriendsByAll(User $user, array $queryOptions)
    {
        $lists = UserFriend::query()
            ->where('user_id', $user->id)
            ->when($queryOptions['friend_group_id'] ?? false, function ($res) use ($queryOptions) {
                return $res->where('wh_group_id', $queryOptions['friend_group_id']);
            })
            ->with('friend_to_user:id,tencent_im_user_id,nick_name_id,avatar,mobile,created_at,updated_at')
            ->orderByDesc('updated_at')
            ->paginate(request('perPage', 10));
        return $lists;
    }

//    static public function getFriendsByWhGroup(User $user, array $queryOptions)
//    {
//
//    }

    /**
     * 通过通讯录获取好友列表
     * @param User $user
     * @param array $addrBooks
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    static public function getFriendsByAddrBook(User $user, array $queryOptions)
    {
        $addrBooks = self::formatAddrBookData($queryOptions['addr_book'] ?? '');
        $userMobile = $user->mobile;

        //删除自己
        unset($addrBooks[array_search($userMobile, $addrBooks, true)]);
        $lists = User::query()
            ->whereIn('mobile', $addrBooks)
            ->select('id', 'tencent_im_user_id', 'nick_name_id', 'avatar', 'mobile', 'created_at', 'updated_at')
            ->with(['user_friends' => function ($res) use ($user) {
                return $res->where('user_id', $user->id);
            }])
            ->orderByDesc('updated_at')
//            ->get();
            ->paginate(request('perPage', 10));
        return $lists;
    }

    /**
     * 验证好友列表请求类型
     * @param int $listType
     * @return bool
     * @throws UserFriendException
     */
    static public function verifyListType(int $listType)
    {
        if (!array_key_exists($listType, self::FRIEND_USER_LIST_FUNCTION)) {
            throw new UserFriendException('获取好友列表类型错误');
        }
        return true;
    }


    /**
     * 格式化通讯录数据
     * @param string $addrBookJsonStr
     * @return array
     * @throws UserFriendException
     */
    static public function formatAddrBookData(string $addrBookJsonStr)
    {
        $addrBook = json_decode($addrBookJsonStr, true);
        if (isset($addrBook['addr_book'])) {
            $addrBook = $addrBook['addr_book'];
        }

        if (!isset($addrBook[0]['contact_name']) || !isset($addrBook[0]['mobile'])) {
            throw new UserFriendException('通讯录数据错误,或解析失败');
        }
        $mobiles = Arr::pluck($addrBook, 'mobile');
        return $mobiles;


    }

    /**
     * @param int $uid
     * @return array
     * @author JYF 2021/2/19 16:08
     */
    public static function getFriendAllByUid(int $uid)
    {
        return UserFriend::query()->where('user_id', $uid)->select('user_id', 'wh_group_id', 'friend_user_id')->get()->toArray();
    }

    /**
     * 获取好友关系
     * @param int $user_id
     * @param int $friend_user_id
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     * @author JYF 2021/2/19 17:22
     */
    public static function getFriendRelation(int $user_id, int $friend_user_id)
    {
        $where = [];
        $where[] = ['user_id', '=', $user_id];
        $where[] = ['friend_user_id', '=', $friend_user_id];
        return UserFriend::query()->where($where)->first();
    }

    /**
     * @param int $uid
     * @return array
     * @author JYF 2021/2/19 20:02
     */
    public static function getFriendAllByFriendUserId(int $uid)
    {
        return UserFriend::query()->where('friend_user_id', $uid)->select('user_id', 'wh_group_id', 'friend_user_id')->get()->toArray();
    }
}
