<?php

namespace App\Services\Channel;

use App\Dao\Channel\ChannelDao;
use App\Dao\Channel\ChannelUserDao;
use App\Libs\Utils;
use App\Consts\ErrorConst;
use App\Exceptions\ApiException;
use Illuminate\Support\Facades\DB;

class ChannelUserService
{
    private $salt = 'N&vQA!saRWjR7v#X';

    private $channelDao;
    private $channelUserDao;

    public function __construct(
        ChannelDao     $channelDao,
        ChannelUserDao $channelUserDao
    )
    {
        $this->channelDao     = $channelDao;
        $this->channelUserDao = $channelUserDao;
    }

    /**
     * @param $account
     * @param $password
     * @return array
     * @throws ApiException
     */
    public function login($account, $password): array
    {
        // 密码
        $md5Pass = md5($password . $this->salt);

        // 获取用户
        $user = $this->channelUserDao->getUserByAccountAndPassword($account, $md5Pass);
        if (empty($user)) {
            Utils::throwError(ErrorConst::USER_IS_NOT_EXIST);
        }

        // 获取站点列表
        $channelUserId = (int)getProp($user, 'id');
        $channels      = $this->channelDao->getUserChannels($channelUserId);

        // 更新登录信息
        $uid        = getProp($user, 'id');
        $nickname   = getProp($user, 'nickname');
        $token      = getProp($user, 'token');
        $phone      = getProp($user, 'phone');
        $updateData = [
            'latest_login_ip'   => _getIp(),
            'latest_login_time' => date('Y-m-d H:i:s'),
            'updated_at'        => date('Y-m-d H:i:s')
        ];

        // 初始化登录需要设置新的token
        if (empty($token)) {
            $token = md5(makeRandStr(32));
            $updateData['token'] = $token;
        }

        $this->channelUserDao->updateUserData(['id' => $uid], $updateData);

        $is_master = 0;
        $sub_channel_ids = DB::table('channel_user_mappings')->where('master_uid', $uid)->select('sub_channel_id')->get()->pluck('sub_channel_id')->toArray();
        if ($sub_channel_ids) $is_master = 1;

        return compact('uid', 'nickname', 'token', 'phone', 'channels', 'is_master');
    }

    /**
     * @param $account
     * @param $password
     * @return bool
     * @throws ApiException
     */
    public function register($account, $password): bool
    {
        // 获取用户
        $user = $this->channelUserDao->getUserByAccount($account);
        if ($user) {
            Utils::throwError(ErrorConst::USER_IS_EXIST);
        }

        // 密码
        $md5Pass = md5($password . $this->salt);
        return $this->channelUserDao->createUser($account, $md5Pass);
    }

    /**
     * 退出登录
     *
     * @param $uid
     * @return bool
     */
    public function logout($uid): bool
    {
        if (empty($uid)) {
            return true;
        }

        return $this->channelUserDao->updateUserData(['id' => $uid], ['token' => '', 'updated_at' => date('Y-m-d H:i:s')]);
    }

    /**
     * 修改密码
     *
     * @param $uid
     * @param $newPassword
     * @return bool
     * @throws ApiException
     */
    public function resetPassword($uid, $newPassword): bool
    {
        // 获取用户
        $user = $this->channelUserDao->getUserByUid($uid);
        if (empty($user)) {
            Utils::throwError(ErrorConst::USER_IS_NOT_EXIST);
        }

        // 更新密码
        $newMd5Pass = md5($newPassword . $this->salt);
        return $this->channelUserDao->updateUserData(['id' => $uid], [
            'password'   => $newMd5Pass,
            'updated_at' => date('Y-m-d H:is')
        ]);
    }
}
