<?php
namespace App\Domains\Virtual\Services;

use App\Core\Service;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
use App\Exceptions\NotExistException;
use App\Models\Virtual\CompanyAccount;
use Illuminate\Support\Facades\Validator;
use App\Domains\Virtual\Repositories\CompanyRepository;
use Dipper\JWTAuth\ServiceContract as JwtServiceContract;
use App\Domains\Virtual\Repositories\CompanyAccountRepository;

class CompanyAccountService extends Service implements JwtServiceContract
{
    protected $companyAccountRepository;

    /**
     * 构造函数
     *
     * @return void
     */
    public function __construct(CompanyAccountRepository $companyAccountRepository)
    {
        $this->companyAccountRepository = $companyAccountRepository;
    }

    /**
     * 获取用户
     *
     * @param string|int $key
     * @param boolean $force
     * @return void
     */
    public function fetch($key, $force = false):? CompanyAccount
    {
        if ($force) {
            $this->companyAccountRepository->forgetCached();
        }

        $account = $this->companyAccountRepository->fetch($key);

        return $account;
    }

    /**
     * 账号列表
     *
     * @param array $conditions
     * @return mixed
     */
    public function index(array $conditions = [])
    {
        $limit = $conditions['limit'] ?? 20;

        $accounts = $this->companyAccountRepository->withConditions($conditions)->applyConditions()->paginate($limit);

        return $accounts;
    }

    /**
     * 存储账号
     *
     * @param array $attributes
     * @param CompanyAccount $parent
     * @return CompanyAccount
     */
    public function store(array $attributes = [])
    {
        $attributes = array_only($attributes, array_merge(app(CompanyAccount::class)->getFillable()));

        $rule = [
            'username' => ['username', 'between:4,32', Rule::unique($this->companyAccountRepository->getTable(), 'username')->ignore($attributes['id'])->whereNUll('deleted_at'), Rule::notIn(config('domain.account.reserved_account'))],
            'nickname' => ['string', 'between:2,32'],
            'mobile' => ['string', 'cn_phone', Rule::unique($this->companyAccountRepository->getTable(), 'mobile')->ignore($attributes['id'])->whereNUll('deleted_at')],
            'password' => ['string'],
            'avatar' => ['image'],
        ];

        $message = [
            'username.required' => '请输入用户名',
            'username.username' => '用户名只能以非特殊字符和数字开头，不能包含特殊字符',
            'username.between' => '用户名长度不合法',
            'username.unique' => '用户名已经被其他用户所使用',
            'username.not_in' => '系统保留用户名，禁止使用',
            'nickname.between' => '昵称长度不合法',
            'mobile.unique' => '手机号已被其他用户使用',
            'mobile.cn_phone' => '手机号不合法',
            'password.required' => '请输入密码',
            'password.string' => '密码格式不合法',
        ];

        if (!$attributes['id']) {
            $rule['username'][] = 'required';
            $rule['password'][] = 'required';
        }

        Validator::validate($attributes, $rule, $message);

        $attributes['mobile'] = empty($attributes['mobile']) ? null : $attributes['mobile'];

        if ($attributes['password']) {
            $attributes['salt'] = Str::random(6);
            $attributes['password'] = md5($attributes['password'].$attributes['salt']);
        }

        if (!$attributes['id']) {
            $attributes['status'] = $attributes['status'] === 2 ? 2 : 1;
            $node = $this->companyAccountRepository->create($attributes, $parent);
        }

        if ($attributes['id']) {
            unset($attributes['username']);

            $node = $this->companyAccountRepository->find($attributes['id']);

            if (!$node) {
                throw new NotExistException('用户不存在');
            }

            $this->companyAccountRepository->setModel($node)->update($attributes);
        }

        app(CompanyRepository::class)->forgetCached();

        return $node;
    }

    /**
     * 删除
     *
     * @return bool
     */
    public function destroy($ids)
    {
        $ids = is_array($ids) ? $ids : [$ids];

        $this->companyAccountRepository->destroy($ids);

        app(CompanyRepository::class)->forgetCached();

        return true;
    }
}
